diff mbox

Invalid hard-reg decomposition in lower-subreg

Message ID 87hb0zo2wc.fsf@firetop.home
State New
Headers show

Commit Message

Richard Sandiford Dec. 17, 2011, 11:26 a.m. UTC
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.

Comments

Eric Botcazou Dec. 18, 2011, 12:33 p.m. UTC | #1
> 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.

OK everywhere.
Richard Sandiford Dec. 19, 2011, 9:20 p.m. UTC | #2
Eric Botcazou <ebotcazou@adacore.com> writes:
>> 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.
>
> OK everywhere.

Thanks.  For the record, I just applied it to trunk for now.  I don't
yet know of a specific case that it fixes in a release branch, but I'll
backport it if I find one.

Richard
diff mbox

Patch

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);
     }