[llvm] [DependenceAnalysis] Extending SIV to handle fusable loops (PR #128782)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 29 13:52:21 PDT 2025


================
@@ -542,10 +619,23 @@ namespace llvm {
     ///     e - 5
     ///     f - 6
     ///     g - 7 = MaxLevels
-    void establishNestingLevels(const Instruction *Src,
-                                const Instruction *Dst);
-
-    unsigned CommonLevels, SrcLevels, MaxLevels;
+    /// SeparateLevels counts the number of levels after common levels that are
+    /// not common but are similar, meaning that they have the same tripcount
+    /// and depth. Assume that in this code fragment, levels c and e are
+    /// similar. In this case only the loop nests at the next level after
+    /// common levels are similar, and SeparateLevel is set to 1.
+    /// If there are similar loop nests, we could use the APIs with considering
+    /// them as fused loops. In that case the level numbers for the previous
+    /// code look like
+    ///     a   - 1
+    ///     b   - 2
+    ///     c,e - 3 = CommonLevels
+    ///     d   - 4 = SrcLevels
+    ///     f   - 5
+    ///     g   - 6 = MaxLevels
----------------
Meinersbur wrote:

This is what I meant. Changing `CommonLevels` temporarily modifies the result of `mapDstLoop`. e, f, and g are mapped to 4,5,6 (instead of 5,6,7). That is, d and e are mapped to the same level (not c,e as your illustration wants to make-believe). When the mapping of `mapDstLoop` changes, indices that formerly pointed to one loop not accesses the data for another. In particular, `Pair[P].Loops` is just being reused without being reset.

The analysis result has to be the same independent of whether fusionable loops have been detected or not. Results that are for loop e will overwrite the result for loop d because `mapDstLoop` maps to the same index into memory. What is the argument for why individual loop analysis results for fusionable loops must be the same, such as `Pair[I].Loops`?

I let you code run over llvm-test-suite. ~1800 compilations are crashing with your patch:
```
/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang -DNDEBUG  -fmax-errors=1 -fuse-ld=lld    -O3 -DNDEBUG   -w -Werror=date-time -Wno-implicit-int -Wno-int-conversion -Wno-implicit-function-declaration -w -MD -MT SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o -MF SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o.d -o SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o -c /home/meinersbur/src/llvm-test-suite/SingleSource/Regression/C/gcc-c-torture/execute/ashrdi-1.c
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: /home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang -DNDEBUG -fmax-errors=1 -fuse-ld=lld -O3 -DNDEBUG -w -Werror=date-time -Wno-implicit-int -Wno-int-conversion -Wno-implicit-function-declaration -w -MD -MT SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o -MF SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o.d -o SingleSource/Regression/C/gcc-c-torture/execute/CMakeFiles/GCC-C-execute-ashrdi-1.dir/ashrdi-1.c.o -c /home/meinersbur/src/llvm-test-suite/SingleSource/Regression/C/gcc-c-torture/execute/ashrdi-1.c
1.      <eof> parser at end of file
2.      Optimizer
3.      Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,chr,print<da>,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 "/home/meinersbur/src/llvm-test-suite/SingleSource/Regression/C/gcc-c-torture/execute/ashrdi-1.c"
4.      Running pass "print<da>" on function "main"
 #0 0x00007f8dee809f02 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x4d9ef02)
 #1 0x00007f8dee806bff llvm::sys::RunSignalHandlers() (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x4d9bbff)
 #2 0x00007f8dee7439c8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f8de9485330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007f8ded7959ac llvm::ScalarEvolution::SimplifyICmpOperands(llvm::CmpPredicate&, llvm::SCEV const*&, llvm::SCEV const*&, unsigned int) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x3d2a9ac)
 #5 0x00007f8ded796b27 llvm::ScalarEvolution::isKnownPredicate(llvm::CmpPredicate, llvm::SCEV const*, llvm::SCEV const*) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x3d2bb27)
 #6 0x00007f8ded5ea3e2 llvm::DependenceInfo::establishNestingLevels(llvm::Instruction const*, llvm::Instruction const*) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x3b7f3e2)
 #7 0x00007f8ded5fbbd1 llvm::DependenceInfo::depends(llvm::Instruction*, llvm::Instruction*, bool) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x3b90bd1)
 #8 0x00007f8ded6027f0 llvm::DependenceAnalysisPrinterPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/meinersbur/src/llvm/flangrt/release_flang_flangrt-bootstrap_openmp-bootstrap/llvm_flang_runtimes/bin/clang+0x3b977f0)
...
```


 Even with those that are not crashing, there are some differences for the non-fusionable analysis. In particular, some `confused` flags are missing:
```diff
 Printing analysis 'Dependence Analysis' for function 'intergroup_score_consweight' in module '/home/meinersbur/src/llvm-test-suite/MultiSource/Benchmarks/mafft/mltaln9.c':
 ...
 Src:  store double %5, ptr %value, align 8, !tbaa !5 --> Dst:  store double %19, ptr %value, align 8, !tbaa !5
-  da analyze - consistent output [S|<]!
+  da analyze - output [S|<]!
```



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


More information about the llvm-commits mailing list