fold-const.c (fold): Convert (T)(x&c) into ((T)x&(T)c) for integer constant c (if...
authorRoger Sayle <roger@eyesopen.com>
Thu, 18 Apr 2002 10:39:41 +0000 (10:39 +0000)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 18 Apr 2002 10:39:41 +0000 (12:39 +0200)
* 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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20020415-1.c [new file with mode: 0644]

index b2ba0f77aa8ec1e6b2fd36f3d861ec572a9ac842..bacaa1a100daaf1d852bd2d5924cae2f6ce50d46 100644 (file)
@@ -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
index 10a92fe412b98685305af89995785972053a8e13..2521413925240bf5b4937681ddac1a45879ba1d2 100644 (file)
@@ -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);
index 6bb6b2217717041b1c660848fd69bbb0f0e0c7ea..8798cc1eb69933bbe210bd2a272b90b802fac43e 100644 (file)
@@ -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 (file)
index 0000000..95cdc1e
--- /dev/null
@@ -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;
+}