diff mbox

Fix extract_fixed_bit_field (PR middle-end/49029)

Message ID 20110518123354.GI17079@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek May 18, 2011, 12:33 p.m. UTC
Hi!

The attached testcase ICEs on arm, because extract_fixed_bit_field
with tmode SImode (and SImode non-NULL target) decides to use DImode for
the signed shifts, but doesn't clear target and thus attempts to use
that SImode target for DImode shifts.
The code apparently already has if (mode != tmode) target = 0;, just
done at a wrong spot before mode can be changed.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux
and tested with a cross to arm-linux on the testcase, ok for trunk/4.6?

2011-05-18  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/49029
	* expmed.c (extract_fixed_bit_field): Test whether target can be used
	only after deciding which mode to use.

	* gcc.c-torture/compile/pr49029.c: New test.


	Jakub

Comments

Eric Botcazou May 22, 2011, 8:42 a.m. UTC | #1
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux
> and tested with a cross to arm-linux on the testcase, ok for trunk/4.6?
>
> 2011-05-18  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR middle-end/49029
> 	* expmed.c (extract_fixed_bit_field): Test whether target can be used
> 	only after deciding which mode to use.
>
> 	* gcc.c-torture/compile/pr49029.c: New test.

Not something I can formally approve but, given the current scarcity of 
reviewers and the extent of the change, I'd say go ahead for both.
Jeff Law May 23, 2011, 2:57 p.m. UTC | #2
On 05/18/11 06:33, Jakub Jelinek wrote:
> Hi!
> 
> The attached testcase ICEs on arm, because extract_fixed_bit_field
> with tmode SImode (and SImode non-NULL target) decides to use DImode for
> the signed shifts, but doesn't clear target and thus attempts to use
> that SImode target for DImode shifts.
> The code apparently already has if (mode != tmode) target = 0;, just
> done at a wrong spot before mode can be changed.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux
> and tested with a cross to arm-linux on the testcase, ok for trunk/4.6?
> 
> 2011-05-18  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/49029
> 	* expmed.c (extract_fixed_bit_field): Test whether target can be used
> 	only after deciding which mode to use.
> 
> 	* gcc.c-torture/compile/pr49029.c: New test.
OK.
Jeff
diff mbox

Patch

--- gcc/expmed.c.jj	2011-05-11 19:39:04.000000000 +0200
+++ gcc/expmed.c	2011-05-18 11:38:43.000000000 +0200
@@ -1769,8 +1769,6 @@  extract_fixed_bit_field (enum machine_mo
   /* To extract a signed bit-field, first shift its msb to the msb of the word,
      then arithmetic-shift its lsb to the lsb of the word.  */
   op0 = force_reg (mode, op0);
-  if (mode != tmode)
-    target = 0;
 
   /* Find the narrowest integer mode that contains the field.  */
 
@@ -1782,6 +1780,9 @@  extract_fixed_bit_field (enum machine_mo
 	break;
       }
 
+  if (mode != tmode)
+    target = 0;
+
   if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
     {
       int amount = GET_MODE_BITSIZE (mode) - (bitsize + bitpos);
--- gcc/testsuite/gcc.c-torture/compile/pr49029.c.jj	2011-05-18 11:55:25.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr49029.c	2011-05-18 11:54:22.000000000 +0200
@@ -0,0 +1,10 @@ 
+/* PR middle-end/49029 */
+struct S { volatile unsigned f : 11; signed g : 30; } __attribute__((packed));
+struct T { volatile struct S h; } __attribute__((packed)) a;
+void foo (int);
+
+void
+bar ()
+{
+  foo (a.h.g);
+}