fold-const.c (negate_expr_p): Handle VECTOR_CST.
authorMarc Glisse <marc.glisse@inria.fr>
Thu, 13 Jun 2013 19:39:19 +0000 (21:39 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Thu, 13 Jun 2013 19:39:19 +0000 (19:39 +0000)
2013-06-13  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* fold-const.c (negate_expr_p): Handle VECTOR_CST.
(fold_negate_expr): Likewise.
(fold_real_zero_addition_p): Handle vectors.
(fold_binary_loc) <PLUS_EXPR, MINUS_EXPR>: Likewise.

gcc/testsuite/
* gcc.dg/fold-minus-1.c: New testcase.

From-SVN: r200073

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-minus-1.c [new file with mode: 0644]

index 4b4fbe09c09a43bbfd1312c378cce830ee68fbaa..9241d1d7e33a1025007c29de6913fb880d2b1472 100644 (file)
@@ -1,3 +1,10 @@
+2013-06-13  Marc Glisse  <marc.glisse@inria.fr>
+
+       * fold-const.c (negate_expr_p): Handle VECTOR_CST.
+       (fold_negate_expr): Likewise.
+       (fold_real_zero_addition_p): Handle vectors.
+       (fold_binary_loc) <PLUS_EXPR, MINUS_EXPR>: Likewise.
+
 2013-06-14  Alan Modra  <amodra@gmail.com>
 
        * varasm.c (force_const_mem): Revert 2013-06-07 change.
index 998948b0e6d3051566d901ee800ce3e6d12815c3..a8e5f43faf434c353484529d30812d0f048b0386 100644 (file)
@@ -421,6 +421,20 @@ negate_expr_p (tree t)
       return negate_expr_p (TREE_REALPART (t))
             && negate_expr_p (TREE_IMAGPART (t));
 
+    case VECTOR_CST:
+      {
+       if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
+         return true;
+
+       int count = TYPE_VECTOR_SUBPARTS (type), i;
+
+       for (i = 0; i < count; i++)
+         if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
+           return false;
+
+       return true;
+      }
+
     case COMPLEX_EXPR:
       return negate_expr_p (TREE_OPERAND (t, 0))
             && negate_expr_p (TREE_OPERAND (t, 1));
@@ -560,6 +574,21 @@ fold_negate_expr (location_t loc, tree t)
       }
       break;
 
+    case VECTOR_CST:
+      {
+       int count = TYPE_VECTOR_SUBPARTS (type), i;
+       tree *elts = XALLOCAVEC (tree, count);
+
+       for (i = 0; i < count; i++)
+         {
+           elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i));
+           if (elts[i] == NULL_TREE)
+             return NULL_TREE;
+         }
+
+       return build_vector (type, elts);
+      }
+
     case COMPLEX_EXPR:
       if (negate_expr_p (t))
        return fold_build2_loc (loc, COMPLEX_EXPR, type,
@@ -6168,9 +6197,12 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
     return true;
 
+  /* In a vector or complex, we would need to check the sign of all zeros.  */
+  if (TREE_CODE (addend) != REAL_CST)
+    return false;
+
   /* Treat x + -0 as x - 0 and x - -0 as x + 0.  */
-  if (TREE_CODE (addend) == REAL_CST
-      && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
+  if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
     negate = !negate;
 
   /* The mode has signed zeros, and we have to honor their sign.
@@ -10161,7 +10193,7 @@ fold_binary_loc (location_t loc,
                            fold_convert_loc (loc, type,
                                              TREE_OPERAND (arg0, 0)));
 
-      if (INTEGRAL_TYPE_P (type))
+      if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
        {
          /* Convert ~A + 1 to -A.  */
          if (TREE_CODE (arg0) == BIT_NOT_EXPR
@@ -10179,7 +10211,7 @@ fold_binary_loc (location_t loc,
              STRIP_NOPS (tem);
              if (operand_equal_p (tem, arg1, 0))
                {
-                 t1 = build_minus_one_cst (type);
+                 t1 = build_all_ones_cst (type);
                  return omit_one_operand_loc (loc, type, t1, arg1);
                }
            }
@@ -10193,7 +10225,7 @@ fold_binary_loc (location_t loc,
              STRIP_NOPS (tem);
              if (operand_equal_p (arg0, tem, 0))
                {
-                 t1 = build_minus_one_cst (type);
+                 t1 = build_all_ones_cst (type);
                  return omit_one_operand_loc (loc, type, t1, arg0);
                }
            }
@@ -10674,8 +10706,6 @@ fold_binary_loc (location_t loc,
                                              TREE_OPERAND (arg1, 0)));
       /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
       if (TREE_CODE (arg0) == NEGATE_EXPR
-         && (FLOAT_TYPE_P (type)
-             || INTEGRAL_TYPE_P (type))
          && negate_expr_p (arg1)
          && reorder_operands_p (arg0, arg1))
        return fold_build2_loc (loc, MINUS_EXPR, type,
@@ -10684,7 +10714,7 @@ fold_binary_loc (location_t loc,
                            fold_convert_loc (loc, type,
                                              TREE_OPERAND (arg0, 0)));
       /* Convert -A - 1 to ~A.  */
-      if (INTEGRAL_TYPE_P (type)
+      if (TREE_CODE (type) != COMPLEX_TYPE
          && TREE_CODE (arg0) == NEGATE_EXPR
          && integer_onep (arg1)
          && !TYPE_OVERFLOW_TRAPS (type))
@@ -10693,13 +10723,13 @@ fold_binary_loc (location_t loc,
                                              TREE_OPERAND (arg0, 0)));
 
       /* Convert -1 - A to ~A.  */
-      if (INTEGRAL_TYPE_P (type)
+      if (TREE_CODE (type) != COMPLEX_TYPE
          && integer_all_onesp (arg0))
        return fold_build1_loc (loc, BIT_NOT_EXPR, type, op1);
 
 
-      /* X - (X / CST) * CST is X % CST.  */
-      if (INTEGRAL_TYPE_P (type)
+      /* X - (X / Y) * Y is X % Y.  */
+      if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
          && TREE_CODE (arg1) == MULT_EXPR
          && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
          && operand_equal_p (arg0,
index 912fe61f7e20516b8bab8542b2757c99a1b80238..39580f763333630c19530a1b1d7307ef7f4a749b 100644 (file)
@@ -1,3 +1,7 @@
+2013-06-13  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/fold-minus-1.c: New testcase.
+
 2013-06-13  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/49074
diff --git a/gcc/testsuite/gcc.dg/fold-minus-1.c b/gcc/testsuite/gcc.dg/fold-minus-1.c
new file mode 100644 (file)
index 0000000..c0fb89a
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-gimple" } */
+
+typedef int vec __attribute__((vector_size(2*sizeof(int))));
+
+void f(vec*x,vec*y){
+  *x -= *x / *y * *y;
+}
+void g(vec*x,vec*y,vec*z){
+  *x = -1 - *x;
+  *y = -*y - 1;
+  *z = -*z - 13;
+}
+
+/* { dg-final { scan-tree-dump-times "%" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times "~" 2 "gimple"} } */
+/* { dg-final { scan-tree-dump-not "/" "gimple"} } */
+/* { dg-final { scan-tree-dump-not "\\\+" "gimple"} } */
+/* { dg-final { scan-tree-dump "{ -13, -13 }" "gimple"} } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */