From: Matt Arsenault Date: Fri, 21 Apr 2017 23:54:12 +0000 (+0000) Subject: LowerSwitch: Fix producing invalid IR on unreachable code X-Git-Tag: llvmorg-5.0.0-rc1~6966 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=01d17e7c5f8c19b3e63ab3bf90ecf11b60175c5e;p=platform%2Fupstream%2Fllvm.git LowerSwitch: Fix producing invalid IR on unreachable code If a switch was in an unreachable block that branched to a block with a phi, it would leave phis with missing predecessors. llvm-svn: 301064 --- diff --git a/llvm/lib/Transforms/Utils/LowerSwitch.cpp b/llvm/lib/Transforms/Utils/LowerSwitch.cpp index b375d51..8959e77 100644 --- a/llvm/lib/Transforms/Utils/LowerSwitch.cpp +++ b/llvm/lib/Transforms/Utils/LowerSwitch.cpp @@ -403,6 +403,14 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI, Value *Val = SI->getCondition(); // The value we are switching on... BasicBlock* Default = SI->getDefaultDest(); + // Don't handle unreachable blocks. If there are successors with phis, this + // would leave them behind with missing predecessors. + if ((CurBlock != &F->getEntryBlock() && pred_empty(CurBlock)) || + CurBlock->getSinglePredecessor() == CurBlock) { + DeleteList.insert(CurBlock); + return; + } + // If there is only the default destination, just branch. if (!SI->getNumCases()) { BranchInst::Create(Default, CurBlock); diff --git a/llvm/test/Transforms/LowerSwitch/phi-in-dead-block.ll b/llvm/test/Transforms/LowerSwitch/phi-in-dead-block.ll new file mode 100644 index 0000000..a632584 --- /dev/null +++ b/llvm/test/Transforms/LowerSwitch/phi-in-dead-block.ll @@ -0,0 +1,40 @@ +; RUN: opt -S -lowerswitch %s | FileCheck %s + +; CHECK-LABEL: @phi_in_dead_block( +; CHECK-NOT: switch +define void @phi_in_dead_block() { +bb: + br i1 undef, label %bb2, label %bb3 + +bb1: ; No predecessors! + switch i32 undef, label %bb2 [ + i32 9, label %bb3 + ] + +bb2: ; preds = %bb1, %bb + %tmp = phi i64 [ undef, %bb1 ], [ undef, %bb ] + unreachable + +bb3: ; preds = %bb1, %bb + unreachable +} + +; CHECK-LABEL: @phi_in_dead_block_br_to_self( +; CHECK-NOT: switch +define void @phi_in_dead_block_br_to_self() { +bb: + br i1 undef, label %bb2, label %bb3 + +bb1: ; No predecessors! + switch i32 undef, label %bb2 [ + i32 9, label %bb3 + i32 10, label %bb1 + ] + +bb2: ; preds = %bb1, %bb + %tmp = phi i64 [ undef, %bb1 ], [ undef, %bb ] + unreachable + +bb3: ; preds = %bb1, %bb + unreachable +}