loop.c overflow problem
Herman ten Brugge
Haj.Ten.Brugge@net.HCC.nl
Mon Oct 19 22:17:00 GMT 1998
Hello,
I found a problem in loop.c. The torture test loop-2d.c failed for the
c4x and m68k target. This test program looks like:
int a[2];
f (b)
{
unsigned int i;
int *p;
for (p = &a[b], i = b; --i < ~0; )
*--p = i * 3 + (int)a;
}
main ()
{
a[0] = a[1] = 0;
f (2);
if (a[0] != (int)a || a[1] != (int)a + 3)
abort ();
exit (0);
}
When compiled for the c4x target with '-m30 -O2' options the function f is
compiled wrong. The same problem is present on the m68k target when compiling
with -O2 -m68000. Perhaps more targets are effected.
The assembly code for the c4x is below.
.sect ".const"
LC0:
.word _a
LC1:
.word _a-6 ; 0081cd508h
.text
.global _f
_f:
ldiu ar2,r0 - ar2 = input value = b
ldp @LC0
ldiu @LC0,r2 - r2 = _a
addi3 r2,r0,ar0 - ar0 = _a + b
ldiu r0,r1 - r1 = b
addi -1,r1 - r1 = b-1
cmpi -2,r1 - correct test for exit loop
retshi (~Carry and ~Zero=unsigned compare)
ldiu r1,r0 - r0 = b-1
ash 1,r0 - r0 = (b-1) << 1
addi3 r1,r0,r1 - r0 = (b-1)*3
addi3 r2,r1,r0 - r0 = _a + (b-1)*3
ldp @LC1
ldiu @LC1,r1 - load _a-6 into r1
L5:
sti r0,*--ar0 - store value r0 into --ar0
addi -3,r0 - r0 = r0 - 3
cmpi3 r1,r0 - test for end
retshi - incorrect test for exit loop
br L5
The loop is optimized by eliminating i out of the loop. Instead the
variable a is used as exit test. The problem is that the compare
instruction does not work correctly now. The loop is only executed once
instead of twice. The problem starts when the final compare instruction:
cmp -2,biv->regno
is replaced by:
cmp -2*3+_a,biv->new_reg
-2 = arg
3 = mult_val
_a = add_val
This is not correct because the -2 is an unsigned value. It should read
0xfffffffe. This causes an overflow. I found the location of the problem
in loop.c. I just turned it off with the patch below.
Some one with more knoledge off biv/giv stuff can probably do a better job.
1998-10-05 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
* loop.c (maybe_eliminate_biv_1): Disable constant mulval plus
register addval due to possible overflow.
--- loop.c.org Fri Oct 2 23:03:27 1998
+++ loop.c Mon Oct 5 20:52:07 1998
@@ -7398,7 +7394,8 @@ maybe_eliminate_biv_1 (x, insn, bl, elim
&& (GET_CODE (v->add_val) == SYMBOL_REF
|| GET_CODE (v->add_val) == LABEL_REF
|| GET_CODE (v->add_val) == CONST
- || (GET_CODE (v->add_val) == REG
+ /* Turn this off due to possible overflow. */
+ || (0 && GET_CODE (v->add_val) == REG
&& REGNO_POINTER_FLAG (REGNO (v->add_val))))
&& ! v->ignore && ! v->maybe_dead && v->always_computable
&& v->mode == mode)
--
-------------------------------------------------------------------------
Herman ten Brugge Email: Haj.Ten.Brugge@net.HCC.nl
More information about the Gcc-bugs
mailing list