[llvm] r264596 - [SimlifyCFG] Prevent passes from destroying canonical loop structure, especially for nested loops
Michael Kuperstein via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 10 13:31:51 PDT 2016
I'll take a look.
On Wed, Aug 10, 2016 at 1:29 PM, Hans Wennborg via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> 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/EqualPHIEdgeBlockMerg
>>>>> e.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
>>>>
>>>>
>>>
>>
>
> _______________________________________________
> 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/c289e6da/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/20160810/c289e6da/attachment-0001.gif>
More information about the llvm-commits
mailing list