[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
Tue Aug 9 23:13:25 PDT 2016


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-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
>>
>>
>
> _______________________________________________
> 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/bfa8dafb/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/bfa8dafb/attachment.gif>


More information about the llvm-commits mailing list