tree.c (integer_each_onep): New function.
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 12 Sep 2014 10:42:47 +0000 (12:42 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Fri, 12 Sep 2014 10:42:47 +0000 (10:42 +0000)
2014-09-12  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* tree.c (integer_each_onep): New function.
* tree.h (integer_each_onep): Declare it.
* fold-const.c (fold_binary_loc): Use it for ~A + 1 to -A and
-A - 1 to ~A.  Disable (X & 1) ^ 1, (X ^ 1) & 1 and ~X & 1 to
(X & 1) == 0 for vector and complex.
gcc/testsuite/
* gcc.dg/vec-andxor1.c: New file.

From-SVN: r215209

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vec-andxor1.c [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index af000040028f6845122fa0e0f815a6b3d22202ab..98586be01d1c52c34d4a6973b518b57bd852093a 100644 (file)
@@ -1,3 +1,11 @@
+2014-09-12  Marc Glisse  <marc.glisse@inria.fr>
+
+       * tree.c (integer_each_onep): New function.
+       * tree.h (integer_each_onep): Declare it.
+       * fold-const.c (fold_binary_loc): Use it for ~A + 1 to -A and
+       -A - 1 to ~A.  Disable (X & 1) ^ 1, (X ^ 1) & 1 and ~X & 1 to
+       (X & 1) == 0 for vector and complex.
+
 2014-09-12  Wilco Dijkstra  <wilco.dijkstra@arm.com>
 
        * gcc/config/aarch64/aarch64.c (cortexa57_regmove_cost): New cost table
index d1b59a1efd81ee46910e7971a2f0cd1b6e3e10b0..f7bf5254e1807291b2bc8ab3b5d1add73b9ed1aa 100644 (file)
@@ -10092,7 +10092,7 @@ fold_binary_loc (location_t loc,
        {
          /* Convert ~A + 1 to -A.  */
          if (TREE_CODE (arg0) == BIT_NOT_EXPR
-             && integer_onep (arg1))
+             && integer_each_onep (arg1))
            return fold_build1_loc (loc, NEGATE_EXPR, type,
                                fold_convert_loc (loc, type,
                                                  TREE_OPERAND (arg0, 0)));
@@ -10619,9 +10619,8 @@ fold_binary_loc (location_t loc,
                            fold_convert_loc (loc, type,
                                              TREE_OPERAND (arg0, 0)));
       /* Convert -A - 1 to ~A.  */
-      if (TREE_CODE (type) != COMPLEX_TYPE
-         && TREE_CODE (arg0) == NEGATE_EXPR
-         && integer_onep (arg1)
+      if (TREE_CODE (arg0) == NEGATE_EXPR
+         && integer_each_onep (arg1)
          && !TYPE_OVERFLOW_TRAPS (type))
        return fold_build1_loc (loc, BIT_NOT_EXPR, type,
                            fold_convert_loc (loc, type,
@@ -11384,6 +11383,7 @@ fold_binary_loc (location_t loc,
 
       /* Fold (X & 1) ^ 1 as (X & 1) == 0.  */
       if (TREE_CODE (arg0) == BIT_AND_EXPR
+         && INTEGRAL_TYPE_P (type)
          && integer_onep (TREE_OPERAND (arg0, 1))
          && integer_onep (arg1))
        return fold_build2_loc (loc, EQ_EXPR, type, arg0,
@@ -11494,6 +11494,7 @@ fold_binary_loc (location_t loc,
 
       /* Fold (X ^ 1) & 1 as (X & 1) == 0.  */
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
+         && INTEGRAL_TYPE_P (type)
          && integer_onep (TREE_OPERAND (arg0, 1))
          && integer_onep (arg1))
        {
@@ -11507,6 +11508,7 @@ fold_binary_loc (location_t loc,
        }
       /* Fold ~X & 1 as (X & 1) == 0.  */
       if (TREE_CODE (arg0) == BIT_NOT_EXPR
+         && INTEGRAL_TYPE_P (type)
          && integer_onep (arg1))
        {
          tree tem2;
index 3aba1c7026af64072e27dd35f37971a028ac5533..fb727bf046484c2ce34ca5733905735b5e91aa91 100644 (file)
@@ -1,3 +1,7 @@
+2014-09-12  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/vec-andxor1.c: New file.
+
 2014-09-11  Marc Glisse  <marc.glisse@inria.fr>
 
        PR target/58757
diff --git a/gcc/testsuite/gcc.dg/vec-andxor1.c b/gcc/testsuite/gcc.dg/vec-andxor1.c
new file mode 100644 (file)
index 0000000..4aa454e
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+typedef int vec __attribute__((vector_size(4*sizeof(int))));
+
+__attribute__((noinline,noclone))
+void f (vec *x) {
+  *x = (*x & 1) ^ 1;
+}
+
+int main() {
+  vec x = { 1, 2, 3, 4 };
+  f(&x);
+  if (x[0] != 0 || x[1] != 1)
+    __builtin_abort();
+  return 0;
+}
index e40ee23e1e3d6d571761687549376926853c184e..6ad05756df00b25db24de08e94650c8fbdbc9416 100644 (file)
@@ -2169,6 +2169,21 @@ integer_onep (const_tree expr)
     }
 }
 
+/* Return 1 if EXPR is the integer constant one.  For complex and vector,
+   return 1 if every piece is the integer constant one.  */
+
+int
+integer_each_onep (const_tree expr)
+{
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == COMPLEX_CST)
+    return (integer_onep (TREE_REALPART (expr))
+           && integer_onep (TREE_IMAGPART (expr)));
+  else
+    return integer_onep (expr);
+}
+
 /* Return 1 if EXPR is an integer containing all 1's in as much precision as
    it contains, or a complex or vector whose subparts are such integers.  */
 
index 93a940aaee0727cdc733e85dc111d8f2bbcdbad3..93a12d403402ecacfe039cd8fdd8ba28eb2cd7a7 100644 (file)
@@ -3947,6 +3947,11 @@ extern int integer_zerop (const_tree);
 
 extern int integer_onep (const_tree);
 
+/* integer_onep (tree x) is nonzero if X is an integer constant of value 1, or
+   a vector or complex where each part is 1.  */
+
+extern int integer_each_onep (const_tree);
+
 /* integer_all_onesp (tree x) is nonzero if X is an integer constant
    all of whose significant bits are 1.  */