| 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