This is an archive of the discontinued LLVM Phabricator instance.

[LoopDeletion] Handle Phis with similar inputs from different block
ClosedPublic

Authored by mkazantsev on Jun 9 2021, 5:46 AM.

Details

Summary

This patch lifts the requirement to have the only incoming live block
for Phis. There can be multiple live blocks if the same value comes to
phi from all live incoming blocks.

Diff Detail

Event Timeline

mkazantsev created this revision.Jun 9 2021, 5:46 AM
mkazantsev requested review of this revision.Jun 9 2021, 5:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 9 2021, 5:46 AM
nikic accepted this revision.Jun 9 2021, 9:45 AM

LGTM

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

Comment needs an update.

llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
664

TODO can be dropped.

This revision is now accepted and ready to land.Jun 9 2021, 9:45 AM
mkazantsev added inline comments.Jun 9 2021, 9:01 PM
llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
664

True, thanks!

mkazantsev planned changes to this revision.Jun 17 2021, 5:56 AM

Per underlying patch change

mkazantsev edited the summary of this revision. (Show Details)

Rebased, comments updated. Will wait couple days before landing, in case if underlying patch breaks.
@nikic could you please check if this has negative CT impact? I imagine it could, just interesting how big it is.

If it's visible, then maybe we should return to idea of lazy phi evaluation.

This revision is now accepted and ready to land.Jun 18 2021, 4:01 AM
nikic accepted this revision.Jun 18 2021, 5:43 AM

Not seeing any compile-time impact, and rebased versions still looks good.

Thanks! Let's give the dependent patch some time to break, and if it's fine, I'll merge this one.

This seems fine to me.
I think there may be some room for undef/poison incoming value handling.

Indeed, we can skip undefs as well.

This revision was landed with ongoing or failed builds.Jun 20 2021, 9:46 PM
This revision was automatically updated to reflect the committed changes.

This seems fine to me.
I think there may be some room for undef/poison incoming value handling.

D104618

This causes a crash while building the Linux kernel: https://github.com/ClangBuiltLinux/linux/issues/1403

$ cat cpu_errata.i
__boot_cpu_mode_0;
enum { false, true } arch_static_branch_jump() {
  asm goto("" : : : : l_yes);
  return false;
l_yes:
  return true;
}
is_hyp_mode_available() {
  if (({
        _Bool branch = arch_static_branch_jump();
        __builtin_expect(branch, 1);
      }))
    return true;
  return __boot_cpu_mode_0;
}
needs_tx2_tvm_workaround() {
  int i;
  if (!is_hyp_mode_available())
    return false;
  for (; i = cpumask_next(i);)
    ;
}

$ clang -O2 --target=aarch64-linux-gnu -c -o /dev/null cpu_errata.i
...
clang: /home/nathan/cbl/github/tc-build/llvm-project/llvm/include/llvm/IR/Instructions.h:2785: llvm::Value *llvm::PHINode::getIncomingValueForBlock(const llvm::BasicBlock *) const: Assertion `Idx >= 0 && "Invalid basic block argument!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: clang -O2 --target=aarch64-linux-gnu -c -o /dev/null cpu_errata.i
1.	<eof> parser at end of file
2.	Optimizer
 #0 0x0000000002f40033 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2f40033)
 #1 0x0000000002f3de7e llvm::sys::RunSignalHandlers() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2f3de7e)
 #2 0x0000000002ecea43 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0
 #3 0x0000000002eceb7e CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #4 0x00007fe3a8a10870 __restore_rt sigaction.c:0:0
 #5 0x00007fe3a84cad22 raise (/usr/lib/libc.so.6+0x3cd22)
 #6 0x00007fe3a84b4862 abort (/usr/lib/libc.so.6+0x26862)
 #7 0x00007fe3a84b4747 _nl_load_domain.cold loadmsgcat.c:0:0
 #8 0x00007fe3a84c3616 (/usr/lib/libc.so.6+0x35616)
 #9 0x0000000002d3d3ca breakBackedgeIfNotTaken(llvm::Loop*, llvm::DominatorTree&, llvm::ScalarEvolution&, llvm::LoopInfo&, llvm::MemorySSA*, llvm::OptimizationRemarkEmitter&) LoopDeletion.cpp:0:0
#10 0x0000000002d3b671 llvm::LoopDeletionPass::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2d3b671)
#11 0x0000000004069ccd llvm::detail::PassModel<llvm::Loop, llvm::LoopDeletionPass, 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&) PassBuilder.cpp:0:0
#12 0x00000000040a803f llvm::Optional<llvm::PreservedAnalyses> llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runSinglePass<llvm::Loop, std::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > > >(llvm::Loop&, std::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&> > >&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&, llvm::PassInstrumentation&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x40a803f)
#13 0x00000000040a7d97 llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runWithoutLoopNestPasses(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x40a7d97)
#14 0x00000000040a74b8 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&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x40a74b8)
#15 0x000000000405f7fd 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&) PassBuilder.cpp:0:0
#16 0x00000000040a91bd llvm::FunctionToLoopPassAdaptor::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x40a91bd)
#17 0x000000000406a14d llvm::detail::PassModel<llvm::Function, llvm::FunctionToLoopPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilder.cpp:0:0
#18 0x00000000028b0e71 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x28b0e71)
#19 0x000000000361f61d 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>&) BackendUtil.cpp:0:0
#20 0x0000000002916e1e llvm::CGSCCToFunctionPassAdaptor::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2916e1e)
#21 0x000000000406d65d llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::CGSCCToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) PassBuilder.cpp:0:0
#22 0x0000000002911351 llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2911351)
#23 0x0000000002a060ad llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) Inliner.cpp:0:0
#24 0x0000000002914f4a llvm::DevirtSCCRepeatedPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2914f4a)
#25 0x0000000002a063ed llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::DevirtSCCRepeatedPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) Inliner.cpp:0:0
#26 0x00000000029134c5 llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x29134c5)
#27 0x0000000002a0624d llvm::detail::PassModel<llvm::Module, llvm::ModuleToPostOrderCGSCCPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) Inliner.cpp:0:0
#28 0x00000000028afba4 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x28afba4)
#29 0x0000000002a02d2e llvm::ModuleInlinerWrapperPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2a02d2e)
#30 0x000000000406d90d llvm::detail::PassModel<llvm::Module, llvm::ModuleInlinerWrapperPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) PassBuilder.cpp:0:0
#31 0x00000000028afba4 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x28afba4)
#32 0x0000000003615a65 (anonymous namespace)::EmitAssemblyHelper::EmitAssemblyWithNewPassManager(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) BackendUtil.cpp:0:0
#33 0x000000000361024c clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x361024c)
#34 0x0000000003a8da60 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) CodeGenAction.cpp:0:0
#35 0x00000000041c73b4 clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x41c73b4)
#36 0x00000000039e2190 clang::FrontendAction::Execute() (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x39e2190)
#37 0x00000000039556df clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x39556df)
#38 0x0000000003a87b37 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x3a87b37)
#39 0x0000000001b4d708 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x1b4d708)
#40 0x0000000001b4b25d ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#41 0x00000000037f8512 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::$_1>(long) Job.cpp:0:0
#42 0x0000000002ece957 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x2ece957)
#43 0x00000000037f8077 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x37f8077)
#44 0x00000000037bfe48 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x37bfe48)
#45 0x00000000037c0117 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x37c0117)
#46 0x00000000037d87e1 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x37d87e1)
#47 0x0000000001b4ab26 main (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x1b4ab26)
#48 0x00007fe3a84b5b25 __libc_start_main (/usr/lib/libc.so.6+0x27b25)
#49 0x0000000001b47ece _start (/home/nathan/cbl/github/tc-build/build/llvm/stage1/bin/clang-13+0x1b47ece)
clang-13: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ClangBuiltLinux clang version 13.0.0 (https://github.com/llvm/llvm-project 0a2d4f3f24a377dc7d3cbed16d30603dc27554a8)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/nathan/cbl/github/tc-build/build/llvm/stage1/bin
clang-13: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

@nathanchance - I'd suggest reverting until @mkazantsev can investigate. He's offline for the next few hours due to time zones.

@nathanchance - I'd suggest reverting until @mkazantsev can investigate. He's offline for the next few hours due to time zones.

Done, thanks!

f52666985d7011b539f26f54e09a5c89b62dad56

Hi @nathanchance ! Thanks for revert. The failure doesn't make much sense to me though. My only idea is that this happens in unreachable code, where loop info may lie about something being a header. I'll try to reproduce this.

mkazantsev added a comment.EditedJun 21 2021, 9:52 PM

Ok, we stepped on a loop that doesn't have a sole predecessor (I didn't even know it's possible, but looks like the loops weren't canonicalized). Reduced IR repro:

opt -S -loop-deletion

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

define dso_local i32 @hoge() local_unnamed_addr #0 {
bb:
  callbr void asm sideeffect "", "X"(i8* blockaddress(@hoge, %bb2)) #1
          to label %bb1 [label %bb2]

bb1:                                              ; preds = %bb
  br label %bb2

bb2:                                              ; preds = %bb2, %bb1, %bb
  %tmp = phi i32 [ undef, %bb1 ], [ %tmp3, %bb2 ], [ undef, %bb ]
  %tmp3 = tail call i32 bitcast (i32 (...)* @widget to i32 (i32)*)(i32 %tmp) #1
  br label %bb2
}

declare dso_local i32 @widget(...) local_unnamed_addr #0

Failure was exposed, but no caused by this patch. I will land a fix and then return this one.