diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/Local.h | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopSimplify.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopSimplify/pr30454.ll | 32 |
4 files changed, 38 insertions, 4 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index d967bd5840a..063e6aa5d22 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -312,7 +312,8 @@ unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB); /// 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 diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 3ad5f58e6cb..01a5579e1ed 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1369,12 +1369,13 @@ unsigned llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) { 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. diff --git a/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/llvm/lib/Transforms/Utils/LoopSimplify.cpp index d24c1c41557..00cda2af00c 100644 --- a/llvm/lib/Transforms/Utils/LoopSimplify.cpp +++ b/llvm/lib/Transforms/Utils/LoopSimplify.cpp @@ -530,7 +530,7 @@ ReprocessLoop: // 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; } } diff --git a/llvm/test/Transforms/LoopSimplify/pr30454.ll b/llvm/test/Transforms/LoopSimplify/pr30454.ll new file mode 100644 index 00000000000..3dcc393aa81 --- /dev/null +++ b/llvm/test/Transforms/LoopSimplify/pr30454.ll @@ -0,0 +1,32 @@ +; 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 +} |