[Mlir-commits] [mlir] 0b3afd3 - [MLIR][LLVM] Fix non-deterministic alloca order in SROA under LLVM_REVERSE_ITERATION (#192087)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Apr 15 05:30:06 PDT 2026
Author: Mehdi Amini
Date: 2026-04-15T14:30:01+02:00
New Revision: 0b3afd35c41d5424e8a0e156f78f8a293934b6a5
URL: https://github.com/llvm/llvm-project/commit/0b3afd35c41d5424e8a0e156f78f8a293934b6a5
DIFF: https://github.com/llvm/llvm-project/commit/0b3afd35c41d5424e8a0e156f78f8a293934b6a5.diff
LOG: [MLIR][LLVM] Fix non-deterministic alloca order in SROA under LLVM_REVERSE_ITERATION (#192087)
AllocaOp::destructure iterated over usedIndices (SmallPtrSet) whose
order depends on pointer values, causing allocas for destructured
subslots to be emitted in a non-deterministic order when
LLVM_REVERSE_ITERATION is enabled. Sort indices ascending by integer
value before creating allocas to guarantee a stable output order. Update
four test cases in sroa-intrinsics.mlir whose CHECK patterns relied on
the old non-deterministic ordering.
Assisted-by: Claude Code
Co-authored-by: Claude Sonnet 4.6 <noreply at anthropic.com>
Added:
Modified:
mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
mlir/test/Dialect/LLVMIR/sroa-intrinsics.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
index 8f3c0dac026a7..66d6a592a93df 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
@@ -87,7 +87,13 @@ DenseMap<Attribute, MemorySlot> LLVM::AllocaOp::destructure(
auto destructurableType = cast<DestructurableTypeInterface>(getElemType());
DenseMap<Attribute, MemorySlot> slotMap;
- for (Attribute index : usedIndices) {
+ // Iterate subelements in their original type order to produce allocas in a
+ // deterministic, readable order (matching appearance in the source type).
+ Type i32 = IntegerType::get(getContext(), 32);
+ for (size_t i = 0; i < slot.subelementTypes.size(); i++) {
+ Attribute index = IntegerAttr::get(i32, i);
+ if (!usedIndices.contains(index))
+ continue;
Type elemType = destructurableType.getTypeAtIndex(index);
assert(elemType && "used index must exist");
auto subAlloca = LLVM::AllocaOp::create(
diff --git a/mlir/test/Dialect/LLVMIR/sroa-intrinsics.mlir b/mlir/test/Dialect/LLVMIR/sroa-intrinsics.mlir
index 6dc8a97884ee1..3253077a76077 100644
--- a/mlir/test/Dialect/LLVMIR/sroa-intrinsics.mlir
+++ b/mlir/test/Dialect/LLVMIR/sroa-intrinsics.mlir
@@ -277,8 +277,8 @@ llvm.func @invalid_indirect_memset_inline() -> i32 {
// CHECK-LABEL: llvm.func @memset_double_use
llvm.func @memset_double_use() -> i32 {
// CHECK: %[[ALLOCA_LEN:.*]] = llvm.mlir.constant(1 : i32) : i32
- // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[ALLOCA_INT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x i32
+ // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[MEMSET_VALUE:.*]] = llvm.mlir.constant(42 : i8) : i8
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
@@ -309,8 +309,8 @@ llvm.func @memset_double_use() -> i32 {
// CHECK-LABEL: llvm.func @memset_inline_double_use
llvm.func @memset_inline_double_use() -> i32 {
// CHECK: %[[ALLOCA_LEN:.*]] = llvm.mlir.constant(1 : i32) : i32
- // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[ALLOCA_INT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x i32
+ // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[MEMSET_VALUE:.*]] = llvm.mlir.constant(42 : i8) : i8
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
@@ -398,8 +398,8 @@ llvm.func @memset_inline_considers_alignment() -> i32 {
// CHECK-LABEL: llvm.func @memset_considers_packing
llvm.func @memset_considers_packing() -> i32 {
// CHECK: %[[ALLOCA_LEN:.*]] = llvm.mlir.constant(1 : i32) : i32
- // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[ALLOCA_INT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x i32
+ // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[MEMSET_VALUE:.*]] = llvm.mlir.constant(42 : i8) : i8
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.alloca %0 x !llvm.struct<"foo", packed (i8, i32, f32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
@@ -430,8 +430,8 @@ llvm.func @memset_considers_packing() -> i32 {
// CHECK-LABEL: llvm.func @memset_inline_considers_packing
llvm.func @memset_inline_considers_packing() -> i32 {
// CHECK: %[[ALLOCA_LEN:.*]] = llvm.mlir.constant(1 : i32) : i32
- // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[ALLOCA_INT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x i32
+ // CHECK: %[[ALLOCA_FLOAT:.*]] = llvm.alloca %[[ALLOCA_LEN]] x f32
// CHECK: %[[MEMSET_VALUE:.*]] = llvm.mlir.constant(42 : i8) : i8
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.alloca %0 x !llvm.struct<"foo", packed (i8, i32, f32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
More information about the Mlir-commits
mailing list