[backport gcc-4.7/trunk r182500 ] From: Richard Sandiford Subject: Invalid hard-reg decomposition in lower-subreg Date: Sat, 17 Dec 2011 11:26:11 +0000 List-Archive: 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/ 2011-12-19 Richard Sandiford * lower-subreg.c (can_decompose_p): Check every word of a hard register. --- gcc-4.6.2/gcc/lower-subreg.c.~1~ 2011-01-03 21:52:22.000000000 +0100 +++ gcc-4.6.2/gcc/lower-subreg.c 2011-12-27 12:57:09.000000000 +0100 @@ -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); }