From: Eli Friedman Date: Mon, 15 Aug 2011 23:59:28 +0000 (+0000) Subject: Update SimplifyCFG for atomic operations. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8176388d65083339efdfa5bee63e620c6bd05aa1;p=oota-llvm.git 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? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137691 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 52145b9c978..850ee490056 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -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(BBI) && !isa(BBI)) break; - - if (StoreInst *SI = dyn_cast(BBI)) - if (SI->isVolatile()) - break; - - if (LoadInst *LI = dyn_cast(BBI)) - if (LI->isVolatile()) + + if (BBI->mayHaveSideEffects()) { + if (StoreInst *SI = dyn_cast(BBI)) { + if (SI->isVolatile()) + break; + } else if (LoadInst *LI = dyn_cast(BBI)) { + if (LI->isVolatile()) + break; + } else if (AtomicRMWInst *RMWI = dyn_cast(BBI)) { + if (RMWI->isVolatile()) + break; + } else if (AtomicCmpXchgInst *CXI = dyn_cast(BBI)) { + if (CXI->isVolatile()) + break; + } else if (!isa(BBI) && !isa(BBI) && + !isa(BBI)) { 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())); diff --git a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll index ebf4f171a3d..10d6981af0e 100644 --- a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll +++ b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll @@ -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 +} +