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

Mikael Holmén via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 21 01:16:28 PDT 2018


Hi,

I wrote
  https://bugs.llvm.org/show_bug.cgi?id=37888

and
  https://bugs.llvm.org/show_bug.cgi?id=37889

about the two crashes.

Regards,
Mikael


On 06/13/2018 10:54 AM, Mikael Holmén wrote:
> 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
>>>



More information about the llvm-commits mailing list