[llvm] [DA] Add option to dump delinearization result in printing analysis (PR #157859)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 05:50:53 PDT 2025
================
@@ -1,10 +1,14 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
-; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
-; RUN: | FileCheck %s
+; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa \
+; RUN: -da-dump-delinearization-result 2>&1 | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv8m.main-arm-none-eabi"
+; FIXME: It seems that we cannot prove that %m * %o doesn't signed wrap in
+; almost all cases. If it wraps, the delinearization result should be
+; discarded, otherwise the result can be incorrect.
+
----------------
kasuga-fj wrote:
After thinking it over for a while, I'm starting to believe that these cases are actually correct, since the load and/or store instructions are executed for every iteration.
For example, `@t1` in DADelin.ll represents a case like the following:
```c
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int k = 0; k < o; k++)
A[i*m*o + j*o + k] = ...;
```
The array access `A[i*m*o + j*o + k]` is delinearized to:
```
Sizes: [Unknown][%m][%o]
Access: %A[{0,+,1}<nsw><%Li>][{0,+,1}<nsw><%Lj>][{0,+,1}<nsw><%Lk>]
```
The potential issue here is; while we check `%m` and `%o` are positive, we don't prove that `%n * %m * %o - 1` cannot signed-wrap. If it wraps, for instance `(%m, %o) = (2^16 - 1, 2^16)` (note: the index type is 32 bits here), then `&(%A[0][0][0]) = &(%A[1][1][0]) = &(%A[2][2][0]) = ...`, which violates the assumption of DependenceAnalysis.
However, in this specific case,
- The store instruction is executed for every iteration of the all loops.
- The corresponding GEP has `nusw`.
- The ranges of each AddRec are as follows:
- `{0,+,1}<%Li>` ranges exactly from 0 to `%n - 1`
- `{0,+,1}<%Lj>` ranges exactly from 0 to `%m - 1`
- `{0,+,1}<%Lk>` ranges exactly from 0 to `%o - 1`
Given the above, in my understanding, if `%n * %m * %o - 1` were to wrap, the GEP would eventually produce poison and trigger UB. Hence we can assume that `%n * %m * %o - 1` doesn't wrap.
In any case, I think this just happens to be correct and DA needs to explicitly check those conditions. I still think there are cases where insufficient validation for delinearization result can lead to wrong outcomes, like the case I added https://github.com/llvm/llvm-project/blob/bbb7ddc1a8d1269c4e529019e7e134ea9e9442fb/llvm/test/Analysis/DependenceAnalysis/DADelin.ll#L781-L859.
https://github.com/llvm/llvm-project/pull/157859
More information about the llvm-commits
mailing list