diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c5a80e1732b..b238d64ad56 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2012-11-13 Jakub Jelinek + PR tree-optimization/55281 + * tree-vect-generic.c (expand_vector_condition): Accept any + is_gimple_val rather than just SSA_NAME if not COMPARISON_CLASS_P. + * fold-const.c (fold_ternary_loc): Fold VEC_COND_EXPR if arg0 is + either integer_all_onesp or integer_zerop. + * tree-vect-stmts.c (vectorizable_condition): Build the condition + using corresponding vector integer type instead of vectype. + PR rtl-optimization/54127 * cfgrtl.c (force_nonfallthru_and_redirect): When redirecting asm goto labels from BB_HEAD (e->dest) to target bb, decrement diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4fa1fd670aa..2e908648451 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14036,6 +14036,16 @@ 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 8a369247cb0..5e6e65b6c15 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2012-11-13 Jakub Jelinek + PR tree-optimization/55281 + * gcc.dg/vect/fast-math-pr55281.c: New test. + * g++.dg/opt/pr55281.C: New test. + PR rtl-optimization/54127 * gcc.dg/torture/pr54127.c: New test. diff --git a/gcc/testsuite/g++.dg/opt/pr55281.C b/gcc/testsuite/g++.dg/opt/pr55281.C new file mode 100644 index 00000000000..7076a19c836 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr55281.C @@ -0,0 +1,17 @@ +// PR tree-optimization/55281 +// { dg-do compile } +// { dg-options "-Ofast" } + +typedef float VF __attribute__((vector_size (16))); + +VF x; + +void +foo (void) +{ + VF a, b, c; + a = (VF) { 1.0, 2.0, 3.0, 4.0 }; + b = (VF) { 5.0, 6.0, 7.0, 8.0 }; + c = (VF) { 0.0, 0.0, 0.0, 0.0 }; + x = c == ((VF) { 0.0, 0.0, 0.0, 0.0 }) ? a : b; +} diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c b/gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c new file mode 100644 index 00000000000..4d75403e77d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/55281 */ +/* { dg-do compile } */ + +static inline float +bar (float k, float j) +{ + float l = 0.0f; + if (k > j) + l = k; + float t = k / j; + float v = t * t; + if (k == 0) + v = 0.0f; + if (t > 0.4f) + v += 0.7; + if (l != 0) + v = 1.5 - v; + return v; +} + +void +foo (int *a, int b, float *d, float *e, int *f) +{ + int i, l; + for (l = 0; l != b; ++l) + for (i = 0; i != 8; ++i) + f[i] = e[i] + bar (a[i], d[i]); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 2dec341fc82..611666f2c86 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -892,7 +892,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi) int i; location_t loc = gimple_location (gsi_stmt (*gsi)); - if (TREE_CODE (a) != SSA_NAME) + if (!is_gimple_val (a)) { gcc_assert (COMPARISON_CLASS_P (a)); a_is_comparison = true; diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 2731084624c..2f4be11703b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -5310,6 +5310,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL; VEC (tree, heap) *vec_oprnds2 = NULL, *vec_oprnds3 = NULL; + tree vec_cmp_type = vectype; if (slp_node || PURE_SLP_STMT (stmt_info)) ncopies = 1; @@ -5382,6 +5383,15 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, && TREE_CODE (else_clause) != FIXED_CST) return false; + if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype))) + { + unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vectype))); + tree cmp_type = build_nonstandard_integer_type (prec, 1); + vec_cmp_type = get_same_sized_vectype (cmp_type, vectype); + if (vec_cmp_type == NULL_TREE) + return false; + } + if (!vec_stmt) { STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; @@ -5488,8 +5498,8 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, vec_then_clause = VEC_index (tree, vec_oprnds2, i); vec_else_clause = VEC_index (tree, vec_oprnds3, i); - vec_compare = build2 (TREE_CODE (cond_expr), vectype, - vec_cond_lhs, vec_cond_rhs); + vec_compare = build2 (TREE_CODE (cond_expr), vec_cmp_type, + vec_cond_lhs, vec_cond_rhs); vec_cond_expr = build3 (VEC_COND_EXPR, vectype, vec_compare, vec_then_clause, vec_else_clause);