[llvm] [Delinearization] Remove `isKnownNonNegative` (PR #171817)

Ryotaro Kasuga via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 11 11:34:54 PST 2025


kasuga-fj wrote:

The original commit is incorrect. To prove an addrec doesn't wrap by using `inbounds`, we need to prove that the GEP and some load/store using its result are executed for every iteration of the loop (see also [LAA's code](https://github.com/llvm/llvm-project/blob/8d59cca1ab9cf4e39e43bf695e415de9ccd41115/llvm/lib/Analysis/LoopAccessAnalysis.cpp#L1031-L1048)). For example, the following IR is valid and `%add` can be negative if `%N` is large enough.

```llvm
; for (i = 0; i < N; i++)
;   for (j = 0; j < N; j++) {
;     offset = i * N + j;
;     if (offset == -1)
;       A[offset] = 1;
;   }
;
; If N == UINT32_MAX, then the store will be executed when (i, j) = (1, 0), (2, 1), (3, 2), ...
define void @nonnegative(ptr nocapture %A, i32 %N) {
entry:
  %cmp44 = icmp eq i32 %N, 0
  br i1 %cmp44, label %exit, label %for.outer

for.outer:
  %h.045 = phi i32 [ %add19, %for.latch ], [ 0, %entry ]
  %mul = mul i32 %h.045, %N
  br label %for.inner.header

for.inner.header:
  %i.043 = phi i32 [ 0, %for.outer ], [ %add16, %for.inner.latch ]
  %add = add i32 %i.043, %mul
  %cond = icmp eq i32 %add, -1
  br i1 %cond, label %if.then, label %for.inner.latch

if.then:
  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %add
  store i32 1, ptr %arrayidx, align 4
  br label %for.inner.latch

for.inner.latch:
  %add16 = add nuw i32 %i.043, 1
  %exitcond46 = icmp eq i32 %add16, %N
  br i1 %exitcond46, label %for.latch, label %for.inner.header

for.latch:
  %add19 = add nuw i32 %h.045, 1
  %exitcond47 = icmp eq i32 %add19, %N
  br i1 %exitcond47, label %exit, label %for.outer

exit:
  ret void
}
```


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


More information about the llvm-commits mailing list