Closed
Description
int printf(const char *, ...);
__int128 a = 3, c;
char b;
int main() {
c = 3;
for (; c >= 0; c--) {
b = 0;
for (; b <= 3; b++) {
if (c)
break;
a = 0;
}
}
printf("%d\n", (int)a);
}
clang -march=z15 -O1 wrong0.i -o a.out
This program should print '0' as 'a' is set to zero inside the loop. It now prints '3' instead. A bisect leads to a recent commit: 79af689 " [SCEV] Handle more adds in computeConstantDifference() (#101339)".
Seems like IndVarSimplify has gone wrong with an i128:
GOOD <> BROKEN
; *** IR Dump After IndVarSimplifyPass on loo ; *** IR Dump After IndVarSimplifyPass on loo
; Preheader: ; Preheader:
entry: entry:
br label %for.cond1.preheader br label %for.cond1.preheader
; Loop: ; Loop:
for.cond1.preheader: for.cond1.preheader:
%storemerge11 = phi i128 [ 3, %entry ], [ % %storemerge11 = phi i128 [ 3, %entry ], [ %
%tobool = icmp ne i128 %storemerge11, 0 | br i1 true, label %for.inc5, label %if.end.
br i1 %tobool, label %for.inc5, label %if.e <
if.end.lr.ph: if.end.lr.ph:
store i128 0, ptr @a, align 8, !tbaa !4 store i128 0, ptr @a, align 8, !tbaa !4
br label %if.end br label %if.end
if.end: if.end:
%storemerge89 = phi i8 [ 0, %if.end.lr.ph ] %storemerge89 = phi i8 [ 0, %if.end.lr.ph ]
%inc = add nuw nsw i8 %storemerge89, 1 %inc = add nuw nsw i8 %storemerge89, 1
%cmp2 = icmp ugt i8 %storemerge89, 2 %cmp2 = icmp ugt i8 %storemerge89, 2
%or.cond = or i1 %tobool, %cmp2 | %or.cond = or i1 true, %cmp2
br i1 %or.cond, label %for.inc5.loopexit, l br i1 %or.cond, label %for.inc5.loopexit, l
for.inc5: for.inc5:
%storemerge8.lcssa = phi i8 [ 0, %for.cond1 %storemerge8.lcssa = phi i8 [ 0, %for.cond1
%dec = add nsw i128 %storemerge11, -1 %dec = add nsw i128 %storemerge11, -1
%cmp = icmp ugt i128 %storemerge11, 0 %cmp = icmp ugt i128 %storemerge11, 0
br i1 %cmp, label %for.cond1.preheader, lab br i1 %cmp, label %for.cond1.preheader, lab
for.inc5.loopexit: for.inc5.loopexit:
%inc.lcssa = phi i8 [ %inc, %if.end ] %inc.lcssa = phi i8 [ %inc, %if.end ]
br label %for.inc5 br label %for.inc5
; Exit blocks ; Exit blocks
for.end6: for.end6:
%storemerge8.lcssa.lcssa = phi i8 [ %storem %storemerge8.lcssa.lcssa = phi i8 [ %storem
store i128 -1, ptr @c, align 8, !tbaa !4 store i128 -1, ptr @c, align 8, !tbaa !4
store i8 %storemerge8.lcssa.lcssa, ptr @b, store i8 %storemerge8.lcssa.lcssa, ptr @b,
%0 = load i128, ptr @a, align 8, !tbaa !4 %0 = load i128, ptr @a, align 8, !tbaa !4
%conv7 = trunc i128 %0 to i32 %conv7 = trunc i128 %0 to i32
%call = call signext i32 (ptr, ...) @printf %call = call signext i32 (ptr, ...) @printf
ret i32 0 ret i32 0