re PR tree-optimization/79737 (wrong code at -O2 and -O3 on x86_64-linux-gnu (in both 32-bit and 64-bit modes))

PR tree-optimization/79737
	* gimple-ssa-store-merging.c (encode_tree_to_bitpos): If bitlen is
	a multiple of BITS_PER_UNIT and !BYTES_BIG_ENDIAN, clear
	tmpbuf[byte_size - 1].  Call natice_encode_expr with byte_size - 1
	instead of byte_size.  Formatting fix.
	(shift_bytes_in_array_right): Formatting fix.

	* gcc.c-torture/execute/pr79737-1.c: New test.
	* gcc.c-torture/execute/pr79737-2.c: New test.

From-SVN: r245795
This commit is contained in:
Jakub Jelinek 2017-02-28 23:39:11 +01:00 committed by Jakub Jelinek
parent 7efb3707f2
commit ad1de65225
5 changed files with 119 additions and 23 deletions

View File

@ -1,3 +1,12 @@
2017-02-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/79737
* gimple-ssa-store-merging.c (encode_tree_to_bitpos): If bitlen is
a multiple of BITS_PER_UNIT and !BYTES_BIG_ENDIAN, clear
tmpbuf[byte_size - 1]. Call natice_encode_expr with byte_size - 1
instead of byte_size. Formatting fix.
(shift_bytes_in_array_right): Formatting fix.
2017-02-28 Eric Botcazou <ebotcazou@adacore.com>
PR target/79749

View File

@ -253,9 +253,9 @@ shift_bytes_in_array_right (unsigned char *ptr, unsigned int sz,
unsigned prev_carry_over = carry_over;
carry_over = ptr[i] & carry_mask;
carry_over <<= (unsigned char) BITS_PER_UNIT - amnt;
ptr[i] >>= amnt;
ptr[i] |= prev_carry_over;
carry_over <<= (unsigned char) BITS_PER_UNIT - amnt;
ptr[i] >>= amnt;
ptr[i] |= prev_carry_over;
}
}
@ -352,8 +352,9 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
{
unsigned int first_byte = bitpos / BITS_PER_UNIT;
tree tmp_int = expr;
bool sub_byte_op_p = (bitlen % BITS_PER_UNIT) || (bitpos % BITS_PER_UNIT)
|| mode_for_size (bitlen, MODE_INT, 0) == BLKmode;
bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT)
|| (bitpos % BITS_PER_UNIT)
|| mode_for_size (bitlen, MODE_INT, 0) == BLKmode);
if (!sub_byte_op_p)
return (native_encode_expr (tmp_int, ptr + first_byte, total_bytes, 0)
@ -407,7 +408,7 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
memset (tmpbuf, '\0', byte_size);
/* The store detection code should only have allowed constants that are
accepted by native_encode_expr. */
if (native_encode_expr (expr, tmpbuf, byte_size, 0) == 0)
if (native_encode_expr (expr, tmpbuf, byte_size - 1, 0) == 0)
gcc_unreachable ();
/* The native_encode_expr machinery uses TYPE_MODE to determine how many
@ -418,25 +419,27 @@ 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 (padding != 0
|| bitlen % BITS_PER_UNIT != 0)
{
/* On big-endian the padding is at the 'front' so just skip the initial
bytes. */
if (BYTES_BIG_ENDIAN)
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)
{
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);
}
byte_size -= padding;
if (bitlen % BITS_PER_UNIT != 0)
{
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);
}
/* Left shifting relies on the last byte being clear if bitlen is
a multiple of BITS_PER_UNIT, which might not be clear if
there are padding bytes. */
else if (!BYTES_BIG_ENDIAN)
tmpbuf[byte_size - 1] = '\0';
/* Clear the bit region in PTR where the bits from TMPBUF will be
inserted into. */

View File

@ -1,3 +1,9 @@
2017-02-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/79737
* gcc.c-torture/execute/pr79737-1.c: New test.
* gcc.c-torture/execute/pr79737-2.c: New test.
2017-02-28 Eric Botcazou <ebotcazou@adacore.com>
* gcc.target/sparc/20170228-1.c: New test.

View File

@ -0,0 +1,37 @@
/* PR tree-optimization/79737 */
#pragma pack(1)
struct S
{
int b:18;
int c:1;
int d:24;
int e:15;
int f:14;
} i;
int g, j, k;
static struct S h;
void
foo ()
{
for (j = 0; j < 6; j++)
k = 0;
for (; k < 3; k++)
{
struct S m = { 5, 0, -5, 9, 5 };
h = m;
if (g)
i = m;
h.e = 0;
}
}
int
main ()
{
foo ();
if (h.e != 0)
__builtin_abort ();
return 0;
}

View File

@ -0,0 +1,41 @@
/* PR tree-optimization/79737 */
#pragma pack(1)
struct S
{
int b:18;
int c:1;
int d:24;
int e:15;
int f:14;
} i, j;
void
foo ()
{
i.e = 0;
i.b = 5;
i.c = 0;
i.d = -5;
i.f = 5;
}
void
bar ()
{
j.b = 5;
j.c = 0;
j.d = -5;
j.e = 0;
j.f = 5;
}
int
main ()
{
foo ();
bar ();
asm volatile ("" : : : "memory");
if (i.b != j.b || i.c != j.c || i.d != j.d || i.e != j.e || i.f != j.f)
__builtin_abort ();
}