[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