A bad loop/alias bug

H.J. Lu hjl@lucon.org
Mon Jun 29 16:22:00 GMT 1998


Hi,

Here is the update on the alias bug reported earlier. It turned out
to be loop related. Here is a simpler test case.

The problem is in invariant_p () in loop.c. Before loop optimization,
we have

(insn 33 30 36 (set (mem:DI (plus:SI (reg:SI 6 %ebp)
                (const_int -8)))
        (reg:DI 31)) 84 {movdi+1} (nil)
    (nil))

(insn 36 33 38 (set (reg:SI 32)
        (plus:SI (reg:SI 6 %ebp)
            (const_int -8))) 142 {addsi3+1} (nil)
    (nil))

(insn 38 36 39 (set (reg:SI 34)
        (mem/s:SI (plus:SI (reg:SI 32)
                (const_int 4)))) 53 {movsi+2} (nil)
    (nil))

When invariant_p is called on

(mem/s:SI (plus:SI (reg:SI 32)
        (const_int 4)))

from loop_optimize around line 537 in loop.c, it calls true_dependence
to see if

(mem/s:SI (plus:SI (reg:SI 32)
        (const_int 4)))

reads

(mem:DI (plus:SI (reg:SI 6 %ebp)
        (const_int -8)))

Unfortunately, true_dependence doesn't know (reg:SI 32) has

(plus:SI (reg:SI 6 %ebp)
         (const_int -8))

As the result, loop_optimize generates buggy codes. I don't know what
the best solution is. But it seems that loop_optimize should have info
on what is in each register so that invariant_p can do a better job.

Thanks.



-- 
H.J. Lu (hjl@gnu.org)
---
long A [2] = {0};
long B [2] = {2, 0};

main ()
{
  unsigned int i;
  long long u;
  for (i = 0; i < 2; i+=2)
  {
    u = A [i] + B [i];
    u = (long long) (*(((long *)&( u ))+1)) + A [i+1] + B [i+1];
    A [i+1] = (long) u;
  }
  if (A [1] != 0)
    abort ();
  return 0;
}



More information about the Gcc-bugs mailing list