PR tree-optimization/78170: Truncate sign-extended padding when encoding bitfields

PR tree-optimization/78170
	* gimple-ssa-store-merging.c (encode_tree_to_bitpos): Truncate padding
	introduced by native_encode_expr on little-endian as well.

	* gcc.c-torture/execute/pr78170.c: New test.

From-SVN: r241779
This commit is contained in:
Kyrylo Tkachov 2016-11-02 09:28:35 +00:00 committed by Kyrylo Tkachov
parent 63e523d6f0
commit 4b2c06f49f
4 changed files with 62 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/78170
* gimple-ssa-store-merging.c (encode_tree_to_bitpos): Truncate padding
introduced by native_encode_expr on little-endian as well.
2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/78162

View File

@ -432,13 +432,23 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
contain a sign bit due to sign-extension). */
unsigned int padding
= byte_size - ROUND_UP (bitlen, BITS_PER_UNIT) / BITS_PER_UNIT - 1;
if (BYTES_BIG_ENDIAN)
if (padding != 0)
{
tmpbuf += padding;
/* On big-endian the padding is at the 'front' so just skip the initial
bytes. */
if (BYTES_BIG_ENDIAN)
tmpbuf += padding;
byte_size -= padding;
if (bitlen % BITS_PER_UNIT != 0)
clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1,
BITS_PER_UNIT - (bitlen % BITS_PER_UNIT));
{
if (BYTES_BIG_ENDIAN)
clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1,
BITS_PER_UNIT - (bitlen % BITS_PER_UNIT));
else
clear_bit_region (tmpbuf, bitlen,
byte_size * BITS_PER_UNIT - bitlen);
}
}
/* Clear the bit region in PTR where the bits from TMPBUF will be

View File

@ -1,3 +1,8 @@
2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/78170
* gcc.c-torture/execute/pr78170.c: New test.
2016-11-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/78162

View File

@ -0,0 +1,37 @@
/* PR tree-optimization/78170.
Check that sign-extended store to a bitfield
doesn't overwrite other fields. */
int a, b, d;
struct S0
{
int f0;
int f1;
int f2;
int f3;
int f4;
int f5:15;
int f6:17;
int f7:2;
int f8:30;
} c;
void fn1 ()
{
d = b = 1;
for (; b; b = a)
{
struct S0 e = { 0, 0, 0, 0, 0, 0, 1, 0, 1 };
c = e;
c.f6 = -1;
}
}
int main ()
{
fn1 ();
if (c.f7 != 0)
__builtin_abort ();
return 0;
}