aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2013-03-21 17:33:33 +0100
committerMarc Glisse <glisse@gcc.gnu.org>2013-03-21 16:33:33 +0000
commit08e0cda61db940bb3b312b44b6d96219f697c27a (patch)
tree32255bfeab9804ebb6cbd03117e49ca038c33706
parentd08633b496a5820431e4049ee8a564796a42114d (diff)
downloadgcc-08e0cda61db940bb3b312b44b6d96219f697c27a.zip
gcc-08e0cda61db940bb3b312b44b6d96219f697c27a.tar.gz
gcc-08e0cda61db940bb3b312b44b6d96219f697c27a.tar.bz2
tree.h (VECTOR_TYPE_P): New macro.
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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/call.c4
-rw-r--r--gcc/fold-const.c26
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ext/vector21.C39
-rw-r--r--gcc/tree.h16
7 files changed, 83 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0baa0a9..3992373 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 89a828f..37b67ce 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8362c75..5c9c286 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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]
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ae03938..905661c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eaa6bdc..fc3ee60 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..71634c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector21.C
@@ -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" } } */
diff --git a/gcc/tree.h b/gcc/tree.h
index 9aae8df..f1b988c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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))