@@ -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;
@@ -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. */
@@ -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);
@@ -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" } } */
@@ -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;
+}