Closed
Description
This program should print -86:
int printf(const char *, ...);
unsigned short a = 0, b = 0;
unsigned __int128 c = 0, d = 0;
unsigned char e(unsigned char f, unsigned char g) { return f + g; }
long h() {
for (; c != 2; c = e(c, 3)) {
--d;
if (d)
continue;
return a;
}
return b;
}
int main() {
h();
printf("%d\n", (int)d);
}
With the option -replexitval=always, the IndVarSimplifyPass does something quite weird that I don't understand. It seems it is trying to compute the final value that is stored in the preheader, but that computation is '0', so it must be wrong.
clang -O3 -march=z15 wrong0.i -o ./a.out <> clang -O3 -march=z15 wrong0.i -o ./a.out -mllvm -replexitval=always
IR Dump After IndVarSimplifyPass on for.body
define dso_local i64 @h() local_unnamed_addr #1 { define dso_local i64 @h() local_unnamed_addr #1 {
entry: entry:
%.pr = load i128, ptr @c, align 8, !tbaa !4 %.pr = load i128, ptr @c, align 8, !tbaa !4
%d.promoted = load i128, ptr @d, align 1, !tbaa !4 %d.promoted = load i128, ptr @d, align 1, !tbaa !4
%cmp.not5 = icmp eq i128 %.pr, 2 %cmp.not5 = icmp eq i128 %.pr, 2
%extract.t9 = trunc i128 %.pr to i8 %extract.t9 = trunc i128 %.pr to i8
br i1 %cmp.not5, label %return, label %for.body.prehea br i1 %cmp.not5, label %return, label %for.body.prehea
for.body.preheader: ; pred for.body.preheader: ; pred
> %0 = add i128 %d.promoted, -1
> %1 = mul i8 %extract.t9, 85
> %2 = add i8 %1, 85
> %3 = zext i8 %2 to i128
> %umin = call i128 @llvm.umin.i128(i128 %0, i128 %3)
> %4 = sub i128 %0, %umin
br label %for.body br label %for.body
for.body: ; pred for.body: ; pred
%.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, % %.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, %
%dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, % %dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, %
%dec = add i128 %dec46, -1 %dec = add i128 %dec46, -1
%tobool.not = icmp eq i128 %dec, 0 %tobool.not = icmp eq i128 %dec, 0
br i1 %tobool.not, label %for.body.return_crit_edge, l br i1 %tobool.not, label %for.body.return_crit_edge, l
for.inc: ; pred for.inc: ; pred
%add.i = add i8 %.off0, 3 %add.i = add i8 %.off0, 3
%conv2 = zext i8 %add.i to i128 %conv2 = zext i8 %add.i to i128
store i128 %conv2, ptr @c, align 8, !tbaa !4 store i128 %conv2, ptr @c, align 8, !tbaa !4
%cmp.not = icmp eq i8 %add.i, 2 %cmp.not = icmp eq i8 %add.i, 2
br i1 %cmp.not, label %for.cond.return_crit_edge, labe br i1 %cmp.not, label %for.cond.return_crit_edge, labe
for.cond.return_crit_edge: ; pred for.cond.return_crit_edge: ; pred
%dec.lcssa10 = phi i128 [ %dec, %for.inc ] | store i128 %4, ptr @d, align 8, !tbaa !4
store i128 %dec.lcssa10, ptr @d, align 8, !tbaa !4 <
br label %return br label %return
for.body.return_crit_edge: ; pred for.body.return_crit_edge: ; pred
%dec.lcssa = phi i128 [ %dec, %for.body ] | store i128 %4, ptr @d, align 8, !tbaa !4
store i128 %dec.lcssa, ptr @d, align 8, !tbaa !4 <
br label %return br label %return
return: ; pred return: ; pred
%retval.0.in.in = phi ptr [ @a, %for.body.return_crit_ %retval.0.in.in = phi ptr [ @a, %for.body.return_crit_
%retval.0.in = load i16, ptr %retval.0.in.in, align 2, %retval.0.in = load i16, ptr %retval.0.in.in, align 2,
%retval.0 = zext i16 %retval.0.in to i64 %retval.0 = zext i16 %retval.0.in to i64
ret i64 %retval.0 ret i64 %retval.0
} }
;
Metadata
Metadata
Assignees
Type
Projects
Status
Done