Commit d48c9816 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

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
parent 6d15c4de
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2519,6 +2519,8 @@ private:
        NewLI->setAAMetadata(AATags);
      if (LI.isVolatile())
        NewLI->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
      if (NewLI->isAtomic())
        NewLI->setAlignment(LI.getAlign());

      // Any !nonnull metadata or !range metadata on the old load is also valid
      // on the new load. This is even true in some cases even when the loads
@@ -2709,6 +2711,8 @@ private:
      NewSI->setAAMetadata(AATags);
    if (SI.isVolatile())
      NewSI->setAtomic(SI.getOrdering(), SI.getSyncScopeID());
    if (NewSI->isAtomic())
      NewSI->setAlignment(SI.getAlign());
    Pass.DeadInsts.insert(&SI);
    deleteIfTriviallyDead(OldOp);

+15 −0
Original line number Diff line number Diff line
@@ -228,4 +228,19 @@ define void @test10() {
  ret void
}

%struct = type { i32, i32 }
define dso_local i32 @pr45010(%struct* %A) {
; CHECK-LABEL: @pr45010
; CHECK: load atomic volatile i32, {{.*}}, align 4

  %B = alloca %struct, align 4
  %A.i = getelementptr inbounds %struct, %struct* %A, i32 0, i32 0
  %B.i = getelementptr inbounds %struct, %struct* %B, i32 0, i32 0
  %1 = load i32, i32* %A.i, align 4
  store atomic volatile i32 %1, i32* %B.i release, align 4
  %2 = bitcast %struct* %B to i32*
  %x = load atomic volatile i32, i32* %2 acquire, align 4
  ret i32 %x
}

declare void @populate(i8*)