Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -1972,7 +1972,7 @@ // Disable vector promotion when there are loads or stores of an FCA. return false; } else if (LoadInst *LI = dyn_cast(U->getUser())) { - if (LI->isVolatile()) + if (!LI->isSimple()) return false; Type *LTy = LI->getType(); if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) { @@ -1982,7 +1982,7 @@ if (!canConvertValue(DL, SliceTy, LTy)) return false; } else if (StoreInst *SI = dyn_cast(U->getUser())) { - if (SI->isVolatile()) + if (!SI->isSimple()) return false; Type *STy = SI->getValueOperand()->getType(); if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) { @@ -2132,7 +2132,7 @@ Use *U = S.getUse(); if (LoadInst *LI = dyn_cast(U->getUser())) { - if (LI->isVolatile()) + if (!LI->isSimple()) return false; // Note that we don't count vector loads or stores as whole-alloca // operations which enable integer widening because we would prefer to use @@ -2150,7 +2150,7 @@ } } else if (StoreInst *SI = dyn_cast(U->getUser())) { Type *ValueTy = SI->getValueOperand()->getType(); - if (SI->isVolatile()) + if (!SI->isSimple()) return false; // Note that we don't count vector loads or stores as whole-alloca // operations which enable integer widening because we would prefer to use @@ -2567,7 +2567,7 @@ Value *rewriteIntegerLoad(LoadInst &LI) { assert(IntTy && "We cannot insert an integer to the alloca"); - assert(!LI.isVolatile()); + assert(LI.isSimple()); Value *V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), "load"); V = convertValue(DL, IRB, V, IntTy); assert(NewBeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); @@ -2591,16 +2591,27 @@ V = rewriteVectorizedLoadInst(); } else if (IntTy && LI.getType()->isIntegerTy()) { V = rewriteIntegerLoad(LI); - } else if (NewBeginOffset == NewAllocaBeginOffset && - canConvertValue(DL, NewAllocaTy, LI.getType())) { - V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), LI.isVolatile(), - LI.getName()); } else { - Type *LTy = TargetTy->getPointerTo(); - V = IRB.CreateAlignedLoad(getNewAllocaSlicePtr(IRB, LTy), - getSliceAlign(TargetTy), LI.isVolatile(), - LI.getName()); - IsPtrAdjusted = true; + if (NewBeginOffset == NewAllocaBeginOffset && + canConvertValue(DL, NewAllocaTy, LI.getType())) { + V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), LI.isVolatile(), + LI.getName()); + } else { + Type *LTy = TargetTy->getPointerTo(); + V = IRB.CreateAlignedLoad(getNewAllocaSlicePtr(IRB, LTy), + getSliceAlign(TargetTy), LI.isVolatile(), + LI.getName()); + IsPtrAdjusted = true; + } + if (LI.isAtomic()) { + auto *NewLI = cast(V); + if (!NewLI->getAlignment()) { + auto *LTy = + NewLI->getPointerOperand()->getType()->getPointerElementType(); + NewLI->setAlignment(DL.getABITypeAlignment(LTy)); + } + NewLI->setAtomic(LI.getOrdering(), LI.getSynchScope()); + } } V = convertValue(DL, IRB, V, TargetTy); @@ -2633,7 +2644,7 @@ Pass.DeadInsts.insert(&LI); deleteIfTriviallyDead(OldOp); DEBUG(dbgs() << " to: " << *V << "\n"); - return !LI.isVolatile() && !IsPtrAdjusted; + return LI.isSimple() && !IsPtrAdjusted; } bool rewriteVectorizedStoreInst(Value *V, StoreInst &SI, Value *OldOp) { @@ -2663,7 +2674,7 @@ bool rewriteIntegerStore(Value *V, StoreInst &SI) { assert(IntTy && "We cannot extract an integer from the alloca"); - assert(!SI.isVolatile()); + assert(SI.isSimple()); if (DL.getTypeSizeInBits(V->getType()) != IntTy->getBitWidth()) { Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), "oldload"); @@ -2722,12 +2733,19 @@ NewSI = IRB.CreateAlignedStore(V, NewPtr, getSliceAlign(V->getType()), SI.isVolatile()); } - (void)NewSI; + if (SI.isAtomic()) { + if (!NewSI->getAlignment()) { + auto *STy = + NewSI->getPointerOperand()->getType()->getPointerElementType(); + NewSI->setAlignment(DL.getABITypeAlignment(STy)); + } + NewSI->setAtomic(SI.getOrdering(), SI.getSynchScope()); + } Pass.DeadInsts.insert(&SI); deleteIfTriviallyDead(OldOp); DEBUG(dbgs() << " to: " << *NewSI << "\n"); - return NewSI->getPointerOperand() == &NewAI && !SI.isVolatile(); + return NewSI->getPointerOperand() == &NewAI && SI.isSimple(); } /// \brief Compute an integer value from splatting an i8 across the given Index: test/Transforms/SROA/atomic.ll =================================================================== --- /dev/null +++ test/Transforms/SROA/atomic.ll @@ -0,0 +1,48 @@ +; RUN: opt -sroa -S < %s | FileCheck %s +target triple = "x86_64-pc-linux" + +define void @PR23737(i64** %x) { +; CHECK-LABEL: PR23737 +entry: + %ptr = alloca i64, align 8 + store atomic i64 0, i64* %ptr seq_cst, align 8 + %load = load atomic volatile i64, i64* %ptr seq_cst, align 8 + ;CHECK: load atomic volatile i64, i64* %{{.*}} seq_cst, align 8 + ret void +} + +define void @test_align(i64** %x) { +; CHECK-LABEL: test_align +entry: + %ptr = alloca i64, align 4 + store atomic i64 0, i64* %ptr seq_cst, align 4 + ; CHECK: store atomic i64 0, i64* %{{.*}} seq_cst, align 4 + %load = load atomic i64, i64* %ptr seq_cst, align 4 + ; CHECK: load atomic i64, i64* %{{.*}} seq_cst, align 4 + + ret void +} + +define i32 @test_vector_prom(<4 x i32> %x, <4 x i32> %y) { +; CHECK-LABEL: @test_vector_prom +entry: + %a = alloca [2 x <4 x i32>], align 8 +; CHECK: alloca + + %a.tmp1 = getelementptr inbounds [2 x <4 x i32>], [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2 + %tmp1 = load atomic i32, i32* %a.tmp1 seq_cst, align 8 +; CHECK: load atomic + ret i32 %tmp1 +} + +%list = type { %list*, i32 } +define i32 @test_integer_prom(i32 %i) { +; CHECK-LABEL: @test_integer_prom +entry: + %a = alloca %list, align 4 + ; CHECK: alloca + %ptr = getelementptr inbounds %list, %list* %a, i32 0, i32 1 + store atomic volatile i32 %i, i32* %ptr seq_cst, align 4 +; CHECK: store atomic volatile i32 %{{.*}}, i32* %{{.*}} seq_cst, align 4 + ret i32 %i +}