summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-generic.c
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2012-11-02 00:39:44 +0100
committerMarc Glisse <glisse@gcc.gnu.org>2012-11-01 23:39:44 +0000
commit374ab2d79709f570856ee9c4a1f0d82b189b6a0e (patch)
tree1a0502f4a9d8b1bc870689bf54fec5e1cf24b5d3 /gcc/tree-vect-generic.c
parent2328b1de5ebeea8908d5db53c1188b2782d33120 (diff)
downloadgcc-374ab2d79709f570856ee9c4a1f0d82b189b6a0e.tar.gz
re PR middle-end/55001 (Handle VEC_COND_EXPR better in tree-vect-generic.c)
2012-11-01 Marc Glisse <marc.glisse@inria.fr> PR middle-end/55001 gcc/ * tree-vect-generic.c (expand_vector_condition): New function. (expand_vector_operations_1): Call it. testsuite/ * g++.dg/ext/vector19.C: Remove target restrictions. * gcc.dg/fold-compare-7.c: New testcase. From-SVN: r193077
Diffstat (limited to 'gcc/tree-vect-generic.c')
-rw-r--r--gcc/tree-vect-generic.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 9d54bdd99b5..2dec341fc82 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -868,6 +868,72 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
return gimplify_build2 (gsi, MINUS_EXPR, type, op0, tem);
}
+/* Expand a vector condition to scalars, by using many conditions
+ on the vector's elements. */
+static void
+expand_vector_condition (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ tree type = gimple_expr_type (stmt);
+ tree a = gimple_assign_rhs1 (stmt);
+ tree a1 = a;
+ tree a2;
+ bool a_is_comparison = false;
+ tree b = gimple_assign_rhs2 (stmt);
+ tree c = gimple_assign_rhs3 (stmt);
+ VEC(constructor_elt,gc) *v;
+ tree constr;
+ tree inner_type = TREE_TYPE (type);
+ tree cond_type = TREE_TYPE (TREE_TYPE (a));
+ tree comp_inner_type = cond_type;
+ tree width = TYPE_SIZE (inner_type);
+ tree index = bitsize_int (0);
+ int nunits = TYPE_VECTOR_SUBPARTS (type);
+ int i;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
+
+ if (TREE_CODE (a) != SSA_NAME)
+ {
+ gcc_assert (COMPARISON_CLASS_P (a));
+ a_is_comparison = true;
+ a1 = TREE_OPERAND (a, 0);
+ a2 = TREE_OPERAND (a, 1);
+ comp_inner_type = TREE_TYPE (TREE_TYPE (a1));
+ }
+
+ if (expand_vec_cond_expr_p (type, TREE_TYPE (a1)))
+ return;
+
+ /* TODO: try and find a smaller vector type. */
+
+ warning_at (loc, OPT_Wvector_operation_performance,
+ "vector condition will be expanded piecewise");
+
+ v = VEC_alloc(constructor_elt, gc, nunits);
+ for (i = 0; i < nunits;
+ i++, index = int_const_binop (PLUS_EXPR, index, width))
+ {
+ tree aa, result;
+ tree bb = tree_vec_extract (gsi, inner_type, b, width, index);
+ tree cc = tree_vec_extract (gsi, inner_type, c, width, index);
+ if (a_is_comparison)
+ {
+ tree aa1 = tree_vec_extract (gsi, comp_inner_type, a1, width, index);
+ tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2, width, index);
+ aa = build2 (TREE_CODE (a), cond_type, aa1, aa2);
+ }
+ else
+ aa = tree_vec_extract (gsi, cond_type, a, width, index);
+ result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
+ constructor_elt ce = {NULL_TREE, result};
+ VEC_quick_push (constructor_elt, v, ce);
+ }
+
+ constr = build_constructor (type, v);
+ gimple_assign_set_rhs_from_tree (gsi, constr);
+ update_stmt (gsi_stmt (*gsi));
+}
+
static tree
expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
gimple assign, enum tree_code code)
@@ -1248,6 +1314,11 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
return;
}
+ if (code == VEC_COND_EXPR)
+ {
+ expand_vector_condition (gsi);
+ return;
+ }
if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
return;