This is an archive of the discontinued LLVM Phabricator instance.

[LoopDeletion] Use max trip count to break backedge in addition to exact one
ClosedPublic

Authored by reames on Aug 27 2021, 10:53 AM.

Details

Summary

We'd added support a while back from breaking the backedge if SCEV can prove the trip count is zero. However, we used the exact trip count which requires *all* exits be analyzeable. I noticed while writing test cases for another patch that this disallows cases where one exit is provably taken paired with another which is unknown. This patch adds the upper bound case.

We could use a symbolic max trip count here instead, but we use an isKnownNonZero filter (presumably for compile time?) for the first-iteration reasoning. I decided this was a more obvious incremental step, and we could go back and untangle the schemes separately.

Diff Detail

Event Timeline

reames created this revision.Aug 27 2021, 10:53 AM
reames requested review of this revision.Aug 27 2021, 10:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 27 2021, 10:53 AM
reames edited the summary of this revision. (Show Details)Aug 27 2021, 10:59 AM
nikic accepted this revision.Aug 27 2021, 1:53 PM

LGTM

llvm/lib/Transforms/Scalar/LoopDeletion.cpp
399

I find this extra BTC->isZero() check a bit confusing -- unless I'm missing something, the check against getConstantMaxBackedgeTakenCount() should be strictly more powerful, right? For the exact count to return zero all exits must have a constant BECount of zero, so the constant max BE count must also be zero.

(We might also want to drop the isKnownNonZero optimization, as IIRC it had no real impact in practice, but that's a different matter.)

This revision is now accepted and ready to land.Aug 27 2021, 1:53 PM
reames added inline comments.Aug 27 2021, 2:17 PM
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
399

You're correct - in theory. I'm very hesitant to introduce an assumption of max=0 ==> exact=0 though as I don't see that properly asserted anywhere in the existing code. We could today compute somewhere in the TC logic a zero max with a non-zero exact, and nothing would care.

Hi,

The following starts crashing with this patch:

opt -passes='function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm))' -o /dev/null bbi-63573.ll

We get

opt: ../lib/Transforms/Scalar/LICM.cpp:1639: void splitPredecessorsOfLoopExit(llvm::PHINode *, llvm::DominatorTree *, llvm::LoopInfo *, const llvm::Loop *, llvm::LoopSafetyInfo *, llvm::MemorySSAUpdater *): Assertion `CurLoop->contains(PredBB) && "Expect all predecessors are in the loop"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ../../master-github/llvm/build-all/bin/opt -passes=function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm)) -o /dev/null bbi-63573.ll
 #0 0x0000000002bc80c3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (../../master-github/llvm/build-all/bin/opt+0x2bc80c3)
 #1 0x0000000002bc5d3e llvm::sys::RunSignalHandlers() (../../master-github/llvm/build-all/bin/opt+0x2bc5d3e)
 #2 0x0000000002bc8446 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fe912719630 __restore_rt sigaction.c:0:0
 #4 0x00007fe90fe4c387 raise (/lib64/libc.so.6+0x36387)
 #5 0x00007fe90fe4da78 abort (/lib64/libc.so.6+0x37a78)
 #6 0x00007fe90fe451a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6)
 #7 0x00007fe90fe45252 (/lib64/libc.so.6+0x2f252)
 #8 0x000000000291ab08 llvm::sinkRegion(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::TargetTransformInfo*, llvm::Loop*, llvm::MemorySSAUpdater*, llvm::ICFLoopSafetyInfo*, llvm::SinkAndHoistLICMFlags&, llvm::OptimizationRemarkEmitter*, llvm::Loop*) (../../master-github/llvm/build-all/bin/opt+0x291ab08)
 #9 0x000000000291c6f8 llvm::sinkRegionForLoopNest(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::TargetTransformInfo*, llvm::Loop*, llvm::MemorySSAUpdater*, llvm::ICFLoopSafetyInfo*, llvm::SinkAndHoistLICMFlags&, llvm::OptimizationRemarkEmitter*) (../../master-github/llvm/build-all/bin/opt+0x291c6f8)
#10 0x000000000291637e (anonymous namespace)::LoopInvariantCodeMotion::runOnLoop(llvm::Loop*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::TargetTransformInfo*, llvm::ScalarEvolution*, llvm::MemorySSA*, llvm::OptimizationRemarkEmitter*, bool) LICM.cpp:0:0
#11 0x0000000002917502 llvm::LNICMPass::run(llvm::LoopNest&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (../../master-github/llvm/build-all/bin/opt+0x2917502)
#12 0x0000000002ed6b8d llvm::detail::PassModel<llvm::LoopNest, llvm::LNICMPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::LoopNest&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) crtstuff.c:0:0
#13 0x000000000341163c llvm::Optional<llvm::PreservedAnalyses> llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runSinglePass<llvm::LoopNest, std::unique_ptr<llvm::detail::PassConcept<llvm::LoopNest, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::LoopNest, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > > >(llvm::LoopNest&, std::unique_ptr<llvm::detail::PassConcept<llvm::LoopNest, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::LoopNest, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > >&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&, llvm::PassInstrumentation&) (../../master-github/llvm/build-all/bin/opt+0x341163c)
#14 0x0000000003410a83 llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runWithLoopNestPasses(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (../../master-github/llvm/build-all/bin/opt+0x3410a83)
#15 0x0000000003410661 llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (../../master-github/llvm/build-all/bin/opt+0x3410661)
#16 0x0000000002eaa25d llvm::detail::PassModel<llvm::Loop, llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) crtstuff.c:0:0
#17 0x000000000341255b llvm::FunctionToLoopPassAdaptor::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../master-github/llvm/build-all/bin/opt+0x341255b)
#18 0x0000000002ec593d llvm::detail::PassModel<llvm::Function, llvm::FunctionToLoopPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) crtstuff.c:0:0
#19 0x00000000023562a5 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (../../master-github/llvm/build-all/bin/opt+0x23562a5)
#20 0x0000000000ae88fd llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) crtstuff.c:0:0
#21 0x000000000235a6ca llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (../../master-github/llvm/build-all/bin/opt+0x235a6ca)
#22 0x0000000000793f0d llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) crtstuff.c:0:0
#23 0x00000000023553e8 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (../../master-github/llvm/build-all/bin/opt+0x23553e8)
#24 0x000000000078bc82 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::StringRef>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool) (../../master-github/llvm/build-all/bin/opt+0x78bc82)
#25 0x000000000079e8ad main (../../master-github/llvm/build-all/bin/opt+0x79e8ad)
#26 0x00007fe90fe38555 __libc_start_main (/lib64/libc.so.6+0x22555)
#27 0x00000000007870cc _start (../../master-github/llvm/build-all/bin/opt+0x7870cc)
Abort

Hi,

The following starts crashing with this patch:

Please file a bug. This does not appear to be a regression with this patch. I've done some analysis and will provide it in the bug report.

Hi,

The following starts crashing with this patch:

Please file a bug. This does not appear to be a regression with this patch. I've done some analysis and will provide it in the bug report.

Sure, will do (as soon as we have a bug reporting system again and I realize how to use it :) .
Thanks!

Hi,

The following starts crashing with this patch:

Please file a bug. This does not appear to be a regression with this patch. I've done some analysis and will provide it in the bug report.

There:
https://github.com/llvm/llvm-project/issues/52688

fhahn added a comment.Dec 14 2021, 3:58 AM

Hi,

The following starts crashing with this patch:

Please file a bug. This does not appear to be a regression with this patch. I've done some analysis and will provide it in the bug report.

There:
https://github.com/llvm/llvm-project/issues/52688

I suspect this may be a problem in the code added in D107219. I added a comment there.