[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