diff options
author | Marc Glisse <marc.glisse@inria.fr> | 2012-11-02 00:39:44 +0100 |
---|---|---|
committer | Marc Glisse <glisse@gcc.gnu.org> | 2012-11-01 23:39:44 +0000 |
commit | 374ab2d79709f570856ee9c4a1f0d82b189b6a0e (patch) | |
tree | 1a0502f4a9d8b1bc870689bf54fec5e1cf24b5d3 /gcc | |
parent | 2328b1de5ebeea8908d5db53c1188b2782d33120 (diff) | |
download | gcc-374ab2d79709f570856ee9c4a1f0d82b189b6a0e.zip gcc-374ab2d79709f570856ee9c4a1f0d82b189b6a0e.tar.gz gcc-374ab2d79709f570856ee9c4a1f0d82b189b6a0e.tar.bz2 |
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')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/vector19.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-compare-7.c | 8 | ||||
-rw-r--r-- | gcc/tree-vect-generic.c | 71 |
5 files changed, 93 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d079b6c..b59e1cb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-11-01 Marc Glisse <marc.glisse@inria.fr> + + PR middle-end/55001 + * tree-vect-generic.c (expand_vector_condition): New function. + (expand_vector_operations_1): Call it. + 2012-11-01 Steve Ellcey <sellcey@mips.com> * target-globals.c (save_target_globals): Save lra_int struct. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c59446..ed39860 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-11-01 Marc Glisse <marc.glisse@inria.fr> + + PR middle-end/55001 + * g++.dg/ext/vector19.C: Remove target restrictions. + * gcc.dg/fold-compare-7.c: New testcase. + 2012-11-01 Oleg Endo <olegendo@gcc.gnu.org> PR target/55160 diff --git a/gcc/testsuite/g++.dg/ext/vector19.C b/gcc/testsuite/g++.dg/ext/vector19.C index ec08e7c..ace1c64 100644 --- a/gcc/testsuite/g++.dg/ext/vector19.C +++ b/gcc/testsuite/g++.dg/ext/vector19.C @@ -1,8 +1,5 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-std=c++11 -mavx2" } */ - -// The target restrictions and the -mavx2 flag are meant to disappear -// once vector lowering is in place. +/* { dg-do compile } */ +/* { dg-options "-std=c++11" } */ typedef double vec __attribute__((vector_size(2*sizeof(double)))); typedef signed char vec2 __attribute__((vector_size(16))); diff --git a/gcc/testsuite/gcc.dg/fold-compare-7.c b/gcc/testsuite/gcc.dg/fold-compare-7.c new file mode 100644 index 0000000..8296751 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-compare-7.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef float vecf __attribute__((vector_size(8*sizeof(float)))); + +long f(vecf *f1, vecf *f2){ + return ((*f1 == *f2) < 0)[2]; +} diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 9d54bdd..2dec341 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; |