lower-subreg.c:can_decompose_p uses the following condition to test
whether a multiword hard register can be decomposed into words:
return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD)
&& HARD_REGNO_MODE_OK (regno, word_mode));
This doesn't work reliably on MIPS, where a doubleword HI-LO value
cannot be split into independent HI and LO words; the LO word is OK,
but the HI word isn't. This means that the test works correctly
on big-endian targets, where the invalid HI case comes first,
but not on little-endian ones, where the valid LO one does.
This endian difference is the cause of the mips-sde-elf build failure
that Maciej reported earlier in the week. Tested on that target and
on x86_64-linux-gnu. OK to install?
Richard
gcc/
* lower-subreg.c (can_decompose_p): Check every word of a hard
register.
Index: gcc/lower-subreg.c
===================================================================
--- gcc/lower-subreg.c 2011-12-14 20:44:42.000000000 +0000
+++ gcc/lower-subreg.c 2011-12-14 21:04:09.000000000 +0000
@@ -634,8 +634,15 @@ can_decompose_p (rtx x)
unsigned int regno = REGNO (x);
if (HARD_REGISTER_NUM_P (regno))
- return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD)
- && HARD_REGNO_MODE_OK (regno, word_mode));
+ {
+ unsigned int byte, num_bytes;
+
+ num_bytes = GET_MODE_SIZE (GET_MODE (x));
+ for (byte = 0; byte < num_bytes; byte += UNITS_PER_WORD)
+ if (simplify_subreg_regno (regno, GET_MODE (x), byte, word_mode) <
0)
+ return false;
+ return true;
+ }
else
return !bitmap_bit_p (subreg_context, regno);
}