Description
Bugzilla Link | 48200 |
Version | trunk |
OS | Linux |
Attachments | reduced testcase, reduced testcase |
CC | @atrick,@fhahn,@hfinkel,@arsenm,@JonPsson,@uweigand |
Extended Description
This program:
int a[] = {0, 6, 0, 0, 6, 0, 0};
int b = 0, d, e;
int c[28];
int main() {
for (; b <= 6; b++) {
d = 0;
for (; d <= 3; d++) {
for (;;) {
c[d * 3] = 10;
break;
}
c[b] = a[b];
}
}
for (e = 0; e < 7; e++)
printf("%d\n", c[e]);
}
is incorrectly compiled with
clang -O3 -target s390x-linux-gnu -march=arch13 -o a.out -w -mllvm -disable-licm-promotion -mllvm -stress-ivchain
On thing that is a bit odd is the computation of the address to @c:
%uglygep = getelementptr i8, i8* %lsr.iv245, i64 sub (i64 ptrtoint ([28 x i32]* @c to i64), i64 ptrtoint ([7 x i32]* @a to i64))
%lsr.iv245 is the address of @a, and then @c - @a is used to get an address into @c. I suppose this means that if @c is declared after @a in the source file, the difference of their addresses can be used in this way, or?
It seems then that the problem is with the post-RA machine scheduler, where the underlying objects are not correctly identified. This instruction uses that GEP:
STMux %15:grx32bit, %31:addr64bit, 0, %19:addr64bit :: (store 4 into %ir.uglygep6, !tbaa !2)
but do not give @a and @c as underlying objects. Instead, the search just goes up through %lsr.iv245. The second sub of the two ptrtoint:s seems to be ignored.
I wonder:
- is LSR emitting correct code here?
- If so, should we handle this case in getUnderlyingObjectsForInstr(), or should instead the memory operand be dropped and by that make MI alias with everything?
%lsr.iv2 = phi [7 x i32]* [ %5, %for.cond1.preheader ], [ %scevgep1, %for.cond1.preheader.preheader ]
%lsr.iv = phi i32 [ %lsr.iv.next, %for.cond1.preheader ], [ %2, %for.cond1.preheader.preheader ]
%indvars.iv = phi i64 [ %0, %for.cond1.preheader.preheader ], [ %indvars.iv.next, %for.cond1.preheader ]
%lsr.iv24 = bitcast [7 x i32]* %lsr.iv2 to i32*
%lsr.iv245 = bitcast i32* %lsr.iv24 to i8*
%3 = load i32, i32* %lsr.iv24, align 4, !tbaa !2
store i32 10, i32* getelementptr inbounds ([28 x i32], [28 x i32]* @c, i64 0, i64 0), align 4, !tbaa !2
store i32 10, i32* getelementptr inbounds ([28 x i32], [28 x i32]* @c, i64 0, i64 3), align 4, !tbaa !2
store i32 10, i32* getelementptr inbounds ([28 x i32], [28 x i32]* @c, i64 0, i64 6), align 4, !tbaa !2
store i32 10, i32* getelementptr inbounds ([28 x i32], [28 x i32]* @c, i64 0, i64 9), align 4, !tbaa !2
%uglygep = getelementptr i8, i8* %lsr.iv245, i64 sub (i64 ptrtoint ([28 x i32]* @c to i64), i64 ptrtoint ([7 x i32]* @a to i64))
%uglygep6 = bitcast i8* %uglygep to i32*
store i32 %3, i32* %uglygep6, align 4, !tbaa !2
All the stores alias with @c, but the last one is not recognized to do so.
llc -mcpu=arch13 -O3 wrong0.ll -stress-ivchain -o -