re PR tree-optimization/63266 (Test regression: gcc.target/sh/pr53568-1.c)
2014-09-24 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ PR tree-optimization/63266 * tree-ssa-math-opts.c (struct symbolic_number): Add comment about marker for unknown byte value. (MARKER_MASK): New macro. (MARKER_BYTE_UNKNOWN): New macro. (HEAD_MARKER): New macro. (do_shift_rotate): Mark bytes with unknown values due to sign extension when doing an arithmetic right shift. Replace hardcoded mask for marker by new MARKER_MASK macro. (find_bswap_or_nop_1): Likewise and adjust ORing of two symbolic numbers accordingly. gcc/testsuite/ PR tree-optimization/63266 * gcc.dg/optimize-bswapsi-1.c (swap32_d): New bswap pass test. From-SVN: r215546
This commit is contained in:
parent
415ebad0b3
commit
aa29ea0cd4
@ -1,3 +1,17 @@
|
||||
2014-09-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
PR tree-optimization/63266
|
||||
* tree-ssa-math-opts.c (struct symbolic_number): Add comment about
|
||||
marker for unknown byte value.
|
||||
(MARKER_MASK): New macro.
|
||||
(MARKER_BYTE_UNKNOWN): New macro.
|
||||
(HEAD_MARKER): New macro.
|
||||
(do_shift_rotate): Mark bytes with unknown values due to sign
|
||||
extension when doing an arithmetic right shift. Replace hardcoded
|
||||
mask for marker by new MARKER_MASK macro.
|
||||
(find_bswap_or_nop_1): Likewise and adjust ORing of two symbolic
|
||||
numbers accordingly.
|
||||
|
||||
2014-09-24 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||
Maxim Kuznetsov <maxim.kuznetsov@intel.com>
|
||||
Anna Tikhonova <anna.tikhonova@intel.com>
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-09-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
PR tree-optimization/63266
|
||||
* gcc.dg/optimize-bswapsi-1.c (swap32_d): New bswap pass test.
|
||||
|
||||
2014-09-24 Zhenqiang Chen <zhenqiang.chen@arm.com>
|
||||
|
||||
* gcc.target/arm/pr63210.c: New test.
|
||||
|
@ -49,5 +49,20 @@ swap32_c (SItype u)
|
||||
| (((u) & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 3 "bswap" } } */
|
||||
/* This variant comes from gcc.target/sh/pr53568-1.c. It requires to track
|
||||
which bytes have an unpredictable value (eg. due to sign extension) to
|
||||
make sure that the final expression have only well defined byte values. */
|
||||
|
||||
SItype
|
||||
swap32_d (SItype in)
|
||||
{
|
||||
/* 1x swap.w
|
||||
2x swap.b */
|
||||
return (((in >> 0) & 0xFF) << 24)
|
||||
| (((in >> 8) & 0xFF) << 16)
|
||||
| (((in >> 16) & 0xFF) << 8)
|
||||
| (((in >> 24) & 0xFF) << 0);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 4 "bswap" } } */
|
||||
/* { dg-final { cleanup-tree-dump "bswap" } } */
|
||||
|
@ -1603,6 +1603,7 @@ make_pass_cse_sincos (gcc::context *ctxt)
|
||||
consisting of octet sized markers:
|
||||
|
||||
0 - target byte has the value 0
|
||||
FF - target byte has an unknown value (eg. due to sign extension)
|
||||
1..size - marker value is the target byte index minus one.
|
||||
|
||||
To detect permutations on memory sources (arrays and structures), a symbolic
|
||||
@ -1629,6 +1630,10 @@ struct symbolic_number {
|
||||
};
|
||||
|
||||
#define BITS_PER_MARKER 8
|
||||
#define MARKER_MASK ((1 << BITS_PER_MARKER) - 1)
|
||||
#define MARKER_BYTE_UNKNOWN MARKER_MASK
|
||||
#define HEAD_MARKER(n, size) \
|
||||
((n) & ((uint64_t) MARKER_MASK << (((size) - 1) * BITS_PER_MARKER)))
|
||||
|
||||
/* The number which the find_bswap_or_nop_1 result should match in
|
||||
order to have a nop. The number is masked according to the size of
|
||||
@ -1651,7 +1656,8 @@ do_shift_rotate (enum tree_code code,
|
||||
struct symbolic_number *n,
|
||||
int count)
|
||||
{
|
||||
int size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
|
||||
int i, size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
|
||||
unsigned head_marker;
|
||||
|
||||
if (count % BITS_PER_UNIT != 0)
|
||||
return false;
|
||||
@ -1668,11 +1674,13 @@ do_shift_rotate (enum tree_code code,
|
||||
n->n <<= count;
|
||||
break;
|
||||
case RSHIFT_EXPR:
|
||||
/* Arithmetic shift of signed type: result is dependent on the value. */
|
||||
if (!TYPE_UNSIGNED (n->type)
|
||||
&& (n->n & ((uint64_t) 0xff << ((size - 1) * BITS_PER_MARKER))))
|
||||
return false;
|
||||
head_marker = HEAD_MARKER (n->n, size);
|
||||
n->n >>= count;
|
||||
/* Arithmetic shift of signed type: result is dependent on the value. */
|
||||
if (!TYPE_UNSIGNED (n->type) && head_marker)
|
||||
for (i = 0; i < count / BITS_PER_MARKER; i++)
|
||||
n->n |= (uint64_t) MARKER_BYTE_UNKNOWN
|
||||
<< ((size - 1 - i) * BITS_PER_MARKER);
|
||||
break;
|
||||
case LROTATE_EXPR:
|
||||
n->n = (n->n << count) | (n->n >> ((size * BITS_PER_MARKER) - count));
|
||||
@ -1878,7 +1886,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
if ((val & tmp) != 0 && (val & tmp) != tmp)
|
||||
return NULL;
|
||||
else if (val & tmp)
|
||||
mask |= (uint64_t) 0xff << (i * BITS_PER_MARKER);
|
||||
mask |= (uint64_t) MARKER_MASK << (i * BITS_PER_MARKER);
|
||||
|
||||
n->n &= mask;
|
||||
}
|
||||
@ -1892,7 +1900,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
break;
|
||||
CASE_CONVERT:
|
||||
{
|
||||
int type_size, old_type_size;
|
||||
int i, type_size, old_type_size;
|
||||
tree type;
|
||||
|
||||
type = gimple_expr_type (stmt);
|
||||
@ -1905,11 +1913,10 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
|
||||
/* Sign extension: result is dependent on the value. */
|
||||
old_type_size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
|
||||
if (!TYPE_UNSIGNED (n->type)
|
||||
&& type_size > old_type_size
|
||||
&& n->n & ((uint64_t) 0xff << ((old_type_size - 1)
|
||||
* BITS_PER_MARKER)))
|
||||
return NULL;
|
||||
if (!TYPE_UNSIGNED (n->type) && type_size > old_type_size
|
||||
&& HEAD_MARKER (n->n, old_type_size))
|
||||
for (i = 0; i < type_size - old_type_size; i++)
|
||||
n->n |= MARKER_BYTE_UNKNOWN << (type_size - 1 - i);
|
||||
|
||||
if (type_size < 64 / BITS_PER_MARKER)
|
||||
{
|
||||
@ -1968,7 +1975,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
if (gimple_assign_rhs1 (source_stmt1)
|
||||
!= gimple_assign_rhs1 (source_stmt2))
|
||||
{
|
||||
int64_t inc, mask;
|
||||
int64_t inc;
|
||||
HOST_WIDE_INT off_sub;
|
||||
struct symbolic_number *n_ptr;
|
||||
|
||||
@ -2002,15 +2009,15 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
bigger weight according to target endianness. */
|
||||
inc = BYTES_BIG_ENDIAN ? off_sub + n2.range - n1.range : off_sub;
|
||||
size = TYPE_PRECISION (n1.type) / BITS_PER_UNIT;
|
||||
mask = 0xff;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
n_ptr = &n1;
|
||||
else
|
||||
n_ptr = &n2;
|
||||
for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER,
|
||||
mask <<= BITS_PER_MARKER)
|
||||
for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER)
|
||||
{
|
||||
if (n_ptr->n & mask)
|
||||
unsigned marker =
|
||||
(n_ptr->n >> (i * BITS_PER_MARKER)) & MARKER_MASK;
|
||||
if (marker && marker != MARKER_BYTE_UNKNOWN)
|
||||
n_ptr->n += inc;
|
||||
}
|
||||
}
|
||||
@ -2028,7 +2035,8 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
|
||||
n->bytepos = n1.bytepos;
|
||||
n->type = n1.type;
|
||||
size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
|
||||
for (i = 0, mask = 0xff; i < size; i++, mask <<= BITS_PER_MARKER)
|
||||
for (i = 0, mask = MARKER_MASK; i < size;
|
||||
i++, mask <<= BITS_PER_MARKER)
|
||||
{
|
||||
uint64_t masked1, masked2;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user