<div dir="ltr">This commit seems to have caused <a href="https://llvm.org/bugs/show_bug.cgi?id=28190" target="_blank">https://llvm.org/bugs/<wbr>show_bug.cgi?id=28190</a><div><br></div><div>Hyojin, can you please investigate?</div><div><br></div><div>I also wonder if anyone reviewed this patch, and if some motivating test case should have been added.</div><div><br></div><div>Thanks,</div><div>Hans</div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 28, 2016 at 9:41 PM, Hyojin Sung via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p>My apologies. I fixed the patch, checked it compiles, and submitted a new commit. <br><br>Regards,<br>Hyojin<br><br><img width="16" height="16" src="cid:1__=8FBBF516DF84FC9E8f9e8a93df938690918c8FB@" border="0" alt="Inactive hide details for Reid Kleckner ---03/28/2016 02:19:24 PM---I reverted this because it didn't compile. You referenced a"><font color="#424282">Reid Kleckner ---03/28/2016 02:19:24 PM---I reverted this because it didn't compile. You referenced a field of SimplifyCFGOpt from a static he</font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">Hyojin Sung/Watson/IBM@IBMUS</font><br><font size="2" color="#5F5F5F">Cc:        </font><font size="2">llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">03/28/2016 02:19 PM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">Re: [llvm] r264596 - [SimlifyCFG] Prevent passes from destroying canonical loop structure, especially for nested loops</font><br></p><hr width="100%" size="2" align="left" noshade style="color:rgb(128,145,165)"><div><div class="m_5298121373315100442gmail-h5"><br><br><br><font size="4">I reverted this because it didn't compile. You referenced a field of SimplifyCFGOpt from a static helper function.</font><br><br><font size="4">On Mon, Mar 28, 2016 at 10:22 AM, Hyojin Sung via llvm-commits <</font><a href="mailto:llvm-commits@lists.llvm.org" target="_blank"><u><font size="4" color="#0000FF">llvm-commits@lists.llvm.org</font></u></a><font size="4">> wrote:</font><ul><font size="4">Author: hsung<br>Date: Mon Mar 28 12:22:25 2016<br>New Revision: 264596<br><br>URL: </font><a href="http://llvm.org/viewvc/llvm-project?rev=264596&view=rev" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=264596&view=rev</font></u></a><font size="4"><br>Log:<br>[SimlifyCFG] Prevent passes from destroying canonical loop structure, especially for nested loops<br><br>When eliminating or merging almost empty basic blocks, the existence of non-trivial PHI nodes<br>is currently used to recognize potential loops of which the block is the header and keep the block.<br>However, the current algorithm fails if the loops' exit condition is evaluated only with volatile<br>values hence no PHI nodes in the header. Especially when such a loop is an outer loop of a nested<br>loop, the loop is collapsed into a single loop which prevent later optimizations from being<br>applied (e.g., transforming nested loops into simplified forms and loop vectorization).<br><br>The patch augments the existing PHI node-based check by adding a pre-test if the BB actually<br>belongs to a set of loop headers and not eliminating it if yes.<br><br><br>Modified:<br>    llvm/trunk/include/llvm/Transf<wbr>orms/Utils/Local.h<br>    llvm/trunk/lib/Transforms/Scal<wbr>ar/JumpThreading.cpp<br>    llvm/trunk/lib/Transforms/Scal<wbr>ar/SimplifyCFGPass.cpp<br>    llvm/trunk/lib/Transforms/Util<wbr>s/SimplifyCFG.cpp<br>    llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/2015-06-17-Metadata.<wbr>ll<br>    llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/infinite-loop.ll<br>    llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/2008-05-16-PHIBlockMe<wbr>rge.ll<br>    llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/EqualPHIEdgeBlockMerg<wbr>e.ll<br><br>Modified: llvm/trunk/include/llvm/Transf<wbr>orms/Utils/Local.h<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Transforms/Utils/Local.h?rev=<wbr>264596&r1=264595&r2=264596&<wbr>view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/include/llvm/Transf<wbr>orms/Utils/Local.h (original)<br>+++ llvm/trunk/include/llvm/Transf<wbr>orms/Utils/Local.h Mon Mar 28 12:22:25 2016<br>@@ -21,6 +21,7 @@<br> #include "llvm/IR/GetElementPtrTypeIter<wbr>ator.h"<br> #include "llvm/IR/IRBuilder.h"<br> #include "llvm/IR/Operator.h"<br>+#include "llvm/ADT/SmallPtrSet.h"<br><br> namespace llvm {<br><br>@@ -124,13 +125,16 @@ bool TryToSimplifyUncondBranchFromE<wbr>mptyB<br> /// values, but instcombine orders them so it usually won't matter.<br> bool EliminateDuplicatePHINodes(Bas<wbr>icBlock *BB);<br><br>-/// This function is used to do simplification of a CFG.  For example, it<br>-/// adjusts branches to branches to eliminate the extra hop, it eliminates<br>-/// unreachable basic blocks, and does other "peephole" optimization of the CFG.<br>-/// It returns true if a modification was made, possibly deleting the basic<br>-/// block that was pointed to.<br>+/// This function is used to do simplification of a CFG.  For<br>+/// example, it adjusts branches to branches to eliminate the extra hop, it<br>+/// eliminates unreachable basic blocks, and does other "peephole" optimization<br>+/// of the CFG.  It returns true if a modification was made, possibly deleting<br>+/// the basic block that was pointed to. LoopHeaders is an optional input<br>+/// parameter, providing the set of loop header that SimplifyCFG should not<br>+/// eliminate.<br> bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,<br>-                 unsigned BonusInstThreshold, AssumptionCache *AC = nullptr);<br>+                 unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,<br>+                 SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);<br><br> /// This function is used to flatten a CFG. For example, it uses parallel-and<br> /// and parallel-or mode to collapse if-conditions and merge if-regions with<br><br>Modified: llvm/trunk/lib/Transforms/Scal<wbr>ar/JumpThreading.cpp<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Transform<wbr>s/Scalar/JumpThreading.cpp?<wbr>rev=264596&r1=264595&r2=<wbr>264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/lib/Transforms/Scal<wbr>ar/JumpThreading.cpp (original)<br>+++ llvm/trunk/lib/Transforms/Scal<wbr>ar/JumpThreading.cpp Mon Mar 28 12:22:25 2016<br>@@ -245,10 +245,13 @@ bool JumpThreading::runOnFunction(F<wbr>uncti<br>       // Can't thread an unconditional jump, but if the block is "almost<br>       // empty", we can replace uses of it with uses of the successor and make<br>       // this dead.<br>+      // We should not eliminate the loop header either, because eliminating<br>+      // a loop header might later prevent LoopSimplify from transforming nested<br>+      // loops into simplified form.<br>       if (BI && BI->isUnconditional() &&<br>           BB != &BB->getParent()->getEntryBloc<wbr>k() &&<br>           // If the terminator is the only non-phi instruction, try to nuke it.<br>-          BB->getFirstNonPHIOrDbg()->isT<wbr>erminator()) {<br>+          BB->getFirstNonPHIOrDbg()->isT<wbr>erminator() && !LoopHeaders.count(BB)) {<br>         // Since TryToSimplifyUncondBranchFromE<wbr>mptyBlock may delete the<br>         // block, we have to make sure it isn't in the LoopHeaders set.  We<br>         // reinsert afterward if needed.<br><br>Modified: llvm/trunk/lib/Transforms/Scal<wbr>ar/SimplifyCFGPass.cpp<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Transform<wbr>s/Scalar/SimplifyCFGPass.cpp?<wbr>rev=264596&r1=264595&r2=<wbr>264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/lib/Transforms/Scal<wbr>ar/SimplifyCFGPass.cpp (original)<br>+++ llvm/trunk/lib/Transforms/Scal<wbr>ar/SimplifyCFGPass.cpp Mon Mar 28 12:22:25 2016<br>@@ -28,6 +28,7 @@<br> #include "llvm/Analysis/GlobalsModRef.h<wbr>"<br> #include "llvm/Analysis/AssumptionCache<wbr>.h"<br> #include "llvm/Analysis/TargetTransform<wbr>Info.h"<br>+#include "llvm/Analysis/CFG.h"<br> #include "llvm/IR/Attributes.h"<br> #include "llvm/IR/CFG.h"<br> #include "llvm/IR/Constants.h"<br>@@ -130,13 +131,20 @@ static bool iterativelySimplifyCFG(Funct<br>                                    AssumptionCache *AC,<br>                                    unsigned BonusInstThreshold) {<br>   bool Changed = false;<br>-  bool LocalChange = true;<br>+  bool LocalChange = true;<br>+<br>+  SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32> Edges;<br>+  FindFunctionBackedges(F, Edges);<br>+  SmallPtrSet<BasicBlock *, 16> LoopHeaders;<br>+  for (unsigned i = 0, e = Edges.size(); i != e; ++i)<br>+    LoopHeaders.insert(const_cast<<wbr>BasicBlock *>(Edges[i].second));<br>+<br>   while (LocalChange) {<br>     LocalChange = false;<br><br>     // Loop over all of the basic blocks and remove them if they are unneeded.<br>     for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {<br>-      if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC)) {<br>+      if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders)) {<br>         LocalChange = true;<br>         ++NumSimpl;<br>       }<br><br>Modified: llvm/trunk/lib/Transforms/Util<wbr>s/SimplifyCFG.cpp<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Transform<wbr>s/Utils/SimplifyCFG.cpp?rev=<wbr>264596&r1=264595&r2=264596&<wbr>view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/lib/Transforms/Util<wbr>s/SimplifyCFG.cpp (original)<br>+++ llvm/trunk/lib/Transforms/Util<wbr>s/SimplifyCFG.cpp Mon Mar 28 12:22:25 2016<br>@@ -135,6 +135,7 @@ class SimplifyCFGOpt {<br>   const DataLayout &DL;<br>   unsigned BonusInstThreshold;<br>   AssumptionCache *AC;<br>+  SmallPtrSetImpl<BasicBlock *> *LoopHeaders;<br>   Value *isValueEqualityComparison(Ter<wbr>minatorInst *TI);<br>   BasicBlock *GetValueEqualityComparisonCas<wbr>es(TerminatorInst *TI,<br>                                std::vector<ValueEqualityCompa<wbr>risonCase> &Cases);<br>@@ -157,8 +158,10 @@ class SimplifyCFGOpt {<br><br> public:<br>   SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,<br>-                 unsigned BonusInstThreshold, AssumptionCache *AC)<br>-      : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstTh<wbr>reshold), AC(AC) {}<br>+                 unsigned BonusInstThreshold, AssumptionCache *AC,<br>+                 SmallPtrSetImpl<BasicBlock *> *LoopHeaders)<br>+      : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstTh<wbr>reshold), AC(AC),<br>+        LoopHeaders(LoopHeaders) {}<br>   bool run(BasicBlock *BB);<br> };<br> }<br>@@ -3362,6 +3365,7 @@ bool SimplifyCFGOpt::SimplifySingle<wbr>Resum<br><br>   // The landingpad is now unreachable.  Zap it.<br>   BB->eraseFromParent();<br>+  if (LoopHeaders) LoopHeaders->erase(BB);<br>   return true;<br> }<br><br>@@ -3480,6 +3484,7 @@ static bool removeEmptyCleanup(CleanupRe<br><br>   // The cleanup pad is now unreachable.  Zap it.<br>   BB->eraseFromParent();<br>+  if (LoopHeaders) LoopHeaders->erase(BB);<br>   return true;<br> }<br><br>@@ -3560,9 +3565,11 @@ bool SimplifyCFGOpt::SimplifyReturn<wbr>(Retu<br>     }<br><br>     // If we eliminated all predecessors of the block, delete the block now.<br>-    if (pred_empty(BB))<br>+    if (pred_empty(BB)) {<br>       // We know there are no successors, so just nuke the block.<br>       BB->eraseFromParent();<br>+      if (LoopHeaders) LoopHeaders->erase(BB);<br>+    }<br><br>     return true;<br>   }<br>@@ -3719,6 +3726,7 @@ bool SimplifyCFGOpt::SimplifyUnreac<wbr>hable<br>       BB != &BB->getParent()->getEntryBloc<wbr>k()) {<br>     // We know there are no successors, so just nuke the block.<br>     BB->eraseFromParent();<br>+    if (LoopHeaders) LoopHeaders->erase(BB);<br>     return true;<br>   }<br><br>@@ -5062,8 +5070,14 @@ bool SimplifyCFGOpt::SimplifyUncond<wbr>Branc<br>     return true;<br><br>   // If the Terminator is the only non-phi instruction, simplify the block.<br>+  // if LoopHeader is provided, check if the block is a loop header<br>+  // (This is for early invocations before loop simplify and vectorization<br>+  // to keep canonical loop forms for nested loops.<br>+  // These blocks can be eliminated when the pass is invoked later<br>+  // in the back-end.)<br>   BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->get<wbr>Iterator();<br>   if (I->isTerminator() && BB != &BB->getParent()->getEntryBloc<wbr>k() &&<br>+      (!LoopHeaders || (LoopHeaders && !LoopHeaders->count(BB))) &&<br>       TryToSimplifyUncondBranchFrom<wbr>EmptyBlock(BB))<br>     return true;<br><br>@@ -5343,7 +5357,8 @@ bool SimplifyCFGOpt::run(BasicBlock *BB)<br> /// of the CFG.  It returns true if a modification was made.<br> ///<br> bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,<br>-                       unsigned BonusInstThreshold, AssumptionCache *AC) {<br>+                       unsigned BonusInstThreshold, AssumptionCache *AC,<br>+                       SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {<br>   return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout<wbr>(),<br>-                        BonusInstThreshold, AC).run(BB);<br>+                        BonusInstThreshold, AC, LoopHeaders).run(BB);<br> }<br><br>Modified: llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/2015-06-17-Metadata.<wbr>ll<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/Transfor<wbr>ms/LoopUnswitch/2015-06-17-<wbr>Metadata.ll?rev=264596&r1=<wbr>264595&r2=264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/2015-06-17-Metadata.<wbr>ll (original)<br>+++ llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/2015-06-17-Metadata.<wbr>ll Mon Mar 28 12:22:25 2016<br>@@ -16,23 +16,23 @@ for.body:<br>   %cmp1 = icmp eq i32 %a, 12345<br>   br i1 %cmp1, label %if.then, label %if.else, !prof !0<br> ; CHECK: %cmp1 = icmp eq i32 %a, 12345<br>-; CHECK-NEXT: br i1 %cmp1, label %</font><a href="http://if.then.us/" target="_blank"><u><font size="4" color="#0000FF">if.then.us</font></u></a><font size="4">, label %if.else, !prof !0<br>+; CHECK-NEXT: br i1 %cmp1, label %</font><a href="http://for.body.us/" target="_blank"><u><font size="4" color="#0000FF">for.body.us</font></u></a><font size="4">, label %for.body, !prof !0<br> if.then:                                          ; preds = %for.body<br>-; CHECK: </font><a href="http://if.then.us/" target="_blank"><u><font size="4" color="#0000FF">if.then.us</font></u></a><font size="4">:<br>+; CHECK: </font><a href="http://for.body.us/" target="_blank"><u><font size="4" color="#0000FF">for.body.us</font></u></a><font size="4">:<br> ; CHECK: add nsw i32 %{{.*}}, 123<br> ; CHECK: %</font><a href="http://exitcond.us/" target="_blank"><u><font size="4" color="#0000FF">exitcond.us</font></u></a><font size="4"> = icmp eq i32 %</font><a href="http://inc.us/" target="_blank"><u><font size="4" color="#0000FF">inc.us</font></u></a><font size="4">, %b<br>-; CHECK: br i1 %</font><a href="http://exitcond.us/" target="_blank"><u><font size="4" color="#0000FF">exitcond.us</font></u></a><font size="4">, label %for.cond.cleanup, label %</font><a href="http://if.then.us/" target="_blank"><u><font size="4" color="#0000FF">if.then.us</font></u></a><font size="4"><br>+; CHECK: br i1 %</font><a href="http://exitcond.us/" target="_blank"><u><font size="4" color="#0000FF">exitcond.us</font></u></a><font size="4">, label %for.cond.cleanup, label %</font><a href="http://for.body.us/" target="_blank"><u><font size="4" color="#0000FF">for.body.us</font></u></a><font size="4"><br>   %add = add nsw i32 %add.i, 123<br>   br label %for.inc<br><br> if.else:                                          ; preds = %for.body<br>   %mul = mul nsw i32 %mul.i, %b<br>   br label %for.inc<br>-; CHECK: if.else:<br>+; CHECK: for.body:<br> ; CHECK: %mul = mul nsw i32 %mul.i, %b<br> ; CHECK: %inc = add nuw nsw i32 %inc.i, 1<br> ; CHECK: %exitcond = icmp eq i32 %inc, %b<br>-; CHECK: br i1 %exitcond, label %for.cond.cleanup, label %if.else<br>+; CHECK: br i1 %exitcond, label %for.cond.cleanup, label %for.body<br> for.inc:                                          ; preds = %if.then, %if.else<br>   %mul.p = phi i32 [ %b, %if.then ], [ %mul, %if.else ]<br>   %add.p = phi i32 [ %add, %if.then ], [ %a, %if.else ]<br><br>Modified: llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/infinite-loop.ll<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/Transfor<wbr>ms/LoopUnswitch/infinite-loop.<wbr>ll?rev=264596&r1=264595&r2=<wbr>264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/infinite-loop.ll (original)<br>+++ llvm/trunk/test/Transforms/Loo<wbr>pUnswitch/infinite-loop.ll Mon Mar 28 12:22:25 2016<br>@@ -16,10 +16,10 @@<br> ; CHECK-NEXT: br i1 %a, label %entry.split, label %abort0.split<br><br> ; CHECK: entry.split:<br>-; CHECK-NEXT: br i1 %b, label %cond.end, label %abort1.split<br>+; CHECK-NEXT: br i1 %b, label %for.body, label %abort1.split<br><br>-; CHECK: cond.end:<br>-; CHECK-NEXT: br label %cond.end<br>+; CHECK: for.body:<br>+; CHECK-NEXT: br label %for.body<br><br> ; CHECK: abort0.split:<br> ; CHECK-NEXT: call void @end0() [[NOR_NUW:#[0-9]+]]<br><br>Modified: llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/2008-05-16-PHIBlockMe<wbr>rge.ll<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/Transfor<wbr>ms/SimplifyCFG/2008-05-16-<wbr>PHIBlockMerge.ll?rev=264596&<wbr>r1=264595&r2=264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/2008-05-16-PHIBlockMe<wbr>rge.ll (original)<br>+++ llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/2008-05-16-PHIBlockMe<wbr>rge.ll Mon Mar 28 12:22:25 2016<br>@@ -1,6 +1,6 @@<br> ; RUN: opt < %s -simplifycfg -S > %t<br> ; RUN: not grep "^BB.tomerge" %t<br>-; RUN: grep "^BB.nomerge" %t | count 2<br>+; RUN: grep "^BB.nomerge" %t | count 4<br><br> ; ModuleID = '<stdin>'<br> declare i1 @foo()<br>@@ -54,24 +54,24 @@ Exit:               ; preds = %Succ<br>        ret void<br> }<br><br>-; This function can be merged<br>+; This function can't be merged (for keeping canonical loop structures)<br> define void @c() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %BB.nomerge<br><br>-BB.tomerge:            ; preds = %Common, %entry<br>+BB.nomerge:            ; preds = %Common, %entry<br>        br label %Succ<br><br> Succ:          ; preds = %Common, %BB.tomerge, %Pre-Exit<br>         ; This phi has identical values for Common and (through BB) Common,<br>         ; blocks can't be merged<br>-       %b = phi i32 [ 1, %BB.tomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]<br>+       %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Common, label %Pre-Exit<br><br> Common:                ; preds = %Succ<br>        %cond = call i1 @foo( )         ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Succ<br>+       br i1 %cond, label %BB.nomerge, label %Succ<br><br> Pre-Exit:       ; preds = %Succ<br>         ; This adds a backedge, so the %b phi node gets a third branch and is<br>@@ -83,25 +83,25 @@ Exit:               ; preds = %Pre-Exit<br>        ret void<br> }<br><br>-; This function can be merged<br>+; This function can't be merged (for keeping canonical loop structures)<br> define void @d() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %BB.nomerge<br><br>-BB.tomerge:            ; preds = %Common, %entry<br>+BB.nomerge:            ; preds = %Common, %entry<br>         ; This phi has a matching value (0) with below phi (0), so blocks<br>         ; can be merged.<br>        %a = phi i32 [ 1, %entry ], [ 0, %Common ]              ; <i32> [#uses=1]<br>        br label %Succ<br><br> Succ:          ; preds = %Common, %BB.tomerge<br>-       %b = phi i32 [ %a, %BB.tomerge ], [ 0, %Common ]                ; <i32> [#uses=0]<br>+       %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ]                ; <i32> [#uses=0]<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Common, label %Exit<br><br> Common:                ; preds = %Succ<br>        %cond = call i1 @foo( )         ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Succ<br>+       br i1 %cond, label %BB.nomerge, label %Succ<br><br> Exit:          ; preds = %Succ<br>        ret void<br>@@ -110,21 +110,21 @@ Exit:             ; preds = %Succ<br> ; This function can be merged<br> define void @e() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %Succ<br><br>-BB.tomerge:            ; preds = %Use, %entry<br>+Succ:          ; preds = %Use, %entry<br>         ; This phi is used somewhere else than Succ, but this should not prevent<br>         ; merging this block<br>        %a = phi i32 [ 1, %entry ], [ 0, %Use ]         ; <i32> [#uses=1]<br>-       br label %Succ<br>+       br label %BB.tomerge<br><br>-Succ:          ; preds = %BB.tomerge<br>+BB.tomerge:            ; preds = %BB.tomerge<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Use, label %Exit<br><br> Use:           ; preds = %Succ<br>        %cond = call i1 @bar( i32 %a )          ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Exit<br>+       br i1 %cond, label %Succ, label %Exit<br><br> Exit:          ; preds = %Use, %Succ<br>        ret void<br><br>Modified: llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/EqualPHIEdgeBlockMerg<wbr>e.ll<br>URL: </font><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff" target="_blank"><u><font size="4" color="#0000FF">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/Transfor<wbr>ms/SimplifyCFG/EqualPHIEdgeBlo<wbr>ckMerge.ll?rev=264596&r1=<wbr>264595&r2=264596&view=diff</font></u></a><font size="4"><br>==============================<wbr>==============================<wbr>==================<br>--- llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/EqualPHIEdgeBlockMerg<wbr>e.ll (original)<br>+++ llvm/trunk/test/Transforms/Sim<wbr>plifyCFG/EqualPHIEdgeBlockMerg<wbr>e.ll Mon Mar 28 12:22:25 2016<br>@@ -5,7 +5,7 @@<br> ; RUN: not grep X: %t<br> ; RUN: not grep 'switch i32[^U]+%U' %t<br> ; RUN: not grep "^BB.tomerge" %t<br>-; RUN: grep "^BB.nomerge" %t | count 2<br>+; RUN: grep "^BB.nomerge" %t | count 4<br> ;<br><br> ; ModuleID = '<stdin>'<br>@@ -179,24 +179,24 @@ Exit:             ; preds = %Succ<br>        ret void<br> }<br><br>-; This function can be merged<br>+; This function can't be merged (for keeping canonical loop structures)<br> define void @c() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %BB.nomerge<br><br>-BB.tomerge:            ; preds = %Common, %entry<br>+BB.nomerge:            ; preds = %Common, %entry<br>        br label %Succ<br><br> Succ:          ; preds = %Common, %BB.tomerge, %Pre-Exit<br>         ; This phi has identical values for Common and (through BB) Common,<br>         ; blocks can't be merged<br>-       %b = phi i32 [ 1, %BB.tomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]<br>+       %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Common, label %Pre-Exit<br><br> Common:                ; preds = %Succ<br>        %cond = call i1 @foo( )         ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Succ<br>+       br i1 %cond, label %BB.nomerge, label %Succ<br><br> Pre-Exit:       ; preds = %Succ<br>         ; This adds a backedge, so the %b phi node gets a third branch and is<br>@@ -208,25 +208,25 @@ Exit:             ; preds = %Pre-Exit<br>        ret void<br> }<br><br>-; This function can be merged<br>+; This function can't be merged (for keeping canonical loop structures)<br> define void @d() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %BB.nomerge<br><br>-BB.tomerge:            ; preds = %Common, %entry<br>+BB.nomerge:            ; preds = %Common, %entry<br>         ; This phi has a matching value (0) with below phi (0), so blocks<br>         ; can be merged.<br>        %a = phi i32 [ 1, %entry ], [ 0, %Common ]              ; <i32> [#uses=1]<br>        br label %Succ<br><br> Succ:          ; preds = %Common, %BB.tomerge<br>-       %b = phi i32 [ %a, %BB.tomerge ], [ 0, %Common ]                ; <i32> [#uses=0]<br>+       %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ]                ; <i32> [#uses=0]<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Common, label %Exit<br><br> Common:                ; preds = %Succ<br>        %cond = call i1 @foo( )         ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Succ<br>+       br i1 %cond, label %BB.nomerge, label %Succ<br><br> Exit:          ; preds = %Succ<br>        ret void<br>@@ -235,21 +235,21 @@ Exit:             ; preds = %Succ<br> ; This function can be merged<br> define void @e() {<br> entry:<br>-       br label %BB.tomerge<br>+       br label %Succ<br><br>-BB.tomerge:            ; preds = %Use, %entry<br>+Succ:          ; preds = %Use, %entry<br>         ; This phi is used somewhere else than Succ, but this should not prevent<br>         ; merging this block<br>        %a = phi i32 [ 1, %entry ], [ 0, %Use ]         ; <i32> [#uses=1]<br>-       br label %Succ<br>+       br label %BB.tomerge<br><br>-Succ:          ; preds = %BB.tomerge<br>+BB.tomerge:            ; preds = %Succ<br>        %conde = call i1 @foo( )                ; <i1> [#uses=1]<br>        br i1 %conde, label %Use, label %Exit<br><br> Use:           ; preds = %Succ<br>        %cond = call i1 @bar( i32 %a )          ; <i1> [#uses=1]<br>-       br i1 %cond, label %BB.tomerge, label %Exit<br>+       br i1 %cond, label %Succ, label %Exit<br><br> Exit:          ; preds = %Use, %Succ<br>        ret void<br><br><br>______________________________<wbr>_________________<br>llvm-commits mailing list</font><u><font size="4" color="#0000FF"><br></font></u><a href="mailto:llvm-commits@lists.llvm.org" target="_blank"><u><font size="4" color="#0000FF">llvm-commits@lists.llvm.org</font></u></a><u><font size="4" color="#0000FF"><br></font></u><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank"><u><font size="4" color="#0000FF">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</font></u></a></ul><br><br><br>
</div></div><p></p></div>
<br>______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div></div></div>