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