tree.h (VECTOR_TYPE_P): New macro.
authorMarc Glisse <marc.glisse@inria.fr>
Thu, 21 Mar 2013 16:33:33 +0000 (17:33 +0100)
committerMarc Glisse <glisse@gcc.gnu.org>
Thu, 21 Mar 2013 16:33:33 +0000 (16:33 +0000)
2013-03-21  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* tree.h (VECTOR_TYPE_P): New macro.
(VECTOR_INTEGER_TYPE_P, VECTOR_FLOAT_TYPE_P, FLOAT_TYPE_P,
TYPE_MODE): Use it.
* fold-const.c (fold_cond_expr_with_comparison): Use build_zero_cst.
VEC_COND_EXPR cannot be lvalues.
(fold_ternary_loc) <VEC_COND_EXPR>: Merge with the COND_EXPR case.

gcc/cp/
* call.c (build_conditional_expr_1): Fold VEC_COND_EXPR.

gcc/testsuite/
* g++.dg/ext/vector21.C: New testcase.

From-SVN: r196884

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector21.C [new file with mode: 0644]
gcc/tree.h

index 0baa0a9..3992373 100644 (file)
@@ -1,5 +1,14 @@
 2013-03-21  Marc Glisse  <marc.glisse@inria.fr>
 
+       * tree.h (VECTOR_TYPE_P): New macro.
+       (VECTOR_INTEGER_TYPE_P, VECTOR_FLOAT_TYPE_P, FLOAT_TYPE_P,
+       TYPE_MODE): Use it.
+       * fold-const.c (fold_cond_expr_with_comparison): Use build_zero_cst.
+       VEC_COND_EXPR cannot be lvalues.
+       (fold_ternary_loc) <VEC_COND_EXPR>: Merge with the COND_EXPR case.
+
+2013-03-21  Marc Glisse  <marc.glisse@inria.fr>
+
        * simplify-rtx.c (simplify_binary_operation_1) <VEC_CONCAT>:
        Restrict the transformation to equal modes.
 
index 89a828f..37b67ce 100644 (file)
@@ -1,3 +1,7 @@
+2013-03-21  Marc Glisse  <marc.glisse@inria.fr>
+
+       * call.c (build_conditional_expr_1): Fold VEC_COND_EXPR.
+
 2013-03-21  Richard Biener  <rguenther@suse.de>
 
        * error.c (cp_printer): Use DECL_HAS_DEBUG_EXPR_P instead of
index 8362c75..5c9c286 100644 (file)
@@ -4437,9 +4437,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
        }
 
       if (!COMPARISON_CLASS_P (arg1))
-       arg1 = build2 (NE_EXPR, signed_type_for (arg1_type), arg1,
+       arg1 = fold_build2 (NE_EXPR, signed_type_for (arg1_type), arg1,
                       build_zero_cst (arg1_type));
-      return build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
+      return fold_build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
     }
 
   /* [expr.cond]
index ae03938..905661c 100644 (file)
@@ -4633,7 +4633,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
       if (comp_code == NE_EXPR)
        return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1));
       else if (comp_code == EQ_EXPR)
-       return build_int_cst (type, 0);
+       return build_zero_cst (type);
     }
 
   /* Try some transformations of A op B ? A : B.
@@ -4667,6 +4667,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
       /* Avoid these transformations if the COND_EXPR may be used
         as an lvalue in the C++ front-end.  PR c++/19199.  */
       && (in_gimple_form
+         || VECTOR_TYPE_P (type)
          || (strcmp (lang_hooks.name, "GNU C++") != 0
              && strcmp (lang_hooks.name, "GNU Objective-C++") != 0)
          || ! maybe_lvalue_p (arg1)
@@ -13899,6 +13900,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
       return NULL_TREE;
 
     case COND_EXPR:
+    case VEC_COND_EXPR:
       /* Pedantic ANSI C says that a conditional expression is never an lvalue,
         so all simple results must be passed through pedantic_non_lvalue.  */
       if (TREE_CODE (arg0) == INTEGER_CST)
@@ -13916,6 +13918,14 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
            return pedantic_non_lvalue_loc (loc, tem);
          return NULL_TREE;
        }
+      else if (TREE_CODE (arg0) == VECTOR_CST)
+       {
+         if (integer_all_onesp (arg0))
+           return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
+         if (integer_zerop (arg0))
+           return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
+       }
+
       if (operand_equal_p (arg1, op2, 0))
        return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
 
@@ -13951,6 +13961,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
            }
        }
 
+      /* ???  Fixup the code below for VEC_COND_EXPR.  */
+      if (code == VEC_COND_EXPR)
+       return NULL_TREE;
+
       /* If the second operand is simpler than the third, swap them
         since that produces better jump optimization results.  */
       if (truth_value_p (TREE_CODE (arg0))
@@ -14138,16 +14152,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
 
       return NULL_TREE;
 
-    case VEC_COND_EXPR:
-      if (TREE_CODE (arg0) == VECTOR_CST)
-       {
-         if (integer_all_onesp (arg0) && !TREE_SIDE_EFFECTS (op2))
-           return pedantic_non_lvalue_loc (loc, op1);
-         if (integer_zerop (arg0) && !TREE_SIDE_EFFECTS (op1))
-           return pedantic_non_lvalue_loc (loc, op2);
-       }
-      return NULL_TREE;
-
     case CALL_EXPR:
       /* CALL_EXPRs used to be ternary exprs.  Catch any mistaken uses
         of fold_ternary on them.  */
index eaa6bdc..fc3ee60 100644 (file)
@@ -1,3 +1,7 @@
+2013-03-21  Marc Glisse  <marc.glisse@inria.fr>
+
+       * g++.dg/ext/vector21.C: New testcase.
+
 2013-03-21  Christophe Lyon  <christophe.lyon@linaro.org>
 
        * gcc.target/arm/neon-for-64bits-1.c: New tests.
diff --git a/gcc/testsuite/g++.dg/ext/vector21.C b/gcc/testsuite/g++.dg/ext/vector21.C
new file mode 100644 (file)
index 0000000..71634c3
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-gimple" } */
+
+typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));
+
+void f1 (vec *x)
+{
+  *x = (*x >= 0) ? *x : -*x;
+}
+void f2 (vec *x)
+{
+  *x = (0 < *x) ? *x : -*x;
+}
+void g1 (vec *x)
+{
+  *x = (*x < 0) ? -*x : *x;
+}
+void g2 (vec *x)
+{
+  *x = (0 > *x) ? -*x : *x;
+}
+void h (vec *x, vec *y)
+{
+  *x = (*x < *y) ? *y : *x;
+}
+void i (vec *x, vec *y)
+{
+  *x = (*x < *y) ? *x : *y;
+}
+void j (vec *x, vec *y)
+{
+  *x = (*x < *y) ? *x : *x;
+}
+
+/* { dg-final { scan-tree-dump-times "ABS_EXPR" 4 "gimple" } } */
+/* { dg-final { scan-tree-dump "MIN_EXPR" "gimple" } } */
+/* { dg-final { scan-tree-dump "MAX_EXPR" "gimple" } } */
+/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
index 9aae8df..f1b988c 100644 (file)
@@ -981,6 +981,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define STRIP_USELESS_TYPE_CONVERSION(EXP) \
   (EXP) = tree_ssa_strip_useless_type_conversions (EXP)
 
+/* Nonzero if TYPE represents a vector type.  */
+
+#define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
+
 /* Nonzero if TYPE represents an integral type.  Note that we do not
    include COMPLEX types here.  Keep these checks in ascending code
    order.  */
@@ -1016,15 +1020,15 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 
 /* Nonzero if TYPE represents a vector integer type.  */
                 
-#define VECTOR_INTEGER_TYPE_P(TYPE)                   \
-             (TREE_CODE (TYPE) == VECTOR_TYPE      \
-                 && TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE)
+#define VECTOR_INTEGER_TYPE_P(TYPE)                    \
+  (VECTOR_TYPE_P (TYPE)                                        \
+   && TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE)
 
 
 /* Nonzero if TYPE represents a vector floating-point type.  */
 
 #define VECTOR_FLOAT_TYPE_P(TYPE)      \
-  (TREE_CODE (TYPE) == VECTOR_TYPE     \
+  (VECTOR_TYPE_P (TYPE)                        \
    && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE)
 
 /* Nonzero if TYPE represents a floating-point type, including complex
@@ -1034,7 +1038,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define FLOAT_TYPE_P(TYPE)                     \
   (SCALAR_FLOAT_TYPE_P (TYPE)                  \
    || ((TREE_CODE (TYPE) == COMPLEX_TYPE       \
-        || TREE_CODE (TYPE) == VECTOR_TYPE)    \
+        || VECTOR_TYPE_P (TYPE))               \
        && SCALAR_FLOAT_TYPE_P (TREE_TYPE (TYPE))))
 
 /* Nonzero if TYPE represents a decimal floating-point type.  */
@@ -2116,7 +2120,7 @@ struct GTY(()) tree_block {
 /* Vector types need to check target flags to determine type.  */
 extern enum machine_mode vector_type_mode (const_tree);
 #define TYPE_MODE(NODE) \
-  (TREE_CODE (TYPE_CHECK (NODE)) == VECTOR_TYPE \
+  (VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
    ? vector_type_mode (NODE) : (NODE)->type_common.mode)
 #define SET_TYPE_MODE(NODE, MODE) \
   (TYPE_CHECK (NODE)->type_common.mode = (MODE))