/// Insert an unreachable instruction before the specified
/// instruction, making it and the rest of the code in the block dead.
-unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap);
+unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap,
+ bool PreserveLCSSA = false);
/// Convert the CallInst to InvokeInst with the specified unwind edge basic
/// block. This also splits the basic block where CI is located, because
return NumDeadInst;
}
-unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap) {
+unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
+ bool PreserveLCSSA) {
BasicBlock *BB = I->getParent();
// Loop over all of the successors, removing BB's entry from any PHI
// nodes.
for (BasicBlock *Successor : successors(BB))
- Successor->removePredecessor(BB);
+ Successor->removePredecessor(BB, PreserveLCSSA);
// Insert a call to llvm.trap right before this. This turns the undefined
// behavior into a hard fail instead of falling through into random code.
// Zap the dead pred's terminator and replace it with unreachable.
TerminatorInst *TI = P->getTerminator();
- changeToUnreachable(TI, /*UseLLVMTrap=*/false);
+ changeToUnreachable(TI, /*UseLLVMTrap=*/false, PreserveLCSSA);
Changed = true;
}
}
--- /dev/null
+; RUN: opt < %s -lcssa -licm -S | FileCheck %s
+; PR30454
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare i8 @bar()
+
+; Test that we preserve LCSSA form when removing edges from unreachable blocks.
+; CHECK-LABEL: @foo
+define void @foo() {
+entry:
+ br label %for.cond
+
+for.cond:
+ %x = phi i8 [ undef, %entry ], [ %y, %for.latch ]
+ br i1 undef, label %for.latch, label %exit
+
+; CHECK: unreachable.bb:
+; CHECK-NEXT: unreachable
+unreachable.bb:
+ br i1 undef, label %exit, label %for.latch
+
+for.latch:
+ %y = call i8 @bar()
+ br label %for.cond
+
+; CHECK: exit:
+; CHECK-NEXT: %x.lcssa = phi i8 [ %x, %for.cond ]
+exit:
+ %z = zext i8 %x to i32
+ ret void
+}