From: glisse Date: Thu, 21 Mar 2013 16:33:33 +0000 (+0000) Subject: 2013-03-21 Marc Glisse X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ee286c80c4d6cb190299e8bf861e3db3c44642f;p=thirdparty%2Fgcc.git 2013-03-21 Marc Glisse 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) : 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196884 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0baa0a9db1c9..3992373c395f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-03-21 Marc Glisse + + * 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) : Merge with the COND_EXPR case. + 2013-03-21 Marc Glisse * simplify-rtx.c (simplify_binary_operation_1) : diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 89a828f4ad29..37b67ce991c4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2013-03-21 Marc Glisse + + * call.c (build_conditional_expr_1): Fold VEC_COND_EXPR. + 2013-03-21 Richard Biener * 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 8362c756c399..5c9c28615df5 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 ae03938e1247..905661cf7e6d 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 eaa6bdcf1a7e..fc3ee606f44d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-03-21 Marc Glisse + + * g++.dg/ext/vector21.C: New testcase. + 2013-03-21 Christophe Lyon * 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 000000000000..71634c327864 --- /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 9aae8df17bc9..f1b988ca7bb5 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))