[Mlir-commits] [mlir] [MLIR][LLVM] Fix crash in LLVMFunctionType::clone when erasing void function results (PR #185093)
Mehdi Amini
llvmlistbot at llvm.org
Mon Mar 9 08:58:19 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/185093
>From 0b92e6668ab60943c618030f947fee65dcd5c911 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 6 Mar 2026 09:45:15 -0800
Subject: [PATCH] [MLIR][LLVM] Fix crash in LLVMFunctionType::clone when
erasing void function results
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.
Update the regression test that previously expected a failure error to instead
verify that erasing no results from a void llvm.func succeeds as a no-op.
Fixes #128322
Assisted-by: Claude Code
---
mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp | 11 +++++++++--
mlir/test/IR/test-func-erase-result.mlir | 4 +++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index e24615c8d3046..3a3a7ca63ea13 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -232,11 +232,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