[llvm] [DA] Add initial support for monotonicity check (PR #162280)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 15 10:27:08 PDT 2025
kasuga-fj wrote:
> > Notably, it is still unclear whether we should also have a category for unsigned monotonicity
>
> In the loop below [...] This is not a correctness issue, and I am not sure if there will be any realistic performance issue caused by this or not. But I thought to bring it up.
It is one of the largest issue in the current implementation. A simpler case like below cannot be handled well, since `N` can be larger than `INT64_MAX`.
```c
for (size_t i = 0; i < N; i++)
A[i] = 0;
```
> Talking about performance impact of monotonicity check, the example that I gave before is more concerning:
>
> ```
> for (long int i = 0; i < 10; i++) {
> for (long int j = 0; j < 10; j++) {
> for (long int k = 0; k < 10; k++) {
> for (long int l = 0; l < 10; l++)
> A[i][j][k][l] = i;
> }
> for (long int k = 1; k < 11; k++) {
> for (long int l = 0; l < 10; l++)
> A[i + 4][j + 3][k + 2][l + 1] = l;
>
> Printing analysis 'Dependence Analysis' for function 'samebd0':
> Monotonicity check:
> Inst: store i64 %i.013, ptr %arrayidx12, align 8
> Expr: {{{{0,+,8000000}<nuw><nsw><%for.cond1.preheader>,+,80000}<nuw><nsw><%for.cond4.preheader>,+,800}<nuw><nsw><%for.cond7.preheader>,+,8}<nuw><nsw><%for.body9>
> Monotonicity: MultiSignedMonotonic
> Inst: store i64 %l17.04, ptr %arrayidx24, align 8
> Expr: {{{{32242408,+,8000000}<nuw><nsw><%for.cond1.preheader>,+,80000}<nw><%for.cond4.preheader>,+,800}<nuw><nsw><%for.cond18.preheader>,+,8}<nuw><nsw><%for.body20>
> Monotonicity: Unknown
> Reason: {{32242408,+,8000000}<nuw><nsw><%for.cond1.preheader>,+,80000}<nw><%for.cond4.preheader>
> ```
>
> loops like this are common in fortran programs. We probably need to look into this and if the missing flag is not a bug then the question is how we can safely check dependency for this?
>
> I don't think this issue prevents us from merging this patch, since this is currently the best solution that we know to address some correctness issues. But anyways, this should be investigated. I think we can do at least an initial investigation on our end.
I haven’t looked into the details of how nowrap flags are inferred in SCEV, but I guess SCEV fails to prove that the second store is executed unconditionally. In fact, inserting a conditional branch before the first store (like [this](https://godbolt.org/z/GM7Gcf6d6)) also causes the nowrap flag to be dropped from the SCEV for the first store and the monotonicity check fails.
Regardless of the cause, I think it should be handled on the DA side. In this specific case, all the variables involved, except for the induction variables, are constants, so I believe it shouldn’t be too difficult to prove that they don’t wrap. Just holding a possible minimum/maximum value while checking `nsw` flag recursively should be enough.
https://github.com/llvm/llvm-project/pull/162280
More information about the llvm-commits
mailing list