Issue 202383
Summary [LoopInterchange] Miscompilation when the inner induction step depends on the outer induction variable
Labels miscompilation, loopoptim
Assignees kasuga-fj
Reporter kasuga-fj
    ```llvm
; for (i = 1; i < 8; i++)
;   for (j = 0, k = 0; k < 16 + i; j++, k += i)
; A[8*j + i] += 1;

@A = global [256 x i64] zeroinitializer

define void @f(ptr %A) {
entry:
  br label %outer.header

outer.header:
  %i = phi i64 [ 1, %entry ], [ %i.next, %outer.latch ]

inner.header:
  %j = phi i64 [ 0, %outer.header ], [ %j.next, %inner.latch ]   ; clean address IV
  %k = phi i64 [ 0, %outer.header ], [ %k.next, %inner.latch ]   ; trip IV, step = %i
  br label %body

body:
  %jx8 = mul nsw nuw i64 %j, 8
  %idx = add nsw nuw i64 %jx8, %i
  %gep = getelementptr inbounds i64, ptr %A, i64 %idx
 %old = load i64, ptr %gep
  %new = add i64 %old, 1
  store i64 %new, ptr %gep
  %j.next = add nuw nsw i64 %j, 1
  %k.next = add nuw nsw i64 %k, %i ; outer-IV-dependent step => trapezoidal
  br label %inner.latch

inner.latch:
  %cond = icmp slt i64 %k, 16             ; bare CmpInst on an inner induction
  br i1 %cond, label %inner.header, label %inner.exit

inner.exit:
  br label %outer.latch

outer.latch:
 %i.next = add nuw nsw i64 %i, 1
  %cmp.i = icmp slt i64 %i.next, 8
  br i1 %cmp.i, label %outer.header, label %exit

exit:
  ret void
}

define i32 @main() {
entry:
  call void @f(ptr @A)
  br label %loop

loop:
 %m = phi i64 [ 0, %entry ], [ %m.next, %loop ]
  %acc = phi i64 [ 0, %entry ], [ %acc.next, %loop ]
  %g = getelementptr inbounds [256 x i64], ptr @A, i64 0, i64 %m
  %v = load i64, ptr %g
  %acc3 = mul i64 %acc, 31
 %acc.next = add i64 %acc3, %v
  %m.next = add i64 %m, 1
  %c = icmp slt i64 %m.next, 256
  br i1 %c, label %loop, label %done

done:
  %r = trunc i64 %acc.next to i32
  %r2 = and i32 %r, 65535
  ret i32 %r2
}
```

```console
$ lli repro.ll
$ echo $?
143
$ opt --passes=loop-interchange --loop-interchange-profitabilities=ignore repro.ll -S -o tmp.ll
$ lli tmp.ll
$ echo $?
132
```

Analysis by Claude Code (not checked carefully, but looks plausible):

> The inner loop's trip count depends on the outer induction variable, because the inner IV `%k` used in the latch has a step (`%k.next = %k + %i`) that is the outer IV. The nest is trapezoidal, but `loop-interchange` treats it as rectangular and interchanges it, changing
the result.

Disclosure: The test case is generated by AI

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to