[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:44:41 PDT 2016
I now see it was reviewed in http://reviews.llvm.org/D13087
On Tue, Aug 9, 2016 at 7:42 PM, Hans Wennborg <hans at chromium.org> wrote:
> This commit seems to have caused https://llvm.org/bugs/s
> how_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/3adc3e7a/attachment-0001.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/3adc3e7a/attachment-0001.gif>
More information about the llvm-commits
mailing list