[PATCH] Fix target/12898 (reload problem on Alpha)

Falk Hueffner falk.hueffner@student.uni-tuebingen.de
Thu Nov 20 14:26:00 GMT 2003


Hi,

This problem causes a bootstrap failure on some Alpha
subarchitectures.

The trouble starts in alpha_emit_set_const:

  /* If we can't make any pseudos, TARGET is an SImode hard register, we
     can't load this constant in one insn, do this in DImode.  */

This is exactly what happens, 32768 needs 2 insns to be emitted.

  if (no_new_pseudos && mode == SImode
      && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
      && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
    {
      target = gen_lowpart (DImode, target);
      mode = DImode;
    }

This creates a paradoxical subreg:

(subreg:DI (reg:SI $15 [129]) 0)

which copy_to_suggested_reg doesn't like, it insists on REG or it will
make a new pseudo:

  if (target && GET_CODE (target) == REG)
    temp = target;
  else
    temp = gen_reg_rtx (mode);

My patch changes copy_to_suggested_reg to recognize paradoxical
subregs and simply copy to the hard reg inside. I'm not certain this
is the right approach, though.

Bootstrapped and tested on alphaev68-unknown-linux-gnu, without ada. I
don't think it is possible to create a sensible test case, since one
needs exactly the right amount of register pressure (e. g. the
original test case would ICE on ev6, but not ev56).

2003-11-20  Falk Hueffner  <falk@debian.org>

        PR target/12898
	* explow.c (copy_to_suggested_reg): Don't create new pseudo for
	paradoxical subregs, but copy into contained hardreg.

Index: explow.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/explow.c,v
retrieving revision 1.117
diff -u -p -r1.117 explow.c
--- explow.c	18 Sep 2003 20:43:04 -0000	1.117
+++ explow.c	20 Nov 2003 13:35:35 -0000
@@ -751,7 +751,13 @@ copy_to_suggested_reg (rtx x, rtx target
 
   if (target && GET_CODE (target) == REG)
     temp = target;
-  else
+  else if (target
+	   && GET_CODE (target) == SUBREG
+	   && GET_CODE (SUBREG_REG (target)) == REG
+	   && (GET_MODE_SIZE (mode)
+	       > GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))))
+    temp = gen_rtx_REG (mode, REGNO (SUBREG_REG (target)));
+  else 
     temp = gen_reg_rtx (mode);
 
   emit_move_insn (temp, x);

-- 
	Falk



More information about the Gcc-patches mailing list