possible gcse failure: not able to eliminate redundant loads
Sanjiv Kumar Gupta, Noida
sanjivg@noida.hcltech.com
Wed Dec 11 03:27:00 GMT 2002
Following code snippet demonstrates the problem.
void func (double *a, double *b, int i)
{
b[2] = a[1];
for (i ; i < 3; i = i + 8)
{
a[4] = a[1];
}
}
for -O2 -fno-argument-alias, I am getting multiple loads for a[1].
_func:
mov.l r14,@-r15
mov r15,r14
add #16,r5
mov r4,r2
add #8,r2
fmov.s @r2+,fr3 --> loading a[1] here
fmov.s @r2,fr2
add #-4,r2
add #4,r5
fmov.s fr2,@r5
mov #2,r1
cmp/gt r1,r6
bt/s .L9
fmov.s fr3,@-r5
add #32,r4
.L6:
fmov.s @r2+,fr3 --> loading a[1] here again //
problem.
fmov.s @r2,fr2
add #-4,r2
add #4,r4
fmov.s fr2,@r4
add #8,r6
cmp/gt r1,r6
bf/s .L6
fmov.s fr3,@-r4
.L9:
mov r14,r15
rts
mov.l @r15+,r14
with -fno-argument-alias GCC knows that b[2] and a[1] do not alias, so
store into b[2] is not invalidating the loaded value of a[1]. Hence
it should have used the previously loaded value of a[1] inside the for loop
instead of reloading it.
The above assembly listing is for sh-elf, but this problem might be there
for other targets too. Enabling store_motion code in gcse.c and
using -O3 -fgcse-lm -fgcse-sm don't help either.
However, it behaves perfectly fine for following
void func (double *a, double *b, int i)
{
b[2] = a[1];
if (i < 3)
{
a[4] = a[1];
}
}
Here, we do not get extra loads for a[1].
Can somebody please help me knowing what is happening here?
--Sanjiv
More information about the Gcc
mailing list