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