aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2002-04-18 10:39:41 +0000
committerJakub Jelinek <jakub@gcc.gnu.org>2002-04-18 12:39:41 +0200
commit58c2956cc78b5eac943d4c800f28faa9e7529b4e (patch)
tree0bdc385dfefe6169060b519e747fd90bf8ebb371 /gcc
parent692efa8ed557524d30dc66687c3f5c58de1be9e3 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/fold-const.c43
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20020415-1.c22
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;
+}