[llvm] [SCEV] Try to re-use pointer LCSSA phis when expanding SCEVs. (PR #147824)

Nathan Chancellor via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 27 12:13:20 PDT 2025


nathanchance wrote:

I am seeing an assertion failure when building the Linux kernel for Hexagon after this change.

```
# bad: [7d7f3819e0bf3adfbd77af3c6fa454636faa274c] Revert "[OMPIRBuilder] Don't use invalid debug loc in reduction functions." (#150832)
# good: [076d3050f1f85679f505405eefd0c2cd1ad6f92b] [RISCV] Merge verifyDagOpCount into addDagOperandMapping in CompressInstEmitter. (#150548)
git bisect start '7d7f3819e0bf3adfbd77af3c6fa454636faa274c' '076d3050f1f85679f505405eefd0c2cd1ad6f92b'
# bad: [284a5c2c0b97edddf255ea210f939203ad3d09f2] [mlir][NFC] update `mlir/examples` create APIs (31/n) (#150652)
git bisect bad 284a5c2c0b97edddf255ea210f939203ad3d09f2
# bad: [5294793bdcf6ca142f7a0df897638bd4e85ed1a7] Revert "[RISCV][TTI] Enable masked interleave access for scalable vector (#149981)"
git bisect bad 5294793bdcf6ca142f7a0df897638bd4e85ed1a7
# good: [33f4582e8d128eac6b699564ecddfef5c553288e] [llvm] [Demangle] Fix a typo in the definition of DEMANGLE_ABI for dllimport
git bisect good 33f4582e8d128eac6b699564ecddfef5c553288e
# good: [b75530ff034a131da8ca1f05a00f3655c13839ff] [LoopInterchange] Consider forward/backward dependency in vectorize heuristic (#133672)
git bisect good b75530ff034a131da8ca1f05a00f3655c13839ff
# bad: [e21ee41be450f849f5247aafa07d7f4c3941bb9d] [SCEV] Try to re-use pointer LCSSA phis when expanding SCEVs. (#147824)
git bisect bad e21ee41be450f849f5247aafa07d7f4c3941bb9d
# good: [c1545b68bcba16c3d21fd3d0ee3bc4c92aa8d98f] Reapply [BranchFolding] Kill common hoisted debug instructions (#149999)
git bisect good c1545b68bcba16c3d21fd3d0ee3bc4c92aa8d98f
# good: [cdb67e11313fe3f848599922774728d2e65f7cc9] [libc++][NFC] Make __is_segmented_iterator a variable template (#149976)
git bisect good cdb67e11313fe3f848599922774728d2e65f7cc9
# good: [e4963834e44b2d41d1d6bce0c7c585a4c0b7bf86] [MemProf] Include caller clone information in dot graph nodes (#150492)
git bisect good e4963834e44b2d41d1d6bce0c7c585a4c0b7bf86
# first bad commit: [e21ee41be450f849f5247aafa07d7f4c3941bb9d] [SCEV] Try to re-use pointer LCSSA phis when expanding SCEVs. (#147824)
```

`cvise` spits out:

```c
struct list_head {
  struct list_head *next;
} __list_add_prev_0, *cell_sort_array, *sort_cells_cell, sort_cells_tmp,
    process_thin_deferred_cells_cells;
int sort_cells_count, process_thin_deferred_cells___trans_tmp_15,
    process_thin_deferred_cells_j, process_thin_deferred_cells_count,
    process_deferred_bios_tc;
int list_empty();
int sort_cells(struct list_head *cells) {
  sort_cells_cell = ({
    void *__mptr = cells;
    __mptr;
  });
  for (; !(sort_cells_cell == 0);)
    cell_sort_array[sort_cells_count++] = sort_cells_tmp;
  return sort_cells_count;
}
void process_thin_deferred_cells() {
  do {
    process_thin_deferred_cells_count =
        sort_cells(&process_thin_deferred_cells_cells);
    if (process_thin_deferred_cells___trans_tmp_15) {
      process_thin_deferred_cells_j = 0;
      for (; process_thin_deferred_cells_j < process_thin_deferred_cells_count;
           process_thin_deferred_cells_j++)
        *(volatile typeof(__list_add_prev_0) *)0;
      return;
    }
  } while (list_empty());
}
void process_deferred_bios() {
  while (process_deferred_bios_tc)
    process_thin_deferred_cells();
}
```

```
$ clang --target=hexagon-linux -O2 -c -o /dev/null dm-thin.i
clang: llvm/lib/Transforms/Utils/LoopSimplify.cpp:709: bool llvm::simplifyLoop(Loop *, DominatorTree *, LoopInfo *, ScalarEvolution *, AssumptionCache *, MemorySSAUpdater *, bool): Assertion `L->isRecursivelyLCSSAForm(*DT, *LI) && "Requested to preserve LCSSA, but it's already broken."' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: clang --target=hexagon-linux -O2 -c -o /dev/null dm-thin.i
1.	<eof> parser at end of file
2.	Optimizer
3.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "dm-thin.i"
4.	Running pass "loop-unroll<O2>" on function "process_deferred_bios"
 #0 0x000055da77863d78 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (clang-22+0x3a23d78)
 #1 0x000055da778614b5 llvm::sys::RunSignalHandlers() (clang-22+0x3a214b5)
 #2 0x000055da777e2ab6 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f71f6e4def0 (/usr/lib/libc.so.6+0x3def0)
 #4 0x00007f71f6ea774c (/usr/lib/libc.so.6+0x9774c)
 #5 0x00007f71f6e4ddc0 raise (/usr/lib/libc.so.6+0x3ddc0)
 #6 0x00007f71f6e3557a abort (/usr/lib/libc.so.6+0x2557a)
 #7 0x00007f71f6e354e3 __assert_perror_fail (/usr/lib/libc.so.6+0x254e3)
 #8 0x000055da7793246d (clang-22+0x3af246d)
 #9 0x000055da7793d375 llvm::UnrollLoop(llvm::Loop*, llvm::UnrollLoopOptions, llvm::LoopInfo*, llvm::ScalarEvolution*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::TargetTransformInfo const*, llvm::OptimizationRemarkEmitter*, bool, llvm::Loop**, llvm::AAResults*) (clang-22+0x3afd375)
#10 0x000055da77706ef5 tryToUnrollLoop(llvm::Loop*, llvm::DominatorTree&, llvm::LoopInfo*, llvm::ScalarEvolution&, llvm::TargetTransformInfo const&, llvm::AssumptionCache&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, bool, int, bool, bool, bool, std::optional<unsigned int>, std::optional<unsigned int>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<unsigned int>, llvm::AAResults*) LoopUnrollPass.cpp:0:0
#11 0x000055da777077d7 llvm::LoopUnrollPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (clang-22+0x38c77d7)
#12 0x000055da789312ed llvm::detail::PassModel<llvm::Function, llvm::LoopUnrollPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilder.cpp:0:0
#13 0x000055da773af557 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (clang-22+0x356f557)
#14 0x000055da768b549d llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) X86CodeGenPassBuilder.cpp:0:0
#15 0x000055da773b2381 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (clang-22+0x3572381)
#16 0x000055da768b560d llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) X86CodeGenPassBuilder.cpp:0:0
#17 0x000055da773ae777 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (clang-22+0x356e777)
#18 0x000055da77fac07e (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#19 0x000055da77fa362a clang::emitBackendOutput(clang::CompilerInstance&, clang::CodeGenOptions&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (clang-22+0x416362a)
#20 0x000055da77fb8753 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (clang-22+0x4178753)
#21 0x000055da79615309 clang::ParseAST(clang::Sema&, bool, bool) (clang-22+0x57d5309)
#22 0x000055da7852e7c6 clang::FrontendAction::Execute() (clang-22+0x46ee7c6)
#23 0x000055da7849d3ed clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (clang-22+0x465d3ed)
#24 0x000055da7860042c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (clang-22+0x47c042c)
#25 0x000055da763a0b07 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (clang-22+0x2560b07)
#26 0x000055da7639c99f ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#27 0x000055da78302d39 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#28 0x000055da777e279e llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (clang-22+0x39a279e)
#29 0x000055da78302573 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (clang-22+0x44c2573)
#30 0x000055da782c3d2c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (clang-22+0x4483d2c)
#31 0x000055da782c3f47 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (clang-22+0x4483f47)
#32 0x000055da782e06a8 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (clang-22+0x44a06a8)
#33 0x000055da7639c243 clang_main(int, char**, llvm::ToolContext const&) (clang-22+0x255c243)
#34 0x000055da763ac9a7 main (clang-22+0x256c9a7)
#35 0x00007f71f6e376b5 (/usr/lib/libc.so.6+0x276b5)
#36 0x00007f71f6e37769 __libc_start_main (/usr/lib/libc.so.6+0x27769)
#37 0x000055da7639a425 _start (clang-22+0x255a425)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
```

`llvm-reduce` spits out:

```llvm
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
target triple = "hexagon-unknown-linux"

%struct.list_head = type { ptr }

@sort_cells_cell = external global ptr
@sort_cells_count = external global i32
@process_thin_deferred_cells_cells = external global %struct.list_head
@process_thin_deferred_cells___trans_tmp_15 = external global i32

define i32 @sort_cells(ptr %cells) {
entry:
  store ptr null, ptr @sort_cells_cell, align 4
  br label %for.cond

for.cond:                                         ; preds = %for.body, %entry
  %0 = phi ptr [ %.pre, %for.body ], [ %cells, %entry ]
  %cmp.not = icmp eq ptr %0, null
  br i1 %cmp.not, label %for.end, label %for.body

for.body:                                         ; preds = %for.cond
  %1 = load ptr, ptr %cells, align 4
  %2 = load i32, ptr @sort_cells_count, align 4, !tbaa !0
  %inc = add i32 %2, 1
  store i32 %inc, ptr @sort_cells_count, align 4, !tbaa !0
  store i32 0, ptr %1, align 4, !tbaa !4
  %.pre = load ptr, ptr %cells, align 4
  br label %for.cond

for.end:                                          ; preds = %for.cond
  %3 = load i32, ptr @sort_cells_count, align 4
  ret i32 %3
}

define void @process_thin_deferred_cells() {
entry:
  %agg.tmp.ensured.sroa.0 = alloca ptr, align 4
  br label %do.body

do.body:                                          ; preds = %do.body, %entry
  %call1 = call i32 @sort_cells(ptr @process_thin_deferred_cells_cells)
  %0 = load i32, ptr @process_thin_deferred_cells___trans_tmp_15, align 4
  %tobool.not = icmp eq i32 %0, 0
  br i1 %tobool.not, label %do.body, label %for.cond

for.cond:                                         ; preds = %for.body, %do.body
  %1 = phi i32 [ %inc, %for.body ], [ 0, %do.body ]
  %cmp = icmp slt i32 %1, %call1
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  store volatile ptr null, ptr %agg.tmp.ensured.sroa.0, align 4
  %inc = add i32 %1, 1
  br label %for.cond

for.end:                                          ; preds = %for.cond
  ret void
}

define void @process_deferred_bios() {
entry:
  br label %while.cond

while.cond:                                       ; preds = %while.cond, %entry
  call void @process_thin_deferred_cells()
  br label %while.cond
}

!0 = !{!1, !1, i64 0}
!1 = !{!"int", !2, i64 0}
!2 = !{!"omnipotent char", !3, i64 0}
!3 = !{!"Simple C/C++ TBAA"}
!4 = !{!5, !5, i64 0}
!5 = !{!"p1 _ZTS9list_head", !6, i64 0}
!6 = !{!"any pointer", !2, i64 0}
```

```
$ opt -O3 -disable-output reduced.ll
opt: llvm/lib/Transforms/Utils/LoopSimplify.cpp:709: bool llvm::simplifyLoop(Loop *, DominatorTree *, LoopInfo *, ScalarEvolution *, AssumptionCache *, MemorySSAUpdater *, bool): Assertion `L->isRecursivelyLCSSAForm(*DT, *LI) && "Requested to preserve LCSSA, but it's already broken."' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: opt -O3 -disable-output reduced.ll
1.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,chr,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-verify-fixpoint>,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "reduced.ll"
2.	Running pass "loop-unroll<O3>" on function "process_deferred_bios"
 #0 0x000055d7ff4ccd38 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (opt+0x1c78d38)
 #1 0x000055d7ff4ca2e5 llvm::sys::RunSignalHandlers() (opt+0x1c762e5)
 #2 0x000055d7ff4cddd1 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007ff4fec4def0 (/usr/lib/libc.so.6+0x3def0)
 #4 0x00007ff4feca774c (/usr/lib/libc.so.6+0x9774c)
 #5 0x00007ff4fec4ddc0 raise (/usr/lib/libc.so.6+0x3ddc0)
 #6 0x00007ff4fec3557a abort (/usr/lib/libc.so.6+0x2557a)
 #7 0x00007ff4fec354e3 __assert_perror_fail (/usr/lib/libc.so.6+0x254e3)
 #8 0x000055d7ffc1556d (opt+0x23c156d)
 #9 0x000055d800935935 llvm::UnrollLoop(llvm::Loop*, llvm::UnrollLoopOptions, llvm::LoopInfo*, llvm::ScalarEvolution*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::TargetTransformInfo const*, llvm::OptimizationRemarkEmitter*, bool, llvm::Loop**, llvm::AAResults*) (opt+0x30e1935)
#10 0x000055d80092aa25 tryToUnrollLoop(llvm::Loop*, llvm::DominatorTree&, llvm::LoopInfo*, llvm::ScalarEvolution&, llvm::TargetTransformInfo const&, llvm::AssumptionCache&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, bool, int, bool, bool, bool, std::optional<unsigned int>, std::optional<unsigned int>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<bool>, std::optional<unsigned int>, llvm::AAResults*) LoopUnrollPass.cpp:0:0
#11 0x000055d80092b307 llvm::LoopUnrollPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (opt+0x30d7307)
#12 0x000055d800c9ebbd llvm::detail::PassModel<llvm::Function, llvm::LoopUnrollPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilderPipelines.cpp:0:0
#13 0x000055d7ff7111c7 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (opt+0x1ebd1c7)
#14 0x000055d80084b1ad llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) X86CodeGenPassBuilder.cpp:0:0
#15 0x000055d7ff715c71 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (opt+0x1ec1c71)
#16 0x000055d80084b31d llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) X86CodeGenPassBuilder.cpp:0:0
#17 0x000055d7ff70ff87 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (opt+0x1ebbf87)
#18 0x000055d800c3f544 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (opt+0x33eb544)
#19 0x000055d7ff4a3c7d optMain (opt+0x1c4fc7d)
#20 0x00007ff4fec376b5 (/usr/lib/libc.so.6+0x276b5)
#21 0x00007ff4fec37769 __libc_start_main (/usr/lib/libc.so.6+0x27769)
#22 0x000055d7ff49d125 _start (opt+0x1c49125)
```

https://github.com/llvm/llvm-project/pull/147824


More information about the llvm-commits mailing list