Hi! This patch fixes two ICEs on the testcases, one is ICE in expand_vector_condition which wouldn't handle VECTOR_CST as first argument of VEC_COND_EXPR (plus a change to make sure it is folded earlier if possible), and the vectorizable_condition change makes sure the condition is actually using a vector of integers instead of vector of floats and similar, which crashes because fold-const.c isn't anywhere close to be prepared for floating point type (or vector float) of NE_EXPR and other comparison tree codes.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2012-11-12 Jakub Jelinek <ja...@redhat.com> 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. * gcc.dg/vect/fast-math-pr55281.c: New test. * g++.dg/opt/pr55281.C: New test. --- gcc/tree-vect-generic.c.jj 2012-11-02 09:01:55.000000000 +0100 +++ gcc/tree-vect-generic.c 2012-11-12 12:14:49.978619417 +0100 @@ -892,7 +892,7 @@ expand_vector_condition (gimple_stmt_ite 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; --- gcc/fold-const.c.jj 2012-11-08 21:08:25.000000000 +0100 +++ gcc/fold-const.c 2012-11-12 15:51:45.118969684 +0100 @@ -14036,6 +14036,16 @@ fold_ternary_loc (location_t loc, enum t 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. */ --- gcc/tree-vect-stmts.c.jj 2012-11-07 08:42:08.000000000 +0100 +++ gcc/tree-vect-stmts.c 2012-11-12 15:29:12.012684236 +0100 @@ -5310,6 +5310,7 @@ vectorizable_condition (gimple stmt, gim 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, gim && 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, gim 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); --- gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c.jj 2012-11-12 15:55:58.069579547 +0100 +++ gcc/testsuite/gcc.dg/vect/fast-math-pr55281.c 2012-11-12 15:56:29.550402151 +0100 @@ -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" } } */ --- gcc/testsuite/g++.dg/opt/pr55281.C.jj 2012-11-12 15:53:50.523289232 +0100 +++ gcc/testsuite/g++.dg/opt/pr55281.C 2012-11-12 15:54:11.529173469 +0100 @@ -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; +} Jakub