[Mlir-commits] [mlir] fd676d8 - [MLIR][LLVM] Fix crash in LLVMFunctionType::clone when erasing void function results (#185093)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Mar 9 09:07:31 PDT 2026
Author: Mehdi Amini
Date: 2026-03-09T16:07:23Z
New Revision: fd676d802213c45c255b806ed906d7b8525e62d0
URL: https://github.com/llvm/llvm-project/commit/fd676d802213c45c255b806ed906d7b8525e62d0
DIFF: https://github.com/llvm/llvm-project/commit/fd676d802213c45c255b806ed906d7b8525e62d0.diff
LOG: [MLIR][LLVM] Fix crash in LLVMFunctionType::clone when erasing void function results (#185093)
LLVMFunctionType::clone(inputs, results) was asserting that
results.size() == 1, which caused a crash (later changed to return
null/failure) when erasing results from a void llvm.func via
FunctionOpInterface::eraseResults.
For LLVM function types, an empty results range maps to void return: the
FunctionOpInterface represents void llvm.func with 0 results, while the
underlying LLVMFunctionType stores an explicit LLVMVoidType. When
erasing all results (or no-op erasing 0 results from a void function),
the interface passes an empty TypeRange to clone(), which should produce
a void function type.
Fix by accepting an empty results range in LLVMFunctionType::clone() and
mapping it to LLVMVoidType. More than one result remains invalid.
Fixes #128322
Assisted-by: Claude Code
Added:
Modified:
mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
mlir/test/IR/test-func-erase-result.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index 63acd075c7017..2b3ba1b8b5a35 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -235,11 +235,18 @@ LLVMFunctionType::getChecked(function_ref<InFlightDiagnostic()> emitError,
LLVMFunctionType LLVMFunctionType::clone(TypeRange inputs,
TypeRange results) const {
- if (results.size() != 1 || !isValidResultType(results[0]))
+ // LLVM functions have exactly one return type. An empty results range
+ // corresponds to a void return type (as FunctionOpInterface represents void
+ // functions with 0 results). More than one result is not valid.
+ if (results.size() > 1)
+ return {};
+ Type resultType =
+ results.empty() ? LLVMVoidType::get(getContext()) : results[0];
+ if (!isValidResultType(resultType))
return {};
if (!llvm::all_of(inputs, isValidArgumentType))
return {};
- return get(results[0], llvm::to_vector(inputs), isVarArg());
+ return get(resultType, llvm::to_vector(inputs), isVarArg());
}
ArrayRef<Type> LLVMFunctionType::getReturnTypes() const {
diff --git a/mlir/test/IR/test-func-erase-result.mlir b/mlir/test/IR/test-func-erase-result.mlir
index a32866227547b..c508daff3c440 100644
--- a/mlir/test/IR/test-func-erase-result.mlir
+++ b/mlir/test/IR/test-func-erase-result.mlir
@@ -69,5 +69,7 @@ func.func private @f() -> (
// -----
-// expected-error @below {{failed to erase results}}
+// Erasing no results from a void llvm.func (0 results) is a no-op and should
+// succeed. Previously this crashed with an assertion in LLVMFunctionType::clone.
+// CHECK: llvm.func @llvm_func(!llvm.ptr, i64)
llvm.func @llvm_func(!llvm.ptr, i64)
More information about the Mlir-commits
mailing list