[llvm] r333493 - [PM/LoopUnswitch] When using the new SimpleLoopUnswitch pass, schedule

Mikael Holmén via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 13 01:54:39 PDT 2018


Hi again,

With

  opt -S -o - bbi-14637_orig.ll -simple-loop-unswitch -verify -loop-deletion

(bbi-14637_orig.ll has a few small differences compared to bbi-14637.ll)
we instead get the failed assertion

opt: ../include/llvm/Analysis/LoopInfoImpl.h:251: void 
llvm::LoopBase<llvm::BasicBlock, llvm::Loop>::verifyLoop() const [BlockT 
= llvm::BasicBlock, LoopT = llvm::Loop]: Assertion 
`std::any_of(GraphTraits<BlockT *>::child_begin(BB), GraphTraits<BlockT 
*>::child_end(BB), [&](BlockT *B) { return contains(B); }) && "Loop 
block has no in-loop successors!"' failed.

This assertion started to trigger with r329047:

     [SCEV] Make computeExitLimit more simple and more powerful

and before that we instead get a failed assertion in SCEV

opt: ../lib/Analysis/ScalarEvolution.cpp:6948: 
ScalarEvolution::ExitLimit llvm::ScalarEvolution::computeExitLimit(const 
llvm::Loop *, llvm::BasicBlock *, bool): Assertion `BI->isConditional() 
&& "If unconditional, it can't be in loop!"' failed.

and this crash appears all the way back to when -simple-loop-unswitch 
was introduced.

We're not normally using -simple-loop-unswitch when compiling for our 
out-of-tree target but found this during fuzz testing using random passes.

Regards,
Mikael


On 06/13/2018 08:52 AM, Mikael Holmén wrote:
> Hi Chandler,
> 
> With this commit I get a failed assertion when running
> 
>   opt -S -o - bbi-14637.ll -simple-loop-unswitch -loop-deletion
> 
> I get
> 
> opt: ../include/llvm/Analysis/LoopInfo.h:150: ArrayRef<BlockT *> 
> llvm::LoopBase<llvm::BasicBlock, llvm::Loop>::getBlocks() const [BlockT 
> = llvm::BasicBlock, LoopT = llvm::Loop]: Assertion `!isInvalid() && 
> "Loop not in a valid state!"' failed.
> Stack dump:
> 0.      Program arguments: ../llvm-patch/build-all/bin/opt -S -o - 
> bbi-14637.ll -simple-loop-unswitch -loop-deletion
> 1.      Running pass 'Function Pass Manager' on module 'bbi-14637.ll'.
> 2.      Running pass 'Loop Pass Manager' on function '@f1'
> #0 0x0000000001fdc3f4 PrintStackTraceSignalHandler(void*) 
> (../llvm-patch/build-all/bin/opt+0x1fdc3f4)
> #1 0x0000000001fda640 llvm::sys::RunSignalHandlers() 
> (../llvm-patch/build-all/bin/opt+0x1fda640)
> #2 0x0000000001fdc758 SignalHandler(int) 
> (../llvm-patch/build-all/bin/opt+0x1fdc758)
> #3 0x00007fbc7fa4a330 __restore_rt 
> (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
> #4 0x00007fbc7e639c37 gsignal 
> /build/eglibc-ripdx6/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0 
> 
> #5 0x00007fbc7e63d028 abort 
> /build/eglibc-ripdx6/eglibc-2.19/stdlib/abort.c:91:0
> #6 0x00007fbc7e632bf6 __assert_fail_base 
> /build/eglibc-ripdx6/eglibc-2.19/assert/assert.c:92:0
> #7 0x00007fbc7e632ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
> #8 0x00000000015208d2 
> llvm::LPPassManager::runOnFunction(llvm::Function&) 
> (../llvm-patch/build-all/bin/opt+0x15208d2)
> #9 0x0000000001a6ab0a 
> llvm::FPPassManager::runOnFunction(llvm::Function&) 
> (../llvm-patch/build-all/bin/opt+0x1a6ab0a)
> #10 0x0000000001a6ad68 llvm::FPPassManager::runOnModule(llvm::Module&) 
> (../llvm-patch/build-all/bin/opt+0x1a6ad68)
> #11 0x0000000001a6b29d llvm::legacy::PassManagerImpl::run(llvm::Module&) 
> (../llvm-patch/build-all/bin/opt+0x1a6b29d)
> #12 0x000000000074498c main (../llvm-patch/build-all/bin/opt+0x74498c)
> #13 0x00007fbc7e624f45 __libc_start_main 
> /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
> #14 0x000000000072dced _start (../llvm-patch/build-all/bin/opt+0x72dced)
> Abort
> 
> With -debug-pass=Executions we get
> 
> Pass Arguments:  -targetlibinfo -tti -targetpassconfig 
> -assumption-cache-tracker -domtree -loops -loop-simplify 
> -lcssa-verification -lcssa -basicaa -aa -scalar-evolution 
> -simple-loop-unswitch -loop-deletion -verify -print-module
> Target Library Information
> Target Transform Information
> Target Pass Configuration
> Assumption Cache Tracker
>    ModulePass Manager
>      FunctionPass Manager
>        Dominator Tree Construction
>        Natural Loop Information
>        Canonicalize natural loops
>        LCSSA Verifier
>        Loop-Closed SSA Form Pass
>        Basic Alias Analysis (stateless AA impl)
>        Function Alias Analysis Results
>        Scalar Evolution Analysis
>        Loop Pass Manager
>          Simple unswitch loops
>          Delete dead loops
>        Module Verifier
>      Print Module IR
> [2018-06-13 08:49:54.217778133] 0x4332600   Executing Pass 'Function 
> Pass Manager' on Module 'bbi-14637.ll'...
> [2018-06-13 08:49:54.217895120] 0x4360730     Executing Pass 'Dominator 
> Tree Construction' on Function 'f1'...
> [2018-06-13 08:49:54.217935699] 0x4360730     Executing Pass 'Natural 
> Loop Information' on Function 'f1'...
> [2018-06-13 08:49:54.217994577] 0x4360730     Executing Pass 
> 'Canonicalize natural loops' on Function 'f1'...
> [2018-06-13 08:49:54.218053804] 0x4360730     Made Modification 
> 'Canonicalize natural loops' on Function 'f1'...
> [2018-06-13 08:49:54.218087119] 0x4360730     Executing Pass 'LCSSA 
> Verifier' on Function 'f1'...
> [2018-06-13 08:49:54.218119526] 0x4360730     Executing Pass 
> 'Loop-Closed SSA Form Pass' on Function 'f1'...
> [2018-06-13 08:49:54.218171420] 0x4360730     Executing Pass 'Basic 
> Alias Analysis (stateless AA impl)' on Function 'f1'...
> [2018-06-13 08:49:54.218216469] 0x4360730     Executing Pass 'Function 
> Alias Analysis Results' on Function 'f1'...
> [2018-06-13 08:49:54.218262635] 0x4360730     Executing Pass 'Scalar 
> Evolution Analysis' on Function 'f1'...
> [2018-06-13 08:49:54.218319557] 0x4360730     Executing Pass 'Loop Pass 
> Manager' on Function 'f1'...
> [2018-06-13 08:49:54.218355946] 0x4361cc0       Executing Pass 'Simple 
> unswitch loops' on Loop 'for.body'...
> [2018-06-13 08:49:54.220672155] 0x4361cc0       Made Modification 
> 'Simple unswitch loops' on Loop 'for.body'...
> [2018-06-13 08:49:54.220740042] 0x4361cc0        Freeing Pass 'Simple 
> unswitch loops' on Loop 'for.body'...
> [2018-06-13 08:49:54.220760856] 0x4361cc0       Executing Pass 'Delete 
> dead loops' on Loop 'for.body'...
> [2018-06-13 08:49:54.220917514] 0x4361cc0       Made Modification 
> 'Delete dead loops' on Loop '<deleted loop>'...
> [2018-06-13 08:49:54.220942727] 0x4361cc0        Freeing Pass 'Delete 
> dead loops' on Loop '<deleted>'...
> [2018-06-13 08:49:54.220961096] 0x4361cc0        Freeing Pass 'Simple 
> unswitch loops' on Loop '<deleted>'...
> [2018-06-13 08:49:54.220979325] 0x4361cc0        Freeing Pass 'Delete 
> dead loops' on Loop '<deleted>'...
> opt: ../include/llvm/Analysis/LoopInfo.h:150: ArrayRef<BlockT *> 
> llvm::LoopBase<llvm::BasicBlock, llvm::Loop>::getBlocks() const [BlockT 
> = llvm::BasicBlock, LoopT = llvm::Loop]: Assertion `!isInvalid() && 
> "Loop not in a valid state!"' failed.
> 
> Regards,
> Mikael
> 
> 
> On 05/30/2018 04:46 AM, Chandler Carruth via llvm-commits wrote:
>> Author: chandlerc
>> Date: Tue May 29 19:46:45 2018
>> New Revision: 333493
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=333493&view=rev
>> Log:
>> [PM/LoopUnswitch] When using the new SimpleLoopUnswitch pass, schedule
>> loop-cleanup passes at the beginning of the loop pass pipeline, and
>> re-enqueue loops after even trivial unswitching.
>>
>> This will allow us to much more consistently avoid simplifying code
>> while doing trivial unswitching. I've also added a test case that
>> specifically shows effective iteration using this technique.
>>
>> I've unconditionally updated the new PM as that is always using the
>> SimpleLoopUnswitch pass, and I've made the pipeline changes for the old
>> PM conditional on using this new unswitch pass. I added a bunch of
>> comments to the loop pass pipeline in the old PM to make it more clear
>> what is going on when reviewing.
>>
>> Hopefully this will unblock doing *partial* unswitching instead of just
>> full unswitching.
>>
>> Differential Revision: https://reviews.llvm.org/D47408
>>
>> Added:
>>      
>> llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll 
>>
>> Modified:
>>      llvm/trunk/lib/Passes/PassBuilder.cpp
>>      llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
>>      llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
>>      llvm/trunk/test/Other/new-pm-defaults.ll
>>      llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
>>
>> Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=333493&r1=333492&r2=333493&view=diff 
>>
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
>> +++ llvm/trunk/lib/Passes/PassBuilder.cpp Tue May 29 19:46:45 2018
>> @@ -390,13 +390,21 @@ PassBuilder::buildFunctionSimplification
>>     // Add the primary loop simplification pipeline.
>>     // FIXME: Currently this is split into two loop pass pipelines 
>> because we run
>> -  // some function passes in between them. These can and should be 
>> replaced by
>> -  // loop pass equivalenst but those aren't ready yet. Specifically,
>> -  // `SimplifyCFGPass` and `InstCombinePass` are used. We have
>> -  // `LoopSimplifyCFGPass` which isn't yet powerful enough, and the 
>> closest to
>> -  // the other we have is `LoopInstSimplify`.
>> +  // some function passes in between them. These can and should be 
>> removed
>> +  // and/or replaced by scheduling the loop pass equivalents in the 
>> correct
>> +  // positions. But those equivalent passes aren't powerful enough yet.
>> +  // Specifically, `SimplifyCFGPass` and `InstCombinePass` are 
>> currently still
>> +  // used. We have `LoopSimplifyCFGPass` which isn't yet powerful 
>> enough yet to
>> +  // fully replace `SimplifyCFGPass`, and the closest to the other we 
>> have is
>> +  // `LoopInstSimplify`.
>>     LoopPassManager LPM1(DebugLogging), LPM2(DebugLogging);
>> +  // Simplify the loop body. We do this initially to clean up after 
>> other loop
>> +  // passes run, either when iterating on a loop or on inner loops with
>> +  // implications on the outer loop.
>> +  LPM1.addPass(LoopInstSimplifyPass());
>> +  LPM1.addPass(LoopSimplifyCFGPass());
>> +
>>     // Rotate Loop - disable header duplication at -Oz
>>     LPM1.addPass(LoopRotatePass(Level != Oz));
>>     LPM1.addPass(LICMPass());
>>
>> Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=333493&r1=333492&r2=333493&view=diff 
>>
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
>> +++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Tue May 29 
>> 19:46:45 2018
>> @@ -138,10 +138,10 @@ static cl::opt<bool>
>>                                 cl::Hidden,
>>                                 cl::desc("Disable shrink-wrap library 
>> calls"));
>> -static cl::opt<bool>
>> -    EnableSimpleLoopUnswitch("enable-simple-loop-unswitch", 
>> cl::init(false),
>> -                             cl::Hidden,
>> -                             cl::desc("Enable the simple loop 
>> unswitch pass."));
>> +static cl::opt<bool> EnableSimpleLoopUnswitch(
>> +    "enable-simple-loop-unswitch", cl::init(false), cl::Hidden,
>> +    cl::desc("Enable the simple loop unswitch pass. Also enables 
>> independent "
>> +             "cleanup passes integrated into the loop pass manager 
>> pipeline."));
>>   static cl::opt<bool> EnableGVNSink(
>>       "enable-gvn-sink", cl::init(false), cl::Hidden,
>> @@ -335,6 +335,15 @@ void PassManagerBuilder::addFunctionSimp
>>     MPM.add(createTailCallEliminationPass()); // Eliminate tail calls
>>     MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
>>     MPM.add(createReassociatePass());           // Reassociate 
>> expressions
>> +
>> +  // Begin the loop pass pipeline.
>> +  if (EnableSimpleLoopUnswitch) {
>> +    // The simple loop unswitch pass relies on separate cleanup 
>> passes. Schedule
>> +    // them first so when we re-process a loop they run before other 
>> loop
>> +    // passes.
>> +    MPM.add(createLoopInstSimplifyPass());
>> +    MPM.add(createLoopSimplifyCFGPass());
>> +  }
>>     // Rotate Loop - disable header duplication at -Oz
>>     MPM.add(createLoopRotatePass(SizeLevel == 2 ? 0 : -1));
>>     MPM.add(createLICMPass());                  // Hoist loop invariants
>> @@ -342,20 +351,26 @@ void PassManagerBuilder::addFunctionSimp
>>       MPM.add(createSimpleLoopUnswitchLegacyPass());
>>     else
>>       MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3, 
>> DivergentTarget));
>> +  // FIXME: We break the loop pass pipeline here in order to do full
>> +  // simplify-cfg. Eventually loop-simplifycfg should be enhanced to 
>> replace the
>> +  // need for this.
>>     MPM.add(createCFGSimplificationPass());
>>     addInstructionCombiningPass(MPM);
>> +  // We resume loop passes creating a second loop pipeline here.
>>     MPM.add(createIndVarSimplifyPass());        // Canonicalize indvars
>>     MPM.add(createLoopIdiomPass());             // Recognize idioms 
>> like memset.
>>     addExtensionsToPM(EP_LateLoopOptimizations, MPM);
>>     MPM.add(createLoopDeletionPass());          // Delete dead loops
>>     if (EnableLoopInterchange) {
>> +    // FIXME: These are function passes and break the loop pass 
>> pipeline.
>>       MPM.add(createLoopInterchangePass()); // Interchange loops
>>       MPM.add(createCFGSimplificationPass());
>>     }
>>     if (!DisableUnrollLoops)
>>       MPM.add(createSimpleLoopUnrollPass(OptLevel));    // Unroll 
>> small loops
>>     addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
>> +  // This ends the loop pass pipelines.
>>     if (OptLevel > 1) {
>>       MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in 
>> diamonds
>>
>> Modified: llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp?rev=333493&r1=333492&r2=333493&view=diff 
>>
>> ============================================================================== 
>>
>> --- llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp Tue May 29 
>> 19:46:45 2018
>> @@ -1466,7 +1466,7 @@ void visitDomSubTree(DominatorTree &DT,
>>   static bool unswitchInvariantBranch(
>>       Loop &L, BranchInst &BI, DominatorTree &DT, LoopInfo &LI,
>>       AssumptionCache &AC,
>> -    function_ref<void(bool, ArrayRef<Loop *>)> NonTrivialUnswitchCB) {
>> +    function_ref<void(bool, ArrayRef<Loop *>)> UnswitchCB) {
>>     assert(BI.isConditional() && "Can only unswitch a conditional 
>> branch!");
>>     assert(L.isLoopInvariant(BI.getCondition()) &&
>>            "Can only unswitch an invariant branch condition!");
>> @@ -1706,7 +1706,7 @@ static bool unswitchInvariantBranch(
>>     for (Loop *UpdatedL : llvm::concat<Loop *>(NonChildClonedLoops, 
>> HoistedLoops))
>>       if (UpdatedL->getParentLoop() == ParentL)
>>         SibLoops.push_back(UpdatedL);
>> -  NonTrivialUnswitchCB(IsStillLoop, SibLoops);
>> +  UnswitchCB(IsStillLoop, SibLoops);
>>     ++NumBranches;
>>     return true;
>> @@ -1754,23 +1754,27 @@ computeDomSubtreeCost(DomTreeNode &N,
>>   static bool
>>   unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, 
>> AssumptionCache &AC,
>>                TargetTransformInfo &TTI, bool NonTrivial,
>> -             function_ref<void(bool, ArrayRef<Loop *>)> 
>> NonTrivialUnswitchCB) {
>> +             function_ref<void(bool, ArrayRef<Loop *>)> UnswitchCB) {
>>     assert(L.isRecursivelyLCSSAForm(DT, LI) &&
>>            "Loops must be in LCSSA form before unswitching.");
>> -  bool Changed = false;
>>     // Must be in loop simplified form: we need a preheader and 
>> dedicated exits.
>>     if (!L.isLoopSimplifyForm())
>>       return false;
>>     // Try trivial unswitch first before loop over other basic blocks 
>> in the loop.
>> -  Changed |= unswitchAllTrivialConditions(L, DT, LI);
>> +  if (unswitchAllTrivialConditions(L, DT, LI)) {
>> +    // If we unswitched successfully we will want to clean up the 
>> loop before
>> +    // processing it further so just mark it as unswitched and return.
>> +    UnswitchCB(/*CurrentLoopValid*/ true, {});
>> +    return true;
>> +  }
>>     // If we're not doing non-trivial unswitching, we're done. We both 
>> accept
>>     // a parameter but also check a local flag that can be used for 
>> testing
>>     // a debugging.
>>     if (!NonTrivial && !EnableNonTrivialUnswitch)
>> -    return Changed;
>> +    return false;
>>     // Collect all remaining invariant branch conditions within this 
>> loop (as
>>     // opposed to an inner loop which would be handled when visiting 
>> that inner
>> @@ -1785,7 +1789,7 @@ unswitchLoop(Loop &L, DominatorTree &DT,
>>     // If we didn't find any candidates, we're done.
>>     if (UnswitchCandidates.empty())
>> -    return Changed;
>> +    return false;
>>     // Check if there are irreducible CFG cycles in this loop. If so, 
>> we cannot
>>     // easily unswitch non-trivial edges out of the loop. Doing so 
>> might turn the
>> @@ -1796,7 +1800,7 @@ unswitchLoop(Loop &L, DominatorTree &DT,
>>     LoopBlocksRPO RPOT(&L);
>>     RPOT.perform(&LI);
>>     if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
>> -    return Changed;
>> +    return false;
>>     LLVM_DEBUG(
>>         dbgs() << "Considering " << UnswitchCandidates.size()
>> @@ -1824,10 +1828,10 @@ unswitchLoop(Loop &L, DominatorTree &DT,
>>           continue;
>>         if (I.getType()->isTokenTy() && I.isUsedOutsideOfBlock(BB))
>> -        return Changed;
>> +        return false;
>>         if (auto CS = CallSite(&I))
>>           if (CS.isConvergent() || CS.cannotDuplicate())
>> -          return Changed;
>> +          return false;
>>         Cost += TTI.getUserCost(&I);
>>       }
>> @@ -1898,18 +1902,17 @@ unswitchLoop(Loop &L, DominatorTree &DT,
>>       }
>>     }
>> -  if (BestUnswitchCost < UnswitchThreshold) {
>> -    LLVM_DEBUG(dbgs() << "  Trying to unswitch non-trivial (cost = "
>> -                      << BestUnswitchCost << ") branch: " << 
>> *BestUnswitchTI
>> -                      << "\n");
>> -    Changed |= unswitchInvariantBranch(L, 
>> cast<BranchInst>(*BestUnswitchTI), DT,
>> -                                       LI, AC, NonTrivialUnswitchCB);
>> -  } else {
>> +  if (BestUnswitchCost >= UnswitchThreshold) {
>>       LLVM_DEBUG(dbgs() << "Cannot unswitch, lowest cost found: "
>>                         << BestUnswitchCost << "\n");
>> +    return false;
>>     }
>> -  return Changed;
>> +  LLVM_DEBUG(dbgs() << "  Trying to unswitch non-trivial (cost = "
>> +                    << BestUnswitchCost << ") branch: " << 
>> *BestUnswitchTI
>> +                    << "\n");
>> +  return unswitchInvariantBranch(L, 
>> cast<BranchInst>(*BestUnswitchTI), DT, LI,
>> +                                 AC, UnswitchCB);
>>   }
>>   PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, 
>> LoopAnalysisManager &AM,
>> @@ -1925,10 +1928,11 @@ PreservedAnalyses SimpleLoopUnswitchPass
>>     // after it has been deleted.
>>     std::string LoopName = L.getName();
>> -  auto NonTrivialUnswitchCB = [&L, &U, &LoopName](bool CurrentLoopValid,
>> -                                                  ArrayRef<Loop *> 
>> NewLoops) {
>> +  auto UnswitchCB = [&L, &U, &LoopName](bool CurrentLoopValid,
>> +                                        ArrayRef<Loop *> NewLoops) {
>>       // If we did a non-trivial unswitch, we have added new (cloned) 
>> loops.
>> -    U.addSiblingLoops(NewLoops);
>> +    if (!NewLoops.empty())
>> +      U.addSiblingLoops(NewLoops);
>>       // If the current loop remains valid, we should revisit it to 
>> catch any
>>       // other unswitch opportunities. Otherwise, we need to mark it 
>> as deleted.
>> @@ -1939,7 +1943,7 @@ PreservedAnalyses SimpleLoopUnswitchPass
>>     };
>>     if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.TTI, NonTrivial,
>> -                    NonTrivialUnswitchCB))
>> +                    UnswitchCB))
>>       return PreservedAnalyses::all();
>>     // Historically this pass has had issues with the dominator tree 
>> so verify it
>> @@ -1987,8 +1991,8 @@ bool SimpleLoopUnswitchLegacyPass::runOn
>>     auto &AC = 
>> getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
>>     auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
>> -  auto NonTrivialUnswitchCB = [&L, &LPM](bool CurrentLoopValid,
>> -                                         ArrayRef<Loop *> NewLoops) {
>> +  auto UnswitchCB = [&L, &LPM](bool CurrentLoopValid,
>> +                               ArrayRef<Loop *> NewLoops) {
>>       // If we did a non-trivial unswitch, we have added new (cloned) 
>> loops.
>>       for (auto *NewL : NewLoops)
>>         LPM.addLoop(*NewL);
>> @@ -2003,7 +2007,7 @@ bool SimpleLoopUnswitchLegacyPass::runOn
>>     };
>>     bool Changed =
>> -      unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, 
>> NonTrivialUnswitchCB);
>> +      unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, UnswitchCB);
>>     // If anything was unswitched, also clear any cached information 
>> about this
>>     // loop.
>>
>> Modified: llvm/trunk/test/Other/new-pm-defaults.ll
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-defaults.ll?rev=333493&r1=333492&r2=333493&view=diff 
>>
>> ============================================================================== 
>>
>> --- llvm/trunk/test/Other/new-pm-defaults.ll (original)
>> +++ llvm/trunk/test/Other/new-pm-defaults.ll Tue May 29 19:46:45 2018
>> @@ -145,6 +145,8 @@
>>   ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
>>   ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
>>   ; CHECK-O-NEXT: Starting Loop pass manager run.
>> +; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
>> +; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
>>   ; CHECK-O-NEXT: Running pass: LoopRotatePass
>>   ; CHECK-O-NEXT: Running pass: LICM
>>   ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
>>
>> Modified: llvm/trunk/test/Other/new-pm-thinlto-defaults.ll
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pm-thinlto-defaults.ll?rev=333493&r1=333492&r2=333493&view=diff 
>>
>> ============================================================================== 
>>
>> --- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll (original)
>> +++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll Tue May 29 
>> 19:46:45 2018
>> @@ -129,6 +129,8 @@
>>   ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
>>   ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
>>   ; CHECK-O-NEXT: Starting Loop pass manager run.
>> +; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
>> +; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
>>   ; CHECK-O-NEXT: Running pass: LoopRotatePass
>>   ; CHECK-O-NEXT: Running pass: LICM
>>   ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
>>
>> Added: 
>> llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll 
>>
>> URL: 
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll?rev=333493&view=auto 
>>
>> ============================================================================== 
>>
>> --- 
>> llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll 
>> (added)
>> +++ 
>> llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll 
>> Tue May 29 19:46:45 2018
>> @@ -0,0 +1,41 @@
>> +; RUN: opt 
>> -passes='loop(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' 
>> -S < %s | FileCheck %s
>> +
>> +declare void @some_func() noreturn
>> +
>> +define i32 @test1(i32* %var, i1 %cond1, i1 %cond2) {
>> +; CHECK-LABEL: @test1(
>> +entry:
>> +  br label %loop_begin
>> +; CHECK-NEXT:  entry:
>> +; CHECK-NEXT:    br i1 %{{.*}}, label %entry.split, label 
>> %loop_exit.split
>> +;
>> +; CHECK:       entry.split:
>> +; CHECK-NEXT:    br i1 %{{.*}}, label %entry.split.split, label 
>> %loop_exit
>> +;
>> +; CHECK:       entry.split.split:
>> +; CHECK-NEXT:    br label %do_something
>> +
>> +loop_begin:
>> +  br i1 %cond1, label %continue, label %loop_exit ; first trivial 
>> condition
>> +
>> +continue:
>> +  %var_val = load i32, i32* %var
>> +  %var_cond = trunc i32 %var_val to i1
>> +  %maybe_cond = select i1 %cond1, i1 %cond2, i1 %var_cond
>> +  br i1 %maybe_cond, label %do_something, label %loop_exit ; second 
>> trivial condition
>> +
>> +do_something:
>> +  call void @some_func() noreturn nounwind
>> +  br label %loop_begin
>> +; CHECK:       do_something:
>> +; CHECK-NEXT:    call
>> +; CHECK-NEXT:    br label %do_something
>> +
>> +loop_exit:
>> +  ret i32 0
>> +; CHECK:       loop_exit:
>> +; CHECK-NEXT:    br label %loop_exit.split
>> +;
>> +; CHECK:       loop_exit.split:
>> +; CHECK-NEXT:    ret
>> +}
>> \ No newline at end of file
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
-------------- next part --------------
target triple = "x86_64-unknown-linux-gnu"

define void @f1() {
entry:
  %tobool = icmp ne i16 undef, 0
  br label %lbl1

lbl1:                                             ; preds = %if.then, %entry
  br label %for.body

for.body:                                         ; preds = %for.inc, %lbl1
  br i1 %tobool, label %if.then, label %if.end

if.then:                                          ; preds = %for.body
  br label %lbl1

if.end:                                           ; preds = %for.body
  br label %for.inc

for.inc:                                          ; preds = %if.end
  br i1 undef, label %for.body, label %for.end

for.end:                                          ; preds = %for.inc
  ret void
}


More information about the llvm-commits mailing list