From: Michael Zolotukhin Date: Fri, 18 Nov 2016 21:01:12 +0000 (+0000) Subject: [LoopSimplify] Preserve LCSSA when removing edges from unreachable blocks. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a7f010bf70d821913877f20d4b373c28592b1cb;p=llvm [LoopSimplify] Preserve LCSSA when removing edges from unreachable blocks. This fixes PR30454. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287379 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index d967bd5840a..063e6aa5d22 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/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/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 3ad5f58e6cb..01a5579e1ed 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/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/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index d24c1c41557..00cda2af00c 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/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/test/Transforms/LoopSimplify/pr30454.ll b/test/Transforms/LoopSimplify/pr30454.ll new file mode 100644 index 00000000000..3dcc393aa81 --- /dev/null +++ b/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 +}