re PR tree-optimization/52979 (likely wrong code bug w/packed bitfields)
PR middle-end/52979 * stor-layout.c (get_best_mode): Don't return mode with bitsize larger than maxbits. Don't compute maxbits modulo align. Also check that unit bytes long store at bitpos / unit * unit doesn't affect bits beyond bitregion_end. * expmed.c (store_bit_field_1): Avoid trying insv if OP_MODE MEM would not fit into bitregion_start ... bitregion_end + 1 bit region. (store_split_bit_field): Decrease unit close to end of bitregion_end if access is restricted in order to avoid mutual recursion. * gcc.c-torture/compile/pr52979-1.c: New test. * gcc.c-torture/execute/pr52979-1.c: New test. * gcc.c-torture/execute/pr52979-2.c: New test. From-SVN: r186819
This commit is contained in:
parent
948e73b3d6
commit
f1cc958978
@ -1,5 +1,16 @@
|
||||
2012-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/52979
|
||||
* stor-layout.c (get_best_mode): Don't return mode with bitsize
|
||||
larger than maxbits. Don't compute maxbits modulo align.
|
||||
Also check that unit bytes long store at bitpos / unit * unit
|
||||
doesn't affect bits beyond bitregion_end.
|
||||
* expmed.c (store_bit_field_1): Avoid trying insv if OP_MODE MEM
|
||||
would not fit into bitregion_start ... bitregion_end + 1 bit
|
||||
region.
|
||||
(store_split_bit_field): Decrease unit close to end of bitregion_end
|
||||
if access is restricted in order to avoid mutual recursion.
|
||||
|
||||
PR tree-optimization/53058
|
||||
* double-int.h (double_int_max_value, double_int_min_value): New
|
||||
prototypes.
|
||||
|
20
gcc/expmed.c
20
gcc/expmed.c
@ -640,7 +640,13 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
&& !(MEM_P (op0) && MEM_VOLATILE_P (op0)
|
||||
&& flag_strict_volatile_bitfields > 0)
|
||||
&& ! ((REG_P (op0) || GET_CODE (op0) == SUBREG)
|
||||
&& (bitsize + bitpos > GET_MODE_BITSIZE (op_mode))))
|
||||
&& (bitsize + bitpos > GET_MODE_BITSIZE (op_mode)))
|
||||
/* Do not use insv if the bit region is restricted and
|
||||
op_mode integer at offset doesn't fit into the
|
||||
restricted region. */
|
||||
&& !(MEM_P (op0) && bitregion_end
|
||||
&& bitnum - bitpos + GET_MODE_BITSIZE (op_mode)
|
||||
> bitregion_end + 1))
|
||||
{
|
||||
struct expand_operand ops[4];
|
||||
int xbitpos = bitpos;
|
||||
@ -760,7 +766,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
|| GET_MODE_BITSIZE (GET_MODE (op0)) > maxbits
|
||||
|| (op_mode != MAX_MACHINE_MODE
|
||||
&& GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (op_mode)))
|
||||
bestmode = get_best_mode (bitsize, bitnum,
|
||||
bestmode = get_best_mode (bitsize, bitnum,
|
||||
bitregion_start, bitregion_end,
|
||||
MEM_ALIGN (op0),
|
||||
(op_mode == MAX_MACHINE_MODE
|
||||
@ -1096,6 +1102,16 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
|
||||
offset = (bitpos + bitsdone) / unit;
|
||||
thispos = (bitpos + bitsdone) % unit;
|
||||
|
||||
/* When region of bytes we can touch is restricted, decrease
|
||||
UNIT close to the end of the region as needed. */
|
||||
if (bitregion_end
|
||||
&& unit > BITS_PER_UNIT
|
||||
&& bitpos + bitsdone - thispos + unit > bitregion_end + 1)
|
||||
{
|
||||
unit = unit / 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* THISSIZE must not overrun a word boundary. Otherwise,
|
||||
store_fixed_bit_field will call us again, and we will mutually
|
||||
recurse forever. */
|
||||
|
@ -2624,7 +2624,7 @@ get_best_mode (int bitsize, int bitpos,
|
||||
if (!bitregion_end)
|
||||
maxbits = MAX_FIXED_MODE_SIZE;
|
||||
else
|
||||
maxbits = (bitregion_end - bitregion_start) % align + 1;
|
||||
maxbits = bitregion_end - bitregion_start + 1;
|
||||
|
||||
/* Find the narrowest integer mode that contains the bit field. */
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
|
||||
@ -2645,7 +2645,10 @@ get_best_mode (int bitsize, int bitpos,
|
||||
(Though at least one Unix compiler ignores this problem:
|
||||
that on the Sequent 386 machine. */
|
||||
|| MIN (unit, BIGGEST_ALIGNMENT) > align
|
||||
|| (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)))
|
||||
|| (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode))
|
||||
|| unit > maxbits
|
||||
|| (bitregion_end
|
||||
&& bitpos - (bitpos % unit) + unit > bitregion_end + 1))
|
||||
return VOIDmode;
|
||||
|
||||
if ((SLOW_BYTE_ACCESS && ! volatilep)
|
||||
@ -2663,7 +2666,9 @@ get_best_mode (int bitsize, int bitpos,
|
||||
&& unit <= MIN (align, BIGGEST_ALIGNMENT)
|
||||
&& unit <= maxbits
|
||||
&& (largest_mode == VOIDmode
|
||||
|| unit <= GET_MODE_BITSIZE (largest_mode)))
|
||||
|| unit <= GET_MODE_BITSIZE (largest_mode))
|
||||
&& (bitregion_end == 0
|
||||
|| bitpos - (bitpos % unit) + unit <= bitregion_end + 1))
|
||||
wide_mode = tmode;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2012-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/52979
|
||||
* gcc.c-torture/compile/pr52979-1.c: New test.
|
||||
* gcc.c-torture/execute/pr52979-1.c: New test.
|
||||
* gcc.c-torture/execute/pr52979-2.c: New test.
|
||||
|
||||
2012-04-25 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.target/i386/l_fma_float_5.c: Adjust.
|
||||
|
15
gcc/testsuite/gcc.c-torture/compile/pr52979-1.c
Normal file
15
gcc/testsuite/gcc.c-torture/compile/pr52979-1.c
Normal file
@ -0,0 +1,15 @@
|
||||
/* PR middle-end/52979 */
|
||||
|
||||
struct S
|
||||
{
|
||||
unsigned int a : 16, b : 16, c : 16, d : 16, e : 14;
|
||||
unsigned int f : 4, g : 14, h : 8;
|
||||
char i;
|
||||
int j;
|
||||
};
|
||||
|
||||
void
|
||||
foo (struct S *s)
|
||||
{
|
||||
s->f = 1;
|
||||
}
|
40
gcc/testsuite/gcc.c-torture/execute/pr52979-1.c
Normal file
40
gcc/testsuite/gcc.c-torture/execute/pr52979-1.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* PR middle-end/52979 */
|
||||
|
||||
extern void abort (void);
|
||||
int c, d, e;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
}
|
||||
|
||||
struct __attribute__((packed)) S { int g : 31; int h : 6; };
|
||||
struct S a = { 1 };
|
||||
static struct S b = { 1 };
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
a.h = 1;
|
||||
struct S f = { };
|
||||
b = f;
|
||||
e = 0;
|
||||
if (d)
|
||||
c = a.g;
|
||||
}
|
||||
|
||||
void
|
||||
baz (void)
|
||||
{
|
||||
bar ();
|
||||
a = b;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
baz ();
|
||||
if (a.g)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
40
gcc/testsuite/gcc.c-torture/execute/pr52979-2.c
Normal file
40
gcc/testsuite/gcc.c-torture/execute/pr52979-2.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* PR middle-end/52979 */
|
||||
|
||||
extern void abort (void);
|
||||
int c, d, e;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
}
|
||||
|
||||
struct __attribute__((packed)) S { int g : 31; int h : 6; };
|
||||
static struct S b = { 1 };
|
||||
struct S a = { 1 };
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
a.h = 1;
|
||||
struct S f = { };
|
||||
b = f;
|
||||
e = 0;
|
||||
if (d)
|
||||
c = a.g;
|
||||
}
|
||||
|
||||
void
|
||||
baz (void)
|
||||
{
|
||||
bar ();
|
||||
a = b;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
baz ();
|
||||
if (a.g)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user