diff options
author | Roger Sayle <roger@eyesopen.com> | 2002-04-18 10:39:41 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2002-04-18 12:39:41 +0200 |
commit | 58c2956cc78b5eac943d4c800f28faa9e7529b4e (patch) | |
tree | 0bdc385dfefe6169060b519e747fd90bf8ebb371 /gcc | |
parent | 692efa8ed557524d30dc66687c3f5c58de1be9e3 (diff) | |
download | gcc-58c2956cc78b5eac943d4c800f28faa9e7529b4e.zip gcc-58c2956cc78b5eac943d4c800f28faa9e7529b4e.tar.gz gcc-58c2956cc78b5eac943d4c800f28faa9e7529b4e.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fold-const.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20020415-1.c | 22 |
4 files changed, 77 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b2ba0f7..bacaa1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 10a92fe..2521413 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6bb6b22..8798cc1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.c-torture/compile/20020415-1.c b/gcc/testsuite/gcc.c-torture/compile/20020415-1.c new file mode 100644 index 0000000..95cdc1e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20020415-1.c @@ -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; +} |