re PR tree-optimization/67781 (wrong code generated on big-endian with -O1 -fexpensive-optimizations)
2016-01-08 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR tree-optimization/67781 * tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg and cmpnop in two steps: first the ones not accessed in original gimple expression in a endian independent way and then the ones not accessed in the final result in an endian-specific way. gcc/testsuite/ PR tree-optimization/67781 * gcc.c-torture/execute/pr67781.c: New file. From-SVN: r232154
This commit is contained in:
parent
262a363ff9
commit
80e9b3aaac
|
@ -1,3 +1,11 @@
|
||||||
|
2016-01-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/67781
|
||||||
|
* tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg
|
||||||
|
and cmpnop in two steps: first the ones not accessed in original
|
||||||
|
gimple expression in a endian independent way and then the ones not
|
||||||
|
accessed in the final result in an endian-specific way.
|
||||||
|
|
||||||
2016-01-08 Jakub Jelinek <jakub@redhat.com>
|
2016-01-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/69083
|
PR tree-optimization/69083
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2016-01-08 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/67781
|
||||||
|
* gcc.c-torture/execute/pr67781.c: New file.
|
||||||
|
|
||||||
2016-01-08 Jakub Jelinek <jakub@redhat.com>
|
2016-01-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/69083
|
PR tree-optimization/69083
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifdef __UINT32_TYPE__
|
||||||
|
typedef __UINT32_TYPE__ uint32_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned uint32_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __UINT8_TYPE__
|
||||||
|
typedef __UINT8_TYPE__ uint8_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t a;
|
||||||
|
uint8_t b;
|
||||||
|
} s = { 0x123456, 0x78 };
|
||||||
|
|
||||||
|
int pr67781()
|
||||||
|
{
|
||||||
|
uint32_t c = (s.a << 8) | s.b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (sizeof (uint32_t) * __CHAR_BIT__ != 32)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pr67781 () != 0x12345678)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -2449,6 +2449,8 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
|
||||||
static gimple *
|
static gimple *
|
||||||
find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap)
|
find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap)
|
||||||
{
|
{
|
||||||
|
unsigned rsize;
|
||||||
|
uint64_t tmpn, mask;
|
||||||
/* The number which the find_bswap_or_nop_1 result should match in order
|
/* The number which the find_bswap_or_nop_1 result should match in order
|
||||||
to have a full byte swap. The number is shifted to the right
|
to have a full byte swap. The number is shifted to the right
|
||||||
according to the size of the symbolic number before using it. */
|
according to the size of the symbolic number before using it. */
|
||||||
|
@ -2472,24 +2474,38 @@ find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap)
|
||||||
|
|
||||||
/* Find real size of result (highest non-zero byte). */
|
/* Find real size of result (highest non-zero byte). */
|
||||||
if (n->base_addr)
|
if (n->base_addr)
|
||||||
{
|
for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
|
||||||
int rsize;
|
else
|
||||||
uint64_t tmpn;
|
rsize = n->range;
|
||||||
|
|
||||||
for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
|
/* Zero out the bits corresponding to untouched bytes in original gimple
|
||||||
n->range = rsize;
|
expression. */
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero out the extra bits of N and CMP*. */
|
|
||||||
if (n->range < (int) sizeof (int64_t))
|
if (n->range < (int) sizeof (int64_t))
|
||||||
{
|
{
|
||||||
uint64_t mask;
|
|
||||||
|
|
||||||
mask = ((uint64_t) 1 << (n->range * BITS_PER_MARKER)) - 1;
|
mask = ((uint64_t) 1 << (n->range * BITS_PER_MARKER)) - 1;
|
||||||
cmpxchg >>= (64 / BITS_PER_MARKER - n->range) * BITS_PER_MARKER;
|
cmpxchg >>= (64 / BITS_PER_MARKER - n->range) * BITS_PER_MARKER;
|
||||||
cmpnop &= mask;
|
cmpnop &= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Zero out the bits corresponding to unused bytes in the result of the
|
||||||
|
gimple expression. */
|
||||||
|
if (rsize < n->range)
|
||||||
|
{
|
||||||
|
if (BYTES_BIG_ENDIAN)
|
||||||
|
{
|
||||||
|
mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
|
||||||
|
cmpxchg &= mask;
|
||||||
|
cmpnop >>= (n->range - rsize) * BITS_PER_MARKER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
|
||||||
|
cmpxchg >>= (n->range - rsize) * BITS_PER_MARKER;
|
||||||
|
cmpnop &= mask;
|
||||||
|
}
|
||||||
|
n->range = rsize;
|
||||||
|
}
|
||||||
|
|
||||||
/* A complete byte swap should make the symbolic number to start with
|
/* A complete byte swap should make the symbolic number to start with
|
||||||
the largest digit in the highest order byte. Unchanged symbolic
|
the largest digit in the highest order byte. Unchanged symbolic
|
||||||
number indicates a read with same endianness as target architecture. */
|
number indicates a read with same endianness as target architecture. */
|
||||||
|
|
Loading…
Reference in New Issue