[Mlir-commits] [mlir] 1f4074b - [mlir][llvm] Fix SROA crash on empty LLVM struct types (#184596)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Mar 4 04:31:53 PST 2026
Author: Mehdi Amini
Date: 2026-03-04T13:31:46+01:00
New Revision: 1f4074b771bea3e29c9efbbd3d22689e62773af1
URL: https://github.com/llvm/llvm-project/commit/1f4074b771bea3e29c9efbbd3d22689e62773af1
DIFF: https://github.com/llvm/llvm-project/commit/1f4074b771bea3e29c9efbbd3d22689e62773af1.diff
LOG: [mlir][llvm] Fix SROA crash on empty LLVM struct types (#184596)
When SROA runs on an alloca of an empty struct type (llvm.struct<()>),
it crashes with:
Assertion `\!subelementIndexMap->empty()' failed.
The root cause is in LLVMStructType::getSubelementIndexMap(): for an
empty struct (no body fields), the loop doesn't execute and an empty
DenseMap is returned as a non-null optional. Later, getTypeAtIndex()
asserts the map is non-empty, triggering the crash.
Fix this by returning std::nullopt for empty structs, indicating they
cannot be destructured. This is consistent with how LLVMArrayType
handles the zero-element case.
Fixes #108366
Added:
Modified:
mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
mlir/test/Dialect/LLVMIR/sroa.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
index 7d9058c262562..8f3c0dac026a7 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
@@ -1585,6 +1585,9 @@ DeletionKind LLVM::MemmoveOp::rewire(const DestructurableMemorySlot &slot,
std::optional<DenseMap<Attribute, Type>>
LLVM::LLVMStructType::getSubelementIndexMap() const {
+ // Empty structs have no sub-elements and cannot be destructured.
+ if (getBody().empty())
+ return std::nullopt;
Type i32 = IntegerType::get(getContext(), 32);
DenseMap<Attribute, Type> destructured;
for (const auto &[index, elemType] : llvm::enumerate(getBody()))
diff --git a/mlir/test/Dialect/LLVMIR/sroa.mlir b/mlir/test/Dialect/LLVMIR/sroa.mlir
index 1674bbd8c796f..b019e66d5a430 100644
--- a/mlir/test/Dialect/LLVMIR/sroa.mlir
+++ b/mlir/test/Dialect/LLVMIR/sroa.mlir
@@ -448,3 +448,18 @@ llvm.func @out_of_bound_gep_array_access(%arg: i32) {
llvm.store %arg, %2 : i32, !llvm.ptr
llvm.return
}
+
+// -----
+
+// Regression test: SROA must not crash when processing an alloca of an empty
+// struct type. Empty structs have no sub-elements and cannot be destructured,
+// so the alloca must be left unchanged.
+// https://github.com/llvm/llvm-project/issues/108366
+// CHECK-LABEL: llvm.func @empty_struct_not_destructured
+llvm.func @empty_struct_not_destructured() -> !llvm.struct<()> {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ // CHECK: llvm.alloca %{{.*}} x !llvm.struct<()>
+ %1 = llvm.alloca %0 x !llvm.struct<()> : (i32) -> !llvm.ptr
+ %2 = llvm.load %1 : !llvm.ptr -> !llvm.struct<()>
+ llvm.return %2 : !llvm.struct<()>
+}
More information about the Mlir-commits
mailing list