[llvm] r264596 - [SimlifyCFG] Prevent passes from destroying canonical loop structure, especially for nested loops
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 9 19:42:16 PDT 2016
This commit seems to have caused https://llvm.org/bugs/show_bug.cgi?id=28190
Hyojin, can you please investigate?
I also wonder if anyone reviewed this patch, and if some motivating test
case should have been added.
Thanks,
Hans
On Mon, Mar 28, 2016 at 9:41 PM, Hyojin Sung via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> My apologies. I fixed the patch, checked it compiles, and submitted a new
> commit.
>
> Regards,
> Hyojin
>
> [image: Inactive hide details for Reid Kleckner ---03/28/2016 02:19:24
> PM---I reverted this because it didn't compile. You referenced a]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
>
> From: Reid Kleckner <rnk at google.com>
> To: Hyojin Sung/Watson/IBM at IBMUS
> Cc: llvm-commits <llvm-commits at lists.llvm.org>
> Date: 03/28/2016 02:19 PM
> Subject: Re: [llvm] r264596 - [SimlifyCFG] Prevent passes from destroying
> canonical loop structure, especially for nested loops
> ------------------------------
>
>
>
> I reverted this because it didn't compile. You referenced a field of
> SimplifyCFGOpt from a static helper function.
>
> On Mon, Mar 28, 2016 at 10:22 AM, Hyojin Sung via llvm-commits <
> *llvm-commits at lists.llvm.org* <llvm-commits at lists.llvm.org>> wrote:
>
> Author: hsung
> Date: Mon Mar 28 12:22:25 2016
> New Revision: 264596
>
> URL: *http://llvm.org/viewvc/llvm-project?rev=264596&view=rev*
> <http://llvm.org/viewvc/llvm-project?rev=264596&view=rev>
> Log:
> [SimlifyCFG] Prevent passes from destroying canonical loop structure,
> especially for nested loops
>
> When eliminating or merging almost empty basic blocks, the existence
> of non-trivial PHI nodes
> is currently used to recognize potential loops of which the block is
> the header and keep the block.
> However, the current algorithm fails if the loops' exit condition is
> evaluated only with volatile
> values hence no PHI nodes in the header. Especially when such a loop
> is an outer loop of a nested
> loop, the loop is collapsed into a single loop which prevent later
> optimizations from being
> applied (e.g., transforming nested loops into simplified forms and
> loop vectorization).
>
> The patch augments the existing PHI node-based check by adding a
> pre-test if the BB actually
> belongs to a set of loop headers and not eliminating it if yes.
>
>
> Modified:
> llvm/trunk/include/llvm/Transforms/Utils/Local.h
> llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
> llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp
> llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
> llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll
> llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll
> llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
> llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Mon Mar 28
> 12:22:25 2016
> @@ -21,6 +21,7 @@
> #include "llvm/IR/GetElementPtrTypeIterator.h"
> #include "llvm/IR/IRBuilder.h"
> #include "llvm/IR/Operator.h"
> +#include "llvm/ADT/SmallPtrSet.h"
>
> namespace llvm {
>
> @@ -124,13 +125,16 @@ bool TryToSimplifyUncondBranchFromEmptyB
> /// values, but instcombine orders them so it usually won't matter.
> bool EliminateDuplicatePHINodes(BasicBlock *BB);
>
> -/// This function is used to do simplification of a CFG. For
> example, it
> -/// adjusts branches to branches to eliminate the extra hop, it
> eliminates
> -/// unreachable basic blocks, and does other "peephole" optimization
> of the CFG.
> -/// It returns true if a modification was made, possibly deleting the
> basic
> -/// block that was pointed to.
> +/// This function is used to do simplification of a CFG. For
> +/// example, it adjusts branches to branches to eliminate the extra
> hop, it
> +/// eliminates unreachable basic blocks, and does other "peephole"
> optimization
> +/// of the CFG. It returns true if a modification was made, possibly
> deleting
> +/// the basic block that was pointed to. LoopHeaders is an optional
> input
> +/// parameter, providing the set of loop header that SimplifyCFG
> should not
> +/// eliminate.
> bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
> - unsigned BonusInstThreshold, AssumptionCache *AC =
> nullptr);
> + unsigned BonusInstThreshold, AssumptionCache *AC =
> nullptr,
> + SmallPtrSetImpl<BasicBlock *> *LoopHeaders =
> nullptr);
>
> /// This function is used to flatten a CFG. For example, it uses
> parallel-and
> /// and parallel-or mode to collapse if-conditions and merge
> if-regions with
>
> Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Mar 28
> 12:22:25 2016
> @@ -245,10 +245,13 @@ bool JumpThreading::runOnFunction(Functi
> // Can't thread an unconditional jump, but if the block is
> "almost
> // empty", we can replace uses of it with uses of the successor
> and make
> // this dead.
> + // We should not eliminate the loop header either, because
> eliminating
> + // a loop header might later prevent LoopSimplify from
> transforming nested
> + // loops into simplified form.
> if (BI && BI->isUnconditional() &&
> BB != &BB->getParent()->getEntryBlock() &&
> // If the terminator is the only non-phi instruction, try
> to nuke it.
> - BB->getFirstNonPHIOrDbg()->isTerminator()) {
> + BB->getFirstNonPHIOrDbg()->isTerminator() &&
> !LoopHeaders.count(BB)) {
> // Since TryToSimplifyUncondBranchFromEmptyBlock may delete
> the
> // block, we have to make sure it isn't in the LoopHeaders
> set. We
> // reinsert afterward if needed.
>
> Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp Mon Mar 28
> 12:22:25 2016
> @@ -28,6 +28,7 @@
> #include "llvm/Analysis/GlobalsModRef.h"
> #include "llvm/Analysis/AssumptionCache.h"
> #include "llvm/Analysis/TargetTransformInfo.h"
> +#include "llvm/Analysis/CFG.h"
> #include "llvm/IR/Attributes.h"
> #include "llvm/IR/CFG.h"
> #include "llvm/IR/Constants.h"
> @@ -130,13 +131,20 @@ static bool iterativelySimplifyCFG(Funct
> AssumptionCache *AC,
> unsigned BonusInstThreshold) {
> bool Changed = false;
> - bool LocalChange = true;
> + bool LocalChange = true;
> +
> + SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32>
> Edges;
> + FindFunctionBackedges(F, Edges);
> + SmallPtrSet<BasicBlock *, 16> LoopHeaders;
> + for (unsigned i = 0, e = Edges.size(); i != e; ++i)
> + LoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
> +
> while (LocalChange) {
> LocalChange = false;
>
> // Loop over all of the basic blocks and remove them if they are
> unneeded.
> for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
> - if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC)) {
> + if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC,
> &LoopHeaders)) {
> LocalChange = true;
> ++NumSimpl;
> }
>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Mar 28
> 12:22:25 2016
> @@ -135,6 +135,7 @@ class SimplifyCFGOpt {
> const DataLayout &DL;
> unsigned BonusInstThreshold;
> AssumptionCache *AC;
> + SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
> Value *isValueEqualityComparison(TerminatorInst *TI);
> BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
> std::vector<ValueEqualityComparisonCase>
> &Cases);
> @@ -157,8 +158,10 @@ class SimplifyCFGOpt {
>
> public:
> SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
> - unsigned BonusInstThreshold, AssumptionCache *AC)
> - : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold),
> AC(AC) {}
> + unsigned BonusInstThreshold, AssumptionCache *AC,
> + SmallPtrSetImpl<BasicBlock *> *LoopHeaders)
> + : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold),
> AC(AC),
> + LoopHeaders(LoopHeaders) {}
> bool run(BasicBlock *BB);
> };
> }
> @@ -3362,6 +3365,7 @@ bool SimplifyCFGOpt::SimplifySingleResum
>
> // The landingpad is now unreachable. Zap it.
> BB->eraseFromParent();
> + if (LoopHeaders) LoopHeaders->erase(BB);
> return true;
> }
>
> @@ -3480,6 +3484,7 @@ static bool removeEmptyCleanup(CleanupRe
>
> // The cleanup pad is now unreachable. Zap it.
> BB->eraseFromParent();
> + if (LoopHeaders) LoopHeaders->erase(BB);
> return true;
> }
>
> @@ -3560,9 +3565,11 @@ bool SimplifyCFGOpt::SimplifyReturn(Retu
> }
>
> // If we eliminated all predecessors of the block, delete the
> block now.
> - if (pred_empty(BB))
> + if (pred_empty(BB)) {
> // We know there are no successors, so just nuke the block.
> BB->eraseFromParent();
> + if (LoopHeaders) LoopHeaders->erase(BB);
> + }
>
> return true;
> }
> @@ -3719,6 +3726,7 @@ bool SimplifyCFGOpt::SimplifyUnreachable
> BB != &BB->getParent()->getEntryBlock()) {
> // We know there are no successors, so just nuke the block.
> BB->eraseFromParent();
> + if (LoopHeaders) LoopHeaders->erase(BB);
> return true;
> }
>
> @@ -5062,8 +5070,14 @@ bool SimplifyCFGOpt::SimplifyUncondBranc
> return true;
>
> // If the Terminator is the only non-phi instruction, simplify the
> block.
> + // if LoopHeader is provided, check if the block is a loop header
> + // (This is for early invocations before loop simplify and
> vectorization
> + // to keep canonical loop forms for nested loops.
> + // These blocks can be eliminated when the pass is invoked later
> + // in the back-end.)
> BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
> if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
> + (!LoopHeaders || (LoopHeaders && !LoopHeaders->count(BB))) &&
> TryToSimplifyUncondBranchFromEmptyBlock(BB))
> return true;
>
> @@ -5343,7 +5357,8 @@ bool SimplifyCFGOpt::run(BasicBlock *BB)
> /// of the CFG. It returns true if a modification was made.
> ///
> bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
> - unsigned BonusInstThreshold, AssumptionCache
> *AC) {
> + unsigned BonusInstThreshold, AssumptionCache
> *AC,
> + SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
> return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(),
> - BonusInstThreshold, AC).run(BB);
> + BonusInstThreshold, AC, LoopHeaders).run(BB);
> }
>
> Modified: llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.
> ll
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll
> (original)
> +++ llvm/trunk/test/Transforms/LoopUnswitch/2015-06-17-Metadata.ll Mon
> Mar 28 12:22:25 2016
> @@ -16,23 +16,23 @@ for.body:
> %cmp1 = icmp eq i32 %a, 12345
> br i1 %cmp1, label %if.then, label %if.else, !prof !0
> ; CHECK: %cmp1 = icmp eq i32 %a, 12345
> -; CHECK-NEXT: br i1 %cmp1, label %*if.then.us* <http://if.then.us/>,
> label %if.else, !prof !0
> +; CHECK-NEXT: br i1 %cmp1, label %*for.body.us* <http://for.body.us/>,
> label %for.body, !prof !0
> if.then: ; preds = %for.body
> -; CHECK: *if.then.us* <http://if.then.us/>:
> +; CHECK: *for.body.us* <http://for.body.us/>:
> ; CHECK: add nsw i32 %{{.*}}, 123
> ; CHECK: %*exitcond.us* <http://exitcond.us/> = icmp eq i32 %*inc.us*
> <http://inc.us/>, %b
> -; CHECK: br i1 %*exitcond.us* <http://exitcond.us/>, label
> %for.cond.cleanup, label %*if.then.us* <http://if.then.us/>
> +; CHECK: br i1 %*exitcond.us* <http://exitcond.us/>, label
> %for.cond.cleanup, label %*for.body.us* <http://for.body.us/>
> %add = add nsw i32 %add.i, 123
> br label %for.inc
>
> if.else: ; preds = %for.body
> %mul = mul nsw i32 %mul.i, %b
> br label %for.inc
> -; CHECK: if.else:
> +; CHECK: for.body:
> ; CHECK: %mul = mul nsw i32 %mul.i, %b
> ; CHECK: %inc = add nuw nsw i32 %inc.i, 1
> ; CHECK: %exitcond = icmp eq i32 %inc, %b
> -; CHECK: br i1 %exitcond, label %for.cond.cleanup, label %if.else
> +; CHECK: br i1 %exitcond, label %for.cond.cleanup, label %for.body
> for.inc: ; preds = %if.then,
> %if.else
> %mul.p = phi i32 [ %b, %if.then ], [ %mul, %if.else ]
> %add.p = phi i32 [ %add, %if.then ], [ %a, %if.else ]
>
> Modified: llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll (original)
> +++ llvm/trunk/test/Transforms/LoopUnswitch/infinite-loop.ll Mon Mar
> 28 12:22:25 2016
> @@ -16,10 +16,10 @@
> ; CHECK-NEXT: br i1 %a, label %entry.split, label %abort0.split
>
> ; CHECK: entry.split:
> -; CHECK-NEXT: br i1 %b, label %cond.end, label %abort1.split
> +; CHECK-NEXT: br i1 %b, label %for.body, label %abort1.split
>
> -; CHECK: cond.end:
> -; CHECK-NEXT: br label %cond.end
> +; CHECK: for.body:
> +; CHECK-NEXT: br label %for.body
>
> ; CHECK: abort0.split:
> ; CHECK-NEXT: call void @end0() [[NOR_NUW:#[0-9]+]]
>
> Modified: llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMe
> rge.ll
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
> (original)
> +++ llvm/trunk/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
> Mon Mar 28 12:22:25 2016
> @@ -1,6 +1,6 @@
> ; RUN: opt < %s -simplifycfg -S > %t
> ; RUN: not grep "^BB.tomerge" %t
> -; RUN: grep "^BB.nomerge" %t | count 2
> +; RUN: grep "^BB.nomerge" %t | count 4
>
> ; ModuleID = '<stdin>'
> declare i1 @foo()
> @@ -54,24 +54,24 @@ Exit: ; preds = %Succ
> ret void
> }
>
> -; This function can be merged
> +; This function can't be merged (for keeping canonical loop
> structures)
> define void @c() {
> entry:
> - br label %BB.tomerge
> + br label %BB.nomerge
>
> -BB.tomerge: ; preds = %Common, %entry
> +BB.nomerge: ; preds = %Common, %entry
> br label %Succ
>
> Succ: ; preds = %Common, %BB.tomerge, %Pre-Exit
> ; This phi has identical values for Common and (through BB)
> Common,
> ; blocks can't be merged
> - %b = phi i32 [ 1, %BB.tomerge ], [ 1, %Common ], [ 2,
> %Pre-Exit ]
> + %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2,
> %Pre-Exit ]
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Common, label %Pre-Exit
>
> Common: ; preds = %Succ
> %cond = call i1 @foo( ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Succ
> + br i1 %cond, label %BB.nomerge, label %Succ
>
> Pre-Exit: ; preds = %Succ
> ; This adds a backedge, so the %b phi node gets a third
> branch and is
> @@ -83,25 +83,25 @@ Exit: ; preds = %Pre-Exit
> ret void
> }
>
> -; This function can be merged
> +; This function can't be merged (for keeping canonical loop
> structures)
> define void @d() {
> entry:
> - br label %BB.tomerge
> + br label %BB.nomerge
>
> -BB.tomerge: ; preds = %Common, %entry
> +BB.nomerge: ; preds = %Common, %entry
> ; This phi has a matching value (0) with below phi (0), so
> blocks
> ; can be merged.
> %a = phi i32 [ 1, %entry ], [ 0, %Common ] ;
> <i32> [#uses=1]
> br label %Succ
>
> Succ: ; preds = %Common, %BB.tomerge
> - %b = phi i32 [ %a, %BB.tomerge ], [ 0, %Common ]
> ; <i32> [#uses=0]
> + %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ]
> ; <i32> [#uses=0]
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Common, label %Exit
>
> Common: ; preds = %Succ
> %cond = call i1 @foo( ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Succ
> + br i1 %cond, label %BB.nomerge, label %Succ
>
> Exit: ; preds = %Succ
> ret void
> @@ -110,21 +110,21 @@ Exit: ; preds = %Succ
> ; This function can be merged
> define void @e() {
> entry:
> - br label %BB.tomerge
> + br label %Succ
>
> -BB.tomerge: ; preds = %Use, %entry
> +Succ: ; preds = %Use, %entry
> ; This phi is used somewhere else than Succ, but this should
> not prevent
> ; merging this block
> %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32>
> [#uses=1]
> - br label %Succ
> + br label %BB.tomerge
>
> -Succ: ; preds = %BB.tomerge
> +BB.tomerge: ; preds = %BB.tomerge
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Use, label %Exit
>
> Use: ; preds = %Succ
> %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Exit
> + br i1 %cond, label %Succ, label %Exit
>
> Exit: ; preds = %Use, %Succ
> ret void
>
> Modified: llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerg
> e.ll
> URL:
> *http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff*
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll?rev=264596&r1=264595&r2=264596&view=diff>
> ============================================================
> ==================
> --- llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
> (original)
> +++ llvm/trunk/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
> Mon Mar 28 12:22:25 2016
> @@ -5,7 +5,7 @@
> ; RUN: not grep X: %t
> ; RUN: not grep 'switch i32[^U]+%U' %t
> ; RUN: not grep "^BB.tomerge" %t
> -; RUN: grep "^BB.nomerge" %t | count 2
> +; RUN: grep "^BB.nomerge" %t | count 4
> ;
>
> ; ModuleID = '<stdin>'
> @@ -179,24 +179,24 @@ Exit: ; preds = %Succ
> ret void
> }
>
> -; This function can be merged
> +; This function can't be merged (for keeping canonical loop
> structures)
> define void @c() {
> entry:
> - br label %BB.tomerge
> + br label %BB.nomerge
>
> -BB.tomerge: ; preds = %Common, %entry
> +BB.nomerge: ; preds = %Common, %entry
> br label %Succ
>
> Succ: ; preds = %Common, %BB.tomerge, %Pre-Exit
> ; This phi has identical values for Common and (through BB)
> Common,
> ; blocks can't be merged
> - %b = phi i32 [ 1, %BB.tomerge ], [ 1, %Common ], [ 2,
> %Pre-Exit ]
> + %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2,
> %Pre-Exit ]
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Common, label %Pre-Exit
>
> Common: ; preds = %Succ
> %cond = call i1 @foo( ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Succ
> + br i1 %cond, label %BB.nomerge, label %Succ
>
> Pre-Exit: ; preds = %Succ
> ; This adds a backedge, so the %b phi node gets a third
> branch and is
> @@ -208,25 +208,25 @@ Exit: ; preds = %Pre-Exit
> ret void
> }
>
> -; This function can be merged
> +; This function can't be merged (for keeping canonical loop
> structures)
> define void @d() {
> entry:
> - br label %BB.tomerge
> + br label %BB.nomerge
>
> -BB.tomerge: ; preds = %Common, %entry
> +BB.nomerge: ; preds = %Common, %entry
> ; This phi has a matching value (0) with below phi (0), so
> blocks
> ; can be merged.
> %a = phi i32 [ 1, %entry ], [ 0, %Common ] ;
> <i32> [#uses=1]
> br label %Succ
>
> Succ: ; preds = %Common, %BB.tomerge
> - %b = phi i32 [ %a, %BB.tomerge ], [ 0, %Common ]
> ; <i32> [#uses=0]
> + %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ]
> ; <i32> [#uses=0]
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Common, label %Exit
>
> Common: ; preds = %Succ
> %cond = call i1 @foo( ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Succ
> + br i1 %cond, label %BB.nomerge, label %Succ
>
> Exit: ; preds = %Succ
> ret void
> @@ -235,21 +235,21 @@ Exit: ; preds = %Succ
> ; This function can be merged
> define void @e() {
> entry:
> - br label %BB.tomerge
> + br label %Succ
>
> -BB.tomerge: ; preds = %Use, %entry
> +Succ: ; preds = %Use, %entry
> ; This phi is used somewhere else than Succ, but this should
> not prevent
> ; merging this block
> %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32>
> [#uses=1]
> - br label %Succ
> + br label %BB.tomerge
>
> -Succ: ; preds = %BB.tomerge
> +BB.tomerge: ; preds = %Succ
> %conde = call i1 @foo( ) ; <i1> [#uses=1]
> br i1 %conde, label %Use, label %Exit
>
> Use: ; preds = %Succ
> %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
> - br i1 %cond, label %BB.tomerge, label %Exit
> + br i1 %cond, label %Succ, label %Exit
>
> Exit: ; preds = %Use, %Succ
> ret void
>
>
> _______________________________________________
> llvm-commits mailing list
> *llvm-commits at lists.llvm.org* <llvm-commits at lists.llvm.org>
> *http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits*
> <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>
>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160809/8af8d1ca/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: graycol.gif
Type: image/gif
Size: 105 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160809/8af8d1ca/attachment.gif>
More information about the llvm-commits
mailing list