This is the mail archive of the
mailing list for the GCC project.
Re: fix rtl/23560
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 11 Aug 2006 16:35:31 +0200
- Subject: Re: fix rtl/23560
- References: <20050826071451.GA9898@redhat.com>
> Yet another rtl strength reduction bug.
> This time, ivopts transforms the loop and creates an unsigned counter
> that runs from -7u to +7u. Odd, but certainly legal. In the middle,
> there's a conditional that's transformed from (i == 8 || i == 9) to
> (ivtmp <= 1). Also fine.
> Well, rtl-loop comes along and tries to eliminate the ivtmp biv with
> a giv that's a pointer value. Except after the transformation to the
> giv, the LEU comparison is incorrect.
I've run into another variant (PR rtl-optimization/28386): ivtmp runs from
-127u to 127u and the test is ivtmp <= 127u:
unsigned int ivtmp.34;
a = g;
j = 0;
ivtmp.34 = 0ffffff81;
if (ivtmp.34 <= 127) goto <L4>; else goto <L5>;
D.1323 = (int) ivtmp.34;
D.1324 = s[D.1323];
a = (char) (int) D.1324;
j = j + 1;
ivtmp.34 = ivtmp.34 + 1;
if (ivtmp.34 != 128) goto <L3>; else goto <L12>;
> Solved by not allowing this transformation unless the biv can be shown
> to not wrap.
That matches the comment in the code:
/* Unless we're dealing with an equality comparison, if we can't
determine that the original biv doesn't wrap, then we must not
apply the transformation. */
/* ??? Actually, what we must do is verify that the transformed
giv doesn't wrap. But the general case of this transformation
was disabled long ago due to wrapping problems, and there's no
point reviving it this close to end-of-life for loop.c. The
only case still enabled is known (via the check on add_val) to
be pointer arithmetic, which in theory never overflows for
valid programs. */
But that doesn't match the code:
case EQ: case NE:
case GT: case GE: case GTU: case GEU:
case LT: case LE: case LTU: case LEU:
/* See if either argument is the biv. */
if (XEXP (x, 0) == reg)
arg = XEXP (x, 1), arg_operand = 1;
else if (XEXP (x, 1) == reg)
arg = XEXP (x, 0), arg_operand = 0;
if (code != EQ && code != NE
&& biased_biv_may_wrap_p (loop, bl, INTVAL (arg)))
The code tests that the biased biv doesn't wrap, which is true in my case so
the biv is wrongly eliminated to a non-wrapping pointer giv.
I think this illustrates that the bias doesn't play any role in the matter: a
biv that wraps cannot be eliminated if it is subject to any comparisons other
than equality or inequality because the wrapping threshold cannot be shifted.
What do you think? Thanks in advance.