Skip to content

[MLIR][LLVM] Don't use void return type in MLIR APIs. #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1514,14 +1514,18 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
ArrayRef<Type> getArgumentTypes() { return getFunctionType().getParams(); }

/// Returns the result types of this function.
ArrayRef<Type> getResultTypes() { return getFunctionType().getReturnTypes(); }
ArrayRef<Type> getResultTypes() {
if (getFunctionType().getReturnType().isa<LLVM::LLVMVoidType>())
return {};
return getFunctionType().getReturnTypes();
}

/// Returns the callable region, which is the function body. If the function
/// is external, returns null.
Region *getCallableRegion();

/// Returns the callable result type, which is the function return type.
ArrayRef<Type> getCallableResults() { return getFunctionType().getReturnTypes(); }
ArrayRef<Type> getCallableResults() { return getResultTypes(); }

}];

Expand Down
11 changes: 10 additions & 1 deletion mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2044,7 +2044,16 @@ buildLLVMFunctionType(OpAsmParser &parser, SMLoc loc, ArrayRef<Type> inputs,
llvmInputs.push_back(t);
}

// No output is denoted as "void" in LLVM type system.
// The void return type is an internal implementation detail that should not
// be expressed explicitly on the IR. This is symmetric to the printer, which
// does not print the implicit void return type.
if (!outputs.empty() && outputs.front().isa<LLVMVoidType>()) {
parser.emitError(loc, "failed to construct function type: void return type "
"should not be passed explicitly");
return {};
}

// Set implicit void type to represent no return value.
Type llvmOutput =
outputs.empty() ? LLVMVoidType::get(b.getContext()) : outputs.front();
if (!isCompatibleType(llvmOutput)) {
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Dialect/LLVMIR/func.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ module {
// -----

module {
// expected-error@+1 {{cannot attach result attributes to functions with a void return}}
llvm.func @variadic_def() -> (!llvm.void {llvm.noundef})
// expected-error@+1 {{void return type should not be passed explicitly}}
llvm.func @variadic_def() -> (!llvm.void)
}

// -----
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Target/LLVMIR/llvmir-types.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//

// CHECK: declare void @return_void()
llvm.func @return_void() -> !llvm.void
llvm.func @return_void()
// CHECK: declare half @return_half()
llvm.func @return_half() -> f16
// CHECK: declare bfloat @return_bfloat()
Expand All @@ -28,7 +28,7 @@ llvm.func @return_x86_mmx() -> !llvm.x86_mmx
//

// CHECK: declare void @f_void_i32(i32)
llvm.func @f_void_i32(i32) -> !llvm.void
llvm.func @f_void_i32(i32)
// CHECK: declare i32 @f_i32_empty()
llvm.func @f_i32_empty() -> i32
// CHECK: declare i32 @f_i32_half_bfloat_float_double(half, bfloat, float, double)
Expand Down