[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.