Message ID | 20110518123354.GI17079@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
> 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.
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
--- 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); +}