[PATCH 2/2] middle-end/126788 - more vector folding
Richard Biener <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
The last match.pd update for double-conversion folding didn't handle
the case where a vector conversion would go away because
supportable_convert_operation doesn't consider a noop conversion
(or a sign conversion). The following rectifies this, allowing
a NOP_EXPR and VIEW_CONVERT_EXPR for same mode types as supportable
conversion as we can RTL expand that just fine.
This shows that the vectorizer routed sign-conversions through
vectorizable_assignment but now vectorizable_conversion would
handle it, emitting NOP_EXPRs (which is fine) instead of
VIEW_CONVERT_EXPRs (which we declared canonical for vectors).
This would confuse some foldings, leading to testsuite FAILs,
so make vectorizable_conversion also prefer VIEW_CONVERT_EXPRs
here.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
I'll wait on comments on 1/2 before pushing.
Richard.
PR middle-end/126788
* optabs-tree.cc (supportable_convert_operation): For same
modes allow NOP_EXPR and VIEW_CONVERT_EXPR.
* tree-ssa-forwprop.cc (simplify_vector_constructor): Avoid
converting the vector to be used for blending into the
result to the type of the permutation.
* tree-vect-stmts.cc (vectorizable_conversion): Prefer
VIEW_CONVERT_EXPR for sign changes.
* gcc.target/i386/pr126788.c: New testcase.
---
gcc/optabs-tree.cc | 4 ++++
gcc/testsuite/gcc.target/i386/pr126788.c | 24 ++++++++++++++++++++++++
gcc/tree-ssa-forwprop.cc | 1 +
gcc/tree-vect-stmts.cc | 9 ++++++++-
4 files changed, 37 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr126788.c
diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
index 5fbdcd3a730..5360a509f8d 100644
--- a/gcc/optabs-tree.cc
+++ b/gcc/optabs-tree.cc
@@ -375,6 +375,10 @@ supportable_convert_operation (enum tree_code code,
if (!VECTOR_MODE_P (m1) || !VECTOR_MODE_P (m2))
return false;
+ if (m1 == m2
+ && (CONVERT_EXPR_CODE_P (code) || code == VIEW_CONVERT_EXPR))
+ return true;
+
/* First check if we can done conversion directly. */
if ((code == FIX_TRUNC_EXPR
&& can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
diff --git a/gcc/testsuite/gcc.target/i386/pr126788.c b/gcc/testsuite/gcc.target/i386/pr126788.c
new file mode 100644
index 00000000000..0448284e8f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126788.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msse2" } */
+
+typedef int v2si __attribute__((vector_size (8)));
+typedef unsigned int v2usi __attribute__((vector_size (8)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+v2si
+f1 (v2si a, v2si b)
+{
+
+ v2di z = __builtin_convertvector (a, v2di);
+ return __builtin_convertvector (z, v2si);
+}
+
+v2usi
+f2 (v2si a, v2si b)
+{
+
+ v2di z = __builtin_convertvector (a, v2di);
+ return __builtin_convertvector (z, v2usi);
+}
+
+/* { dg-final { scan-assembler-not "xmm" { target { ! ia32 } } } } */
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 55bd8aee5f8..0044293b7c5 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -4363,6 +4363,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
/* For a real orig[1] (no splat, constant etc.) we might need to
nop-convert it. Do so here. */
if (orig[1] && orig[1] != error_mark_node
+ && !converted_orig1
&& !useless_type_conversion_p (perm_type, TREE_TYPE (orig[1]))
&& tree_nop_conversion_p (TREE_TYPE (perm_type),
TREE_TYPE (TREE_TYPE (orig[1]))))
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 44090015e7a..070981dbdb3 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5499,7 +5499,14 @@ vectorizable_conversion (vec_info *vinfo,
{
gcc_assert (converts.length () <= 2);
if (converts.length () == 1)
- code1 = converts[0].second;
+ {
+ code1 = converts[0].second;
+ if (CONVERT_EXPR_CODE_P (code)
+ && tree_nop_conversion_p (TREE_TYPE (vectype_out),
+ TREE_TYPE (vectype_in)))
+ /* Prefer VIEW_CONVERT_EXPR for sign-changes. */
+ code1 = VIEW_CONVERT_EXPR;
+ }
else
{
cvt_type = NULL_TREE;
--
2.51.0