OSDN Git Service

[LoopSimplify] Preserve LCSSA when removing edges from unreachable blocks.
authorMichael Zolotukhin <mzolotukhin@apple.com>
Fri, 18 Nov 2016 21:01:12 +0000 (21:01 +0000)
committerMichael Zolotukhin <mzolotukhin@apple.com>
Fri, 18 Nov 2016 21:01:12 +0000 (21:01 +0000)
This fixes PR30454.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287379 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/Local.h
lib/Transforms/Utils/Local.cpp
lib/Transforms/Utils/LoopSimplify.cpp
test/Transforms/LoopSimplify/pr30454.ll [new file with mode: 0644]

index d967bd5..063e6aa 100644 (file)
@@ -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
index 3ad5f58..01a5579 100644 (file)
@@ -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.
index d24c1c4..00cda2a 100644 (file)
@@ -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 (file)
index 0000000..3dcc393
--- /dev/null
@@ -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
+}