------- Additional Comments From aoliva at gcc dot gnu dot org  2005-04-12 
06:58 -------
Subject: Re: [PR target/20126, RFC] loop DEST_ADDR biv replacement may fail

On Apr 12, 2005, Alexandre Oliva <[EMAIL PROTECTED]> wrote:

> On Apr 11, 2005, Josh Conner <[EMAIL PROTECTED]> wrote:
>> I'm now getting a ICE building the mainline (please ignore the
>> "3.4.3" in the directory structure, it's a holdover from the build
>> scripts I'm using) that appears to be related to this patch.

> That sounds possible.  The patch might indeed have the effect of
> turning previously-silent miscompilations into ICEs.  I didn't expect
> we'd get any, but you may be proving me wrong.  Would you please send
> me the preprocessed testcase in private, or just confirm that you're
> using newlib as the C library?  I'll then try to duplicate the problem
> on one of the platforms at my disposal.

I went ahead and tried to build an arm-elf toolchain out of uberbaum,
and got the problem.

The problem was an stmia instruction in a loop, whose base address
pseudo loop wanted to replace with another pseudo plus a constant.
Since there's a requirement that all of the base addresses match, when
we started replacing the address expressions of any of the
destinations other than the first, that didn't have an offset, the
insn failed to match, and none of the work arounds I introduced for
such a replacement failure succeeded.

The only relatively simple way to overcome this error I could think of
was to introduce yet another work around, to enable us to handle not
only REGs, but also PLUS involving a REG and a constant (very likely
a literal immediate, but I didn't introduce such a requirement).

This has enabled the testcase to compile successfully and correctly,
although we generate a total of 4 assignments to the pseudo in
response to the 4 givs detected involving it in the 4-register stmia
instruction.  Not a big deal, since they end up being optimized away.

The bad news is that this is a regression.  The code before my patch
would still work: for some reason I still don't understand, the
assignment of the base pseudo isn't removed, so with my new work
around patch below, we end up introducing unnecessary assignments to
the giv.  They are optimized away, but if I can figure out what the
conditions are in which we don't need to introduce assignments to the
giv, we could simply avoid all the messy new code, that assumes we
absolutely must replace the expression with something else.

Anyhow, here's the patch with the workaround for the problem you ran
into.  I'll submit it formally when it completes testing.

Index: gcc/loop.c
===================================================================
RCS file: /cvs/uberbaum/gcc/loop.c,v
retrieving revision 1.526
diff -u -p -r1.526 loop.c
--- gcc/loop.c 10 Apr 2005 04:00:45 -0000 1.526
+++ gcc/loop.c 12 Apr 2005 06:35:26 -0000
@@ -5488,6 +5488,15 @@ loop_givs_rescan (struct loop *loop, str
            loop_insn_emit_before (loop, 0, v->insn,
                                   gen_move_insn (*v->location,
                                                  v->new_reg));
+         else if (GET_CODE (*v->location) == PLUS
+                  && REG_P (XEXP (*v->location, 0))
+                  && CONSTANT_P (XEXP (*v->location, 1)))
+           loop_insn_emit_before (loop, 0, v->insn,
+                                  gen_move_insn (XEXP (*v->location, 0),
+                                                 gen_rtx_MINUS
+                                                 (GET_MODE (*v->location),
+                                                  v->new_reg,
+                                                  XEXP (*v->location, 1))));
          else
            {
              /* If it wasn't a reg, create a pseudo and use that.  */

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   [EMAIL PROTECTED], gcc.gnu.org}
Free Software Evangelist  [EMAIL PROTECTED], gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20126

Reply via email to