Skip to content

Commit 7cb6829

Browse files
committed
SROA: Don't drop atomic load/store alignments (PR45010)
SROA will drop the explicit alignment on allocas when the ABI guarantees enough alignment. Because the alignment on new load/store instructions are set based on the alloca's alignment, that means SROA would end up dropping the alignment from atomic loads and stores, which is not allowed (see bug). For those, make sure to always carry over the alignment from the previous instruction. Differential revision: https://reviews.llvm.org/D75266 (cherry picked from commit d48c981)
1 parent daae05a commit 7cb6829

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,6 +2519,8 @@ class llvm::sroa::AllocaSliceRewriter
25192519
NewLI->setAAMetadata(AATags);
25202520
if (LI.isVolatile())
25212521
NewLI->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
2522+
if (NewLI->isAtomic())
2523+
NewLI->setAlignment(LI.getAlign());
25222524

25232525
// Any !nonnull metadata or !range metadata on the old load is also valid
25242526
// on the new load. This is even true in some cases even when the loads
@@ -2709,6 +2711,8 @@ class llvm::sroa::AllocaSliceRewriter
27092711
NewSI->setAAMetadata(AATags);
27102712
if (SI.isVolatile())
27112713
NewSI->setAtomic(SI.getOrdering(), SI.getSyncScopeID());
2714+
if (NewSI->isAtomic())
2715+
NewSI->setAlignment(SI.getAlign());
27122716
Pass.DeadInsts.insert(&SI);
27132717
deleteIfTriviallyDead(OldOp);
27142718

llvm/test/Transforms/SROA/alignment.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,19 @@ define void @test10() {
228228
ret void
229229
}
230230

231+
%struct = type { i32, i32 }
232+
define dso_local i32 @pr45010(%struct* %A) {
233+
; CHECK-LABEL: @pr45010
234+
; CHECK: load atomic volatile i32, {{.*}}, align 4
235+
236+
%B = alloca %struct, align 4
237+
%A.i = getelementptr inbounds %struct, %struct* %A, i32 0, i32 0
238+
%B.i = getelementptr inbounds %struct, %struct* %B, i32 0, i32 0
239+
%1 = load i32, i32* %A.i, align 4
240+
store atomic volatile i32 %1, i32* %B.i release, align 4
241+
%2 = bitcast %struct* %B to i32*
242+
%x = load atomic volatile i32, i32* %2 acquire, align 4
243+
ret i32 %x
244+
}
245+
231246
declare void @populate(i8*)

0 commit comments

Comments
 (0)