diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2240,13 +2240,15 @@ --MaxNumInstToLookAt; // Could be calling an instruction that affects memory like free(). - if (CurI.mayHaveSideEffects() && !isa(CurI)) + if (CurI.mayWriteToMemory() && !isa(CurI)) return nullptr; if (auto *SI = dyn_cast(&CurI)) { - // Found the previous store make sure it stores to the same location. + // Found the previous store to same location and type. Make sure it is + // simple, to avoid introducing a spurious non-atomic write after an + // atomic write. if (SI->getPointerOperand() == StorePtr && - SI->getValueOperand()->getType() == StoreTy) + SI->getValueOperand()->getType() == StoreTy && SI->isSimple()) // Found the previous store, return its value operand. return SI->getValueOperand(); return nullptr; // Unknown store. diff --git a/llvm/test/Transforms/SimplifyCFG/speculate-store.ll b/llvm/test/Transforms/SimplifyCFG/speculate-store.ll --- a/llvm/test/Transforms/SimplifyCFG/speculate-store.ll +++ b/llvm/test/Transforms/SimplifyCFG/speculate-store.ll @@ -135,13 +135,11 @@ define void @readonly_call(ptr %ptr, i1 %cmp) { ; CHECK-LABEL: @readonly_call( +; CHECK-NEXT: ret.end: ; CHECK-NEXT: store i32 0, ptr [[PTR:%.*]], align 4 ; CHECK-NEXT: call void @unknown_fun() #[[ATTR0:[0-9]+]] -; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[RET_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4 -; CHECK-NEXT: br label [[RET_END]] -; CHECK: ret.end: +; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[CMP:%.*]], i32 1, i32 0 +; CHECK-NEXT: store i32 [[SPEC_STORE_SELECT]], ptr [[PTR]], align 4 ; CHECK-NEXT: ret void ; store i32 0, ptr %ptr @@ -158,10 +156,12 @@ define void @atomic_and_simple(ptr %ptr, i1 %cmp) { ; CHECK-LABEL: @atomic_and_simple( -; CHECK-NEXT: ret.end: ; CHECK-NEXT: store atomic i32 0, ptr [[PTR:%.*]] seq_cst, align 4 -; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[CMP:%.*]], i32 1, i32 0 -; CHECK-NEXT: store i32 [[SPEC_STORE_SELECT]], ptr [[PTR]], align 4 +; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[RET_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4 +; CHECK-NEXT: br label [[RET_END]] +; CHECK: ret.end: ; CHECK-NEXT: ret void ; store atomic i32 0, ptr %ptr seq_cst, align 4