<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Thanks for reverting this.  I think it also caused some LTO failures on green dragon, although I was still trying to reproduce them to make sure.<div class=""><br class=""></div><div class="">More detail is here (<a href="http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build/8797/consoleFull" class="">http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build/8797/consoleFull</a>), but were you seeing something like the following?</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="">While deleting: i8* %</div></div><div class=""><div class="">Use still stuck around after Def is destroyed:  call void @llvm.lifetime.end(i64 24, i8* nonnull <badref>) #3, !dbg !4862</div></div><div class=""><div class="">Use still stuck around after Def is destroyed:  %.pre194 = load i8, i8* <badref>, align 8, !dbg !4799, !tbaa !4501</div></div><div class=""><div class="">Use still stuck around after Def is destroyed:  call void @llvm.memset.p0i8.i64(i8* <badref>, i8 0, i64 24, i32 8, i1 false) #3, !dbg !4783, !alias.scope !4791</div></div><div class=""><br class="Apple-interchange-newline"></div><div class="">Assertion failed: (use_empty() && "Uses remain when a value is destroyed!"), function ~Value, file /Users/buildslave/jenkins/sharedspace/phase1@2/llvm/lib/IR/Value.cpp, line 85.</div></blockquote><div class=""><br class=""></div>Cheers,<div class="">Pete<br class=""><div class=""><div><blockquote type="cite" class=""><div class="">On May 2, 2016, at 12:43 PM, Reid Kleckner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Author: rnk<br class="">Date: Mon May  2 14:43:22 2016<br class="">New Revision: 268288<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=268288&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=268288&view=rev</a><br class="">Log:<br class="">Revert "[SimplifyCFG] Extend TryToSimplifyUncondBranchFromEmptyBlock for empty block including lifetime intrinsics"<br class=""><br class="">This reverts commit r268254.<br class=""><br class="">This change causes assertion failures while building Chromium. Reduced<br class="">test case coming soon.<br class=""><br class="">Modified:<br class="">    llvm/trunk/include/llvm/IR/BasicBlock.h<br class="">    llvm/trunk/lib/IR/BasicBlock.cpp<br class="">    llvm/trunk/lib/Transforms/Utils/Local.cpp<br class="">    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br class="">    llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll<br class=""><br class="">Modified: llvm/trunk/include/llvm/IR/BasicBlock.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=268288&r1=268287&r2=268288&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=268288&r1=268287&r2=268288&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)<br class="">+++ llvm/trunk/include/llvm/IR/BasicBlock.h Mon May  2 14:43:22 2016<br class="">@@ -152,15 +152,6 @@ public:<br class="">     return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();<br class="">   }<br class=""><br class="">-  /// \brief Returns a pointer to the first instruction in this block that is<br class="">-  /// not a PHINode, a debug intrinsic, a lifetime intrinsic, or a bitcast<br class="">-  /// instruction coupled with the following lifetime intrinsic.<br class="">-  Instruction *getFirstNonPHIOrDbgOrLifetimeOrBitCast();<br class="">-  const Instruction *getFirstNonPHIOrDbgOrLifetimeOrBitCast() const {<br class="">-    return const_cast<BasicBlock *>(this)<br class="">-        ->getFirstNonPHIOrDbgOrLifetimeOrBitCast();<br class="">-  }<br class="">-<br class="">   /// \brief Returns an iterator to the first instruction in this block that is<br class="">   /// suitable for inserting a non-PHI instruction.<br class="">   ///<br class=""><br class="">Modified: llvm/trunk/lib/IR/BasicBlock.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=268288&r1=268287&r2=268288&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=268288&r1=268287&r2=268288&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/IR/BasicBlock.cpp (original)<br class="">+++ llvm/trunk/lib/IR/BasicBlock.cpp Mon May  2 14:43:22 2016<br class="">@@ -206,30 +206,6 @@ Instruction* BasicBlock::getFirstNonPHIO<br class="">   return nullptr;<br class=""> }<br class=""><br class="">-Instruction *BasicBlock::getFirstNonPHIOrDbgOrLifetimeOrBitCast() {<br class="">-  for (Instruction &I : *this) {<br class="">-    if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))<br class="">-      continue;<br class="">-<br class="">-    if (auto *II = dyn_cast<IntrinsicInst>(&I))<br class="">-      if (II->getIntrinsicID() == Intrinsic::lifetime_start ||<br class="">-          II->getIntrinsicID() == Intrinsic::lifetime_end)<br class="">-        continue;<br class="">-<br class="">-    if (auto *BCI = dyn_cast<BitCastInst>(&I)) {<br class="">-      if (auto *II = dyn_cast<IntrinsicInst>(++I.getIterator())) {<br class="">-        if ((II->getIntrinsicID() == Intrinsic::lifetime_start ||<br class="">-             II->getIntrinsicID() == Intrinsic::lifetime_end) &&<br class="">-            II->getOperand(1) == BCI) {<br class="">-          continue;<br class="">-        }<br class="">-      }<br class="">-    }<br class="">-    return &I;<br class="">-  }<br class="">-  return nullptr;<br class="">-}<br class="">-<br class=""> BasicBlock::iterator BasicBlock::getFirstInsertionPt() {<br class="">   Instruction *FirstNonPHI = getFirstNonPHI();<br class="">   if (!FirstNonPHI)<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=268288&r1=268287&r2=268288&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=268288&r1=268287&r2=268288&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)<br class="">+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon May  2 14:43:22 2016<br class="">@@ -800,55 +800,6 @@ static void redirectValuesFromPredecesso<br class="">   replaceUndefValuesInPhi(PN, IncomingValues);<br class=""> }<br class=""><br class="">-/// Return true if BB has lifetime.end intrinsic.<br class="">-///<br class="">-static bool hasLifetime(BasicBlock *BB) {<br class="">-  for (auto &I : *BB) {<br class="">-    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) {<br class="">-      if (II->getIntrinsicID() == Intrinsic::lifetime_end ||<br class="">-          II->getIntrinsicID() == Intrinsic::lifetime_start) {<br class="">-        return true;<br class="">-      }<br class="">-    }<br class="">-  }<br class="">-  return false;<br class="">-}<br class="">-<br class="">-/// hoistLifetimeFromEmptyBlockToPred - Hoist lifetime.end intrinsics and<br class="">-/// related bitcast instructions from BB to predecessors of BB.<br class="">-///<br class="">-static bool hoistLifetimeFromEmptyBlockToPred(BasicBlock *BB) {<br class="">-  // Check to see if all Preds have single successor and if not, we cannot<br class="">-  // hoist lifetime intrinsics because it would change semantics.<br class="">-  for (auto Pred : predecessors(BB))<br class="">-    if (!Pred->getSingleSuccessor())<br class="">-      return false;<br class="">-<br class="">-  // Hoist all lifetime.end intrinsics and related bitcast instrunctions<br class="">-  // in BB to Preds.<br class="">-  for (auto &I : *BB) {<br class="">-    if (auto *II = dyn_cast<IntrinsicInst>(&I)) {<br class="">-      if (II->getIntrinsicID() == Intrinsic::lifetime_end ||<br class="">-          II->getIntrinsicID() == Intrinsic::lifetime_start) {<br class="">-        for (auto Pred : predecessors(BB)) {<br class="">-          Instruction *NewII = I.clone();<br class="">-          NewII->insertBefore(Pred->getTerminator());<br class="">-<br class="">-          if (I.getIterator() != BB->begin()) {<br class="">-            if (auto BC = dyn_cast<BitCastInst>(--I.getIterator())) {<br class="">-              assert(BC == I.getOperand(1));<br class="">-              auto NewBC = BC->clone();<br class="">-              NewBC->insertBefore(NewII);<br class="">-              NewII->setOperand(1, NewBC);<br class="">-            }<br class="">-          }<br class="">-        }<br class="">-      }<br class="">-    }<br class="">-  }<br class="">-  return true;<br class="">-}<br class="">-<br class=""> /// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an<br class=""> /// unconditional branch, and contains no instructions other than PHI nodes,<br class=""> /// potential side-effect free intrinsics and the branch.  If possible,<br class="">@@ -862,118 +813,74 @@ bool llvm::TryToSimplifyUncondBranchFrom<br class="">   BasicBlock *Succ = cast<BranchInst>(BB->getTerminator())->getSuccessor(0);<br class="">   if (BB == Succ) return false;<br class=""><br class="">-  // If BB has lifetime.end intrinsics, simplify BB under more constraints.<br class="">-  if (hasLifetime(BB)) {<br class="">-    // Check to see if BB and its predecessors and successors have PHI.<br class="">-    if (isa<PHINode>(BB->begin()))<br class="">-      return false;<br class="">-<br class="">-    for (auto Pred : predecessors(BB))<br class="">-      if (isa<PHINode>(Pred->begin()))<br class="">-        return false;<br class="">-<br class="">-    for (auto Succ : successors(BB))<br class="">-      if (isa<PHINode>(Succ->begin()))<br class="">-        return false;<br class="">-<br class="">-    if (Succ->getSinglePredecessor()) {<br class="">-      // BB is the only predecessor of Succ, so Succ will end up with exactly<br class="">-      // the same predecessors BB had.<br class="">-<br class="">-      // Copy over any debug or lifetime instruction.<br class="">-      BB->getTerminator()->eraseFromParent();<br class="">-      Succ->getInstList().splice(Succ->getFirstNonPHI()->getIterator(),<br class="">-                                 BB->getInstList());<br class="">-<br class="">-    } else {<br class="">-      // Unless BB is the only predecessor of Succ, hoist lifetime intrinsics<br class="">-      // to predecessors of BB and simplify BB.<br class="">-      if (!hoistLifetimeFromEmptyBlockToPred(BB)) {<br class="">-        return false;<br class="">-      }<br class="">-    }<br class="">-<br class="">-    DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);<br class="">-<br class="">-    // Everything that jumped to BB now goes to Succ.<br class="">-    BB->replaceAllUsesWith(Succ);<br class="">-    if (!Succ->hasName())<br class="">-      Succ->takeName(BB);<br class="">-    BB->eraseFromParent(); // Delete the old basic block.<br class="">-    return true;<br class="">-  } else {<br class="">-    // Check to see if merging these blocks would cause conflicts for any of the<br class="">-    // phi nodes in BB or Succ. If not, we can safely merge.<br class="">-    if (!CanPropagatePredecessorsForPHIs(BB, Succ))<br class="">-      return false;<br class="">-<br class="">-    // Check for cases where Succ has multiple predecessors and a PHI node in BB<br class="">-    // has uses which will not disappear when the PHI nodes are merged.  It is<br class="">-    // possible to handle such cases, but difficult: it requires checking<br class="">-    // whether BB dominates Succ, which is non-trivial to calculate in the<br class="">-    // case where Succ has multiple predecessors.  Also, it requires checking<br class="">-    // whether constructing the necessary self-referential PHI node doesn't<br class="">-    // introduce any conflicts; this isn't too difficult, but the previous code<br class="">-    // for doing this was incorrect.<br class="">-    //<br class="">-    // Note that if this check finds a live use, BB dominates Succ, so BB is<br class="">-    // something like a loop pre-header (or rarely, a part of an irreducible<br class="">-    // CFG);<br class="">-    // folding the branch isn't profitable in that case anyway.<br class="">-    if (!Succ->getSinglePredecessor()) {<br class="">-      BasicBlock::iterator BBI = BB->begin();<br class="">-      while (isa<PHINode>(*BBI)) {<br class="">-        for (Use &U : BBI->uses()) {<br class="">-          if (PHINode *PN = dyn_cast<PHINode>(U.getUser())) {<br class="">-            if (PN->getIncomingBlock(U) != BB)<br class="">-              return false;<br class="">-          } else {<br class="">+  // Check to see if merging these blocks would cause conflicts for any of the<br class="">+  // phi nodes in BB or Succ. If not, we can safely merge.<br class="">+  if (!CanPropagatePredecessorsForPHIs(BB, Succ)) return false;<br class="">+<br class="">+  // Check for cases where Succ has multiple predecessors and a PHI node in BB<br class="">+  // has uses which will not disappear when the PHI nodes are merged.  It is<br class="">+  // possible to handle such cases, but difficult: it requires checking whether<br class="">+  // BB dominates Succ, which is non-trivial to calculate in the case where<br class="">+  // Succ has multiple predecessors.  Also, it requires checking whether<br class="">+  // constructing the necessary self-referential PHI node doesn't introduce any<br class="">+  // conflicts; this isn't too difficult, but the previous code for doing this<br class="">+  // was incorrect.<br class="">+  //<br class="">+  // Note that if this check finds a live use, BB dominates Succ, so BB is<br class="">+  // something like a loop pre-header (or rarely, a part of an irreducible CFG);<br class="">+  // folding the branch isn't profitable in that case anyway.<br class="">+  if (!Succ->getSinglePredecessor()) {<br class="">+    BasicBlock::iterator BBI = BB->begin();<br class="">+    while (isa<PHINode>(*BBI)) {<br class="">+      for (Use &U : BBI->uses()) {<br class="">+        if (PHINode* PN = dyn_cast<PHINode>(U.getUser())) {<br class="">+          if (PN->getIncomingBlock(U) != BB)<br class="">             return false;<br class="">-          }<br class="">+        } else {<br class="">+          return false;<br class="">         }<br class="">-        ++BBI;<br class="">       }<br class="">+      ++BBI;<br class="">     }<br class="">+  }<br class=""><br class="">-    DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);<br class="">+  DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);<br class=""><br class="">-    if (isa<PHINode>(Succ->begin())) {<br class="">-      // If there is more than one pred of succ, and there are PHI nodes in<br class="">-      // the successor, then we need to add incoming edges for the PHI nodes<br class="">-      //<br class="">-      const PredBlockVector BBPreds(pred_begin(BB), pred_end(BB));<br class="">-<br class="">-      // Loop over all of the PHI nodes in the successor of BB.<br class="">-      for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {<br class="">-        PHINode *PN = cast<PHINode>(I);<br class="">+  if (isa<PHINode>(Succ->begin())) {<br class="">+    // If there is more than one pred of succ, and there are PHI nodes in<br class="">+    // the successor, then we need to add incoming edges for the PHI nodes<br class="">+    //<br class="">+    const PredBlockVector BBPreds(pred_begin(BB), pred_end(BB));<br class=""><br class="">-        redirectValuesFromPredecessorsToPhi(BB, BBPreds, PN);<br class="">-      }<br class="">-    }<br class="">+    // Loop over all of the PHI nodes in the successor of BB.<br class="">+    for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {<br class="">+      PHINode *PN = cast<PHINode>(I);<br class=""><br class="">-    if (Succ->getSinglePredecessor()) {<br class="">-      // BB is the only predecessor of Succ, so Succ will end up with exactly<br class="">-      // the same predecessors BB had.<br class="">-<br class="">-      // Copy over any phi, debug or lifetime instruction.<br class="">-      BB->getTerminator()->eraseFromParent();<br class="">-      Succ->getInstList().splice(Succ->getFirstNonPHI()->getIterator(),<br class="">-                                 BB->getInstList());<br class="">-    } else {<br class="">-      while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {<br class="">-        // We explicitly check for such uses in CanPropagatePredecessorsForPHIs.<br class="">-        assert(PN->use_empty() && "There shouldn't be any uses here!");<br class="">-        PN->eraseFromParent();<br class="">-      }<br class="">+      redirectValuesFromPredecessorsToPhi(BB, BBPreds, PN);<br class="">     }<br class="">+  }<br class=""><br class="">-    // Everything that jumped to BB now goes to Succ.<br class="">-    BB->replaceAllUsesWith(Succ);<br class="">-    if (!Succ->hasName())<br class="">-      Succ->takeName(BB);<br class="">-    BB->eraseFromParent(); // Delete the old basic block.<br class="">-    return true;<br class="">+  if (Succ->getSinglePredecessor()) {<br class="">+    // BB is the only predecessor of Succ, so Succ will end up with exactly<br class="">+    // the same predecessors BB had.<br class="">+<br class="">+    // Copy over any phi, debug or lifetime instruction.<br class="">+    BB->getTerminator()->eraseFromParent();<br class="">+    Succ->getInstList().splice(Succ->getFirstNonPHI()->getIterator(),<br class="">+                               BB->getInstList());<br class="">+  } else {<br class="">+    while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {<br class="">+      // We explicitly check for such uses in CanPropagatePredecessorsForPHIs.<br class="">+      assert(PN->use_empty() && "There shouldn't be any uses here!");<br class="">+      PN->eraseFromParent();<br class="">+    }<br class="">   }<br class="">+<br class="">+  // Everything that jumped to BB now goes to Succ.<br class="">+  BB->replaceAllUsesWith(Succ);<br class="">+  if (!Succ->hasName()) Succ->takeName(BB);<br class="">+  BB->eraseFromParent();              // Delete the old basic block.<br class="">+  return true;<br class=""> }<br class=""><br class=""> /// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=268288&r1=268287&r2=268288&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=268288&r1=268287&r2=268288&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)<br class="">+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon May  2 14:43:22 2016<br class="">@@ -5056,15 +5056,14 @@ bool SimplifyCFGOpt::SimplifyUncondBranc<br class=""><br class="">   if (SinkCommon && SinkThenElseCodeToEnd(BI))<br class="">     return true;<br class="">-  // If the Terminator is the only non-phi instruction except for bitcast<br class="">-  // instruction coupled with the following lifetime intrinsic, simplify the<br class="">-  // block. If LoopHeader is provided, check if the block is a loop header<br class="">+<br class="">+  // If the Terminator is the only non-phi instruction, simplify the block.<br class="">+  // if LoopHeader is provided, check if the block is a loop header<br class="">   // (This is for early invocations before loop simplify and vectorization<br class="">   // to keep canonical loop forms for nested loops.<br class="">   // These blocks can be eliminated when the pass is invoked later<br class="">   // in the back-end.)<br class="">-  BasicBlock::iterator I =<br class="">-      BB->getFirstNonPHIOrDbgOrLifetimeOrBitCast()->getIterator();<br class="">+  BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();<br class="">   if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&<br class="">       (!LoopHeaders || !LoopHeaders->count(BB)) &&<br class="">       TryToSimplifyUncondBranchFromEmptyBlock(BB))<br class=""><br class="">Modified: llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll?rev=268288&r1=268287&r2=268288&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll?rev=268288&r1=268287&r2=268288&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll (original)<br class="">+++ llvm/trunk/test/Transforms/SimplifyCFG/lifetime.ll Mon May  2 14:43:22 2016<br class="">@@ -1,9 +1,6 @@<br class=""> ; RUN: opt < %s -simplifycfg -S | FileCheck %s<br class=""><br class=""> ; Test that a lifetime intrinsic isn't removed because that would change semantics<br class="">-; This case is that predecessor(s) of the target empty block (bb0) has multiple<br class="">-; successors (bb0 and bb1) and its successor has multiple predecessors (entry and<br class="">-; bb0).<br class=""><br class=""> ; CHECK: foo<br class=""> ; CHECK: entry:<br class="">@@ -30,232 +27,3 @@ declare void @f()<br class=""> declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind<br class=""><br class=""> declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind<br class="">-<br class="">-; Test that empty block including lifetime intrinsic and not related bitcast<br class="">-; instruction cannot be removed. It is because the block is not empty.<br class="">- <br class="">-; CHECK-LABEL: coo<br class="">-; CHECK-LABEL: entry:<br class="">-; CHECK-LABEL: if.then:<br class="">-; CHECK-LABEL: if.else:<br class="">-; CHECK-LABEL: if.end:<br class="">-; CHECK-LABEL: bb:<br class="">-; CHECK: ret<br class="">-<br class="">-define void @coo(i1 %x, i1 %y) {<br class="">-entry:<br class="">-  %a = alloca i8, align 4<br class="">-  %b = alloca i32, align 4<br class="">-  br label %while.cond<br class="">-<br class="">-while.cond:                                       ; preds = %if.end, %entry<br class="">-  br i1 %y, label %while.body, label %bb<br class="">-<br class="">-while.body:                                       ; preds = %while.cond<br class="">-  call void @llvm.lifetime.start(i64 4, i8* %a)<br class="">-  %c = load i8, i8* %a, align 4<br class="">-  br i1 %x, label %if.then, label %if.else<br class="">-<br class="">-if.then:                                          ; preds = %while.body<br class="">-  %d = add i8 %c, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.else:                                          ; preds = %while.body<br class="">-  %e = sub i8 %c, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.end:                                           ; preds = %if.else, %if.then<br class="">-  %f = bitcast i32* %b to i8*<br class="">-  call void @llvm.lifetime.end(i64 4, i8* %a)<br class="">-  br label %while.cond<br class="">-<br class="">-bb:                                               ; preds = %while.cond<br class="">-  ret void<br class="">-}<br class="">-<br class="">-; Test that empty block including lifetime intrinsic can be removed.<br class="">-; Lifetime.end intrinsic is moved to predecessors because successor has <br class="">-; multiple predecessors.<br class="">-<br class="">-; CHECK-LABEL: soo<br class="">-; CHECK-LABEL: entry:<br class="">-; CHECK-LABEL: if.then:<br class="">-; CHECK-NEXT: %e<br class="">-; CHECK-NEXT: call void @llvm.lifetime.end<br class="">-; CHECK-LABEL: if.else:<br class="">-; CHECK-NEXT: %g<br class="">-; CHECK-NEXT: call void @llvm.lifetime.end<br class="">-; CHECK-NEXT: br label %while.cond<br class="">-; CHECK-NOT: if.end:<br class="">-; CHECK: ret<br class="">-<br class="">-define void @soo(i1 %x, i1 %y) {<br class="">-entry:<br class="">-  %a = alloca i8, align 4<br class="">-  br label %while.cond<br class="">-<br class="">-while.cond:                                       ; preds = %if.end, %entry<br class="">-  br i1 %y, label %while.body, label %bb<br class="">-<br class="">-while.body:                                       ; preds = %while.cond<br class="">-  call void @llvm.lifetime.start(i64 4, i8* %a)<br class="">-  %d = load i8, i8* %a, align 4<br class="">-  br i1 %x, label %if.then, label %if.else<br class="">-<br class="">-if.then:                                          ; preds = %while.body<br class="">-  %e = add i8 %d, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.else:                                          ; preds = %while.body<br class="">-  %g = sub i8 %d, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.end:                                           ; preds = %if.else, %if.then<br class="">-  call void @llvm.lifetime.end(i64 4, i8* %a)<br class="">-  br label %while.cond<br class="">-<br class="">-bb:                                               ; preds = %while.cond<br class="">-  ret void<br class="">-}<br class="">-<br class="">-; Test that empty block including lifetime intrinsic and related bitcast<br class="">-; instruction can be removed. Lifetime.end intrinsic and related bitcast <br class="">-; instruction are moved to predecessors because successor has multiple<br class="">-; predecessors.<br class="">-<br class="">-; CHECK-LABEL: boo<br class="">-; CHECK-LABEL: entry:<br class="">-; CHECK-LABEL: if.then:<br class="">-; CHECK-NEXT: %e<br class="">-; CHECK-NEXT: %[[T:[^ ]+]] = bitcast<br class="">-; CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* %[[T]])<br class="">-; CHECK-LABEL: if.else:<br class="">-; CHECK-NEXT: %g<br class="">-; CHECK-NEXT: %[[B:[^ ]+]] = bitcast<br class="">-; CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* %[[B]])<br class="">-; CHECK-NEXT: br label %while.cond<br class="">-; CHECK-NOT: if.end:<br class="">-; CHECK: ret<br class="">-<br class="">-define void @boo(i1 %x, i1 %y) {<br class="">-entry:<br class="">-  %a = alloca i32, align 4<br class="">-  br label %while.cond<br class="">-<br class="">-while.cond:                                       ; preds = %if.end, %entry<br class="">-  br i1 %y, label %while.body, label %bb<br class="">-<br class="">-while.body:                                       ; preds = %while.cond<br class="">-  %b = bitcast i32* %a to i8*<br class="">-  call void @llvm.lifetime.start(i64 4, i8* %b)<br class="">-  %d = load i32, i32* %a, align 4<br class="">-  br i1 %x, label %if.then, label %if.else<br class="">-<br class="">-if.then:                                          ; preds = %while.body<br class="">-  %e = add i32 %d, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.else:                                          ; preds = %while.body<br class="">-  %g = sub i32 %d, 1<br class="">-  br label %if.end<br class="">-<br class="">-if.end:                                           ; preds = %if.else, %if.then<br class="">-  %c = bitcast i32* %a to i8*<br class="">-  call void @llvm.lifetime.end(i64 4, i8* %c)<br class="">-  br label %while.cond<br class="">-<br class="">-bb:                                               ; preds = %while.cond<br class="">-  ret void<br class="">-}<br class="">-<br class="">-; Test that empty block including lifetime intrinsic can be removed.<br class="">-; Lifetime.start intrinsic is moved to predecessors because successor has <br class="">-; multiple predecessors.<br class="">-<br class="">-; CHECK-LABEL: koo<br class="">-; CHECK-LABEL: entry:<br class="">-; CHECK-LABEL: if.then:<br class="">-; CHECK-NEXT: call void @f<br class="">-; CHECK-NEXT: call void @llvm.lifetime.start<br class="">-; CHECK-LABEL: if.else:<br class="">-; CHECK-NEXT: call void @g<br class="">-; CHECK-NEXT: call void @llvm.lifetime.start<br class="">-; CHECK-NEXT: br label %bb<br class="">-; CHECK-NOT: if.end:<br class="">-; CHECK: ret<br class="">-<br class="">-define void @koo(i1 %x, i1 %y, i1 %z) {<br class="">-entry:<br class="">-  %a = alloca i8, align 4<br class="">-  br i1 %z, label %bb, label %bb0<br class="">-<br class="">-bb0:                                              ; preds = %entry<br class="">-  br i1 %x, label %if.then, label %if.else<br class="">-<br class="">-if.then:                                          ; preds = %bb0<br class="">-  call void @f()<br class="">-  br label %if.end<br class="">-<br class="">-if.else:                                          ; preds = %bb0<br class="">-  call void @g()<br class="">-  br label %if.end<br class="">-<br class="">-if.end:                                           ; preds = %if.else, %if.then<br class="">-  call void @llvm.lifetime.start(i64 4, i8* %a)<br class="">-  br label %bb<br class="">-<br class="">-bb:                                               ; preds = %if.end, %entry<br class="">-  %d = load i8, i8* %a, align 4<br class="">-  call void @llvm.lifetime.end(i64 4, i8* %a)<br class="">-  ret void<br class="">-}<br class="">-<br class="">-declare void @g()<br class="">-<br class="">-; Test that empty block including lifetime intrinsic and related bitcast<br class="">-; instruction can be removed. Lifetime.start intrinsic and related bitcast <br class="">-; instruction are moved to predecessors because successor has multiple<br class="">-; predecessors.<br class="">-<br class="">-<br class="">-; CHECK-LABEL: goo<br class="">-; CHECK-LABEL: entry:<br class="">-; CHECK-LABEL: if.then:<br class="">-; CHECK-NEXT: call void @f<br class="">-; CHECK-NEXT: %[[T:[^ ]+]] = bitcast<br class="">-; CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* %[[T]])<br class="">-; CHECK-LABEL: if.else:<br class="">-; CHECK-NEXT: call void @g<br class="">-; CHECK-NEXT: %[[B:[^ ]+]] = bitcast<br class="">-; CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* %[[B]])<br class="">-; CHECK-NEXT: br label %bb<br class="">-; CHECK-NOT: if.end:<br class="">-; CHECK: ret<br class="">-<br class="">-define void @goo(i1 %x, i1 %y, i1 %z) {<br class="">-entry:<br class="">-  %a = alloca i32, align 4<br class="">-  br i1 %z, label %bb, label %bb0<br class="">-<br class="">-bb0:                                              ; preds = %entry<br class="">-  br i1 %x, label %if.then, label %if.else<br class="">-<br class="">-if.then:                                          ; preds = %bb0<br class="">-  call void @f()<br class="">-  br label %if.end<br class="">-<br class="">-if.else:                                          ; preds = %bb0<br class="">-  call void @g()<br class="">-  br label %if.end<br class="">-<br class="">-if.end:                                           ; preds = %if.else, %if.then<br class="">-  %b = bitcast i32* %a to i8*<br class="">-  call void @llvm.lifetime.start(i64 4, i8* %b)<br class="">-  br label %bb<br class="">-<br class="">-bb:                                               ; preds = %if.end, %entry<br class="">-  %d = load i32, i32* %a, align 4<br class="">-  %c = bitcast i32* %a to i8*<br class="">-  call void @llvm.lifetime.end(i64 4, i8* %c)<br class="">-  ret void<br class="">-}<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits<br class=""></div></div></blockquote></div><br class=""></div></div></body></html>