[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