mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 11:41:07 +08:00
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:
parent
7efb3707f2
commit
ad1de65225
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
37
gcc/testsuite/gcc.c-torture/execute/pr79737-1.c
Normal file
37
gcc/testsuite/gcc.c-torture/execute/pr79737-1.c
Normal 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;
|
||||
}
|
41
gcc/testsuite/gcc.c-torture/execute/pr79737-2.c
Normal file
41
gcc/testsuite/gcc.c-torture/execute/pr79737-2.c
Normal 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 ();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user