[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
Wed Aug 10 13:29:22 PDT 2016
Actually, this commit also seems to have caused
https://llvm.org/bugs/show_bug.cgi?id=28330 which looks like a separate
issue.
On Wed, Aug 10, 2016 at 9:40 AM, Hans Wennborg <hans at chromium.org> wrote:
> Great, thanks for catching that.
>
> On Tue, Aug 9, 2016 at 11:13 PM, Michael Kuperstein <
> michael.kuperstein at gmail.com> wrote:
>
>> Looks like a dup of PR28541, there's already patch that fixes it under
>> review (D22952).
>>
>> Michael
>>
>> On 9 August 2016 at 19:42, Hans Wennborg via llvm-commits <
>> llvm-commits at lists.llvm.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-PHIBlockMe
>>>> rge.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()->get
>>>> Iterator();
>>>> 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/Loo
>>>> pUnswitch/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/Sim
>>>> plifyCFG/2008-05-16-PHIBlockMerge.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/Sim
>>>> plifyCFG/EqualPHIEdgeBlockMerge.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
>>>>
>>>>
>>>
>>> _______________________________________________
>>> 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/20160810/d1f25974/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/20160810/d1f25974/attachment.gif>
More information about the llvm-commits
mailing list