forked from OSchip/llvm-project
Update SimplifyCFG for atomic operations.
This commit includes a mention of the landingpad instruction, but it's not changing the behavior around it. I think the current behavior is correct, though. Bill, can you double-check that? llvm-svn: 137691
This commit is contained in:
parent
01a67111d1
commit
0ffdf2ea0b
|
@ -2244,18 +2244,34 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
|
|||
while (UI != BB->begin()) {
|
||||
BasicBlock::iterator BBI = UI;
|
||||
--BBI;
|
||||
// Do not delete instructions that can have side effects, like calls
|
||||
// (which may never return) and volatile loads and stores.
|
||||
// Do not delete instructions that can have side effects which might cause
|
||||
// the unreachable to not be reachable; specifically, calls and volatile
|
||||
// operations may have this effect.
|
||||
if (isa<CallInst>(BBI) && !isa<DbgInfoIntrinsic>(BBI)) break;
|
||||
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
|
||||
if (SI->isVolatile())
|
||||
|
||||
if (BBI->mayHaveSideEffects()) {
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) {
|
||||
if (SI->isVolatile())
|
||||
break;
|
||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
|
||||
if (LI->isVolatile())
|
||||
break;
|
||||
} else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(BBI)) {
|
||||
if (RMWI->isVolatile())
|
||||
break;
|
||||
} else if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(BBI)) {
|
||||
if (CXI->isVolatile())
|
||||
break;
|
||||
} else if (!isa<FenceInst>(BBI) && !isa<VAArgInst>(BBI) &&
|
||||
!isa<LandingPadInst>(BBI)) {
|
||||
break;
|
||||
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(BBI))
|
||||
if (LI->isVolatile())
|
||||
break;
|
||||
|
||||
}
|
||||
// Note that deleting LandingPad's here is in fact okay, although it
|
||||
// involves a bit of subtle reasoning. If this inst is a LandingPad,
|
||||
// all the predecessors of this block will be the unwind edges of Invokes,
|
||||
// and we can therefore guaranteed this block will be erased.
|
||||
}
|
||||
|
||||
// Delete this instruction (any uses are guaranteed to be dead)
|
||||
if (!BBI->use_empty())
|
||||
BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
|
||||
|
|
|
@ -42,3 +42,46 @@ entry:
|
|||
; CHECK: store volatile i32 4, i32* null
|
||||
; CHECK: ret
|
||||
}
|
||||
|
||||
; Check store before unreachable.
|
||||
define void @test4(i1 %C, i32* %P) {
|
||||
; CHECK: @test4
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: br i1 %C
|
||||
entry:
|
||||
br i1 %C, label %T, label %F
|
||||
T:
|
||||
store volatile i32 0, i32* %P
|
||||
unreachable
|
||||
F:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check cmpxchg before unreachable.
|
||||
define void @test5(i1 %C, i32* %P) {
|
||||
; CHECK: @test5
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: br i1 %C
|
||||
entry:
|
||||
br i1 %C, label %T, label %F
|
||||
T:
|
||||
cmpxchg volatile i32* %P, i32 0, i32 1 seq_cst
|
||||
unreachable
|
||||
F:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check atomicrmw before unreachable.
|
||||
define void @test6(i1 %C, i32* %P) {
|
||||
; CHECK: @test6
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: br i1 %C
|
||||
entry:
|
||||
br i1 %C, label %T, label %F
|
||||
T:
|
||||
atomicrmw volatile xchg i32* %P, i32 0 seq_cst
|
||||
unreachable
|
||||
F:
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue