fold-const.c (fold): Convert (T)(x&c) into ((T)x&(T)c) for integer constant c (if...
* fold-const.c (fold) [NOP_EXPR]: Convert (T)(x&c) into ((T)x&(T)c) for integer constant c (if x has unsigned type or sign bit is not set in c). This folds the zero/sign extension into the bit-wise and operation. * gcc.c-torture/compile/20020415-1.c: New. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r52465
This commit is contained in:
parent
692efa8ed5
commit
58c2956cc7
@ -1,3 +1,11 @@
|
||||
2002-04-18 Roger Sayle <roger@eyesopen.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* fold-const.c (fold) [NOP_EXPR]: Convert (T)(x&c) into ((T)x&(T)c)
|
||||
for integer constant c (if x has unsigned type or sign bit is not
|
||||
set in c). This folds the zero/sign extension into the bit-wise and
|
||||
operation.
|
||||
|
||||
2002-04-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/6205
|
||||
|
@ -4695,6 +4695,49 @@ fold (expr)
|
||||
TREE_USED (t) = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
|
||||
constants (if x has signed type, the sign bit cannot be set
|
||||
in c). This folds extension into the BIT_AND_EXPR. */
|
||||
if (INTEGRAL_TYPE_P (TREE_TYPE (t))
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == BIT_AND_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST)
|
||||
{
|
||||
tree and = TREE_OPERAND (t, 0);
|
||||
tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
|
||||
int change = 0;
|
||||
|
||||
if (TREE_UNSIGNED (TREE_TYPE (and))
|
||||
|| (TYPE_PRECISION (TREE_TYPE (t))
|
||||
<= TYPE_PRECISION (TREE_TYPE (and))))
|
||||
change = 1;
|
||||
else if (TYPE_PRECISION (TREE_TYPE (and1))
|
||||
<= HOST_BITS_PER_WIDE_INT
|
||||
&& host_integerp (and1, 1))
|
||||
{
|
||||
unsigned HOST_WIDE_INT cst;
|
||||
|
||||
cst = tree_low_cst (and1, 1);
|
||||
cst &= (HOST_WIDE_INT) -1
|
||||
<< (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
|
||||
change = (cst == 0);
|
||||
#ifdef LOAD_EXTEND_OP
|
||||
if (change
|
||||
&& (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
|
||||
== ZERO_EXTEND))
|
||||
{
|
||||
tree uns = unsigned_type (TREE_TYPE (and0));
|
||||
and0 = convert (uns, and0);
|
||||
and1 = convert (uns, and1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (change)
|
||||
return fold (build (BIT_AND_EXPR, TREE_TYPE (t),
|
||||
convert (TREE_TYPE (t), and0),
|
||||
convert (TREE_TYPE (t), and1)));
|
||||
}
|
||||
|
||||
if (!wins)
|
||||
{
|
||||
TREE_CONSTANT (t) = TREE_CONSTANT (arg0);
|
||||
|
@ -1,3 +1,7 @@
|
||||
2002-04-18 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gcc.c-torture/compile/20020415-1.c: New.
|
||||
|
||||
2002-04-18 David S. Miller <davem@redhat.com>
|
||||
|
||||
* gcc.c-torture/execute/20020418-1.c: New test.
|
||||
|
22
gcc/testsuite/gcc.c-torture/compile/20020415-1.c
Normal file
22
gcc/testsuite/gcc.c-torture/compile/20020415-1.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* Check that floating point casts of integer operations don't ICE. */
|
||||
/* The first of these routines caused problems for a patch, that wasn't
|
||||
otherwise caught by a full bootstrap, the regression test suite or
|
||||
SPEC CPU2000. */
|
||||
|
||||
double
|
||||
andop (unsigned int x)
|
||||
{
|
||||
return x & 1;
|
||||
}
|
||||
|
||||
double
|
||||
orop (unsigned int x)
|
||||
{
|
||||
return x | 1;
|
||||
}
|
||||
|
||||
double
|
||||
notop (unsigned int x)
|
||||
{
|
||||
return ~x;
|
||||
}
|
Loading…
Reference in New Issue
Block a user