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

Mikael Holmén via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 12 23:52:56 PDT 2018


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 %for.body

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

if.then:                                          ; preds = %for.body
  unreachable

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