[gcc r17-3331] middle-end/126788 - more vector folding

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:465ee014cb0cf9be62f0fd3de3821c755d37f58d

commit r17-3331-g465ee014cb0cf9be62f0fd3de3821c755d37f58d
Author: Richard Biener <[email protected]>
Date:   Thu Aug 13 14:57:56 2026 +0200

    middle-end/126788 - more vector folding
    
    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.
    
            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): Leave
            nop-conversions to vectorizable_assignment.
    
            * gcc.target/i386/pr126788.c: New testcase.

Diff:
---
 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(-)

diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
index 5fbdcd3a730d..5360a509f8d8 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 000000000000..0448284e8f68
--- /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 55bd8aee5f83..0044293b7c53 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 a023977bc51f..38a17e29a84c 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5475,7 +5475,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)))
+		/* NOP conversions are handled by vectorizable_assignment.  */
+		return false;
+	    }
 	  else
 	    {
 	      cvt_type = NULL_TREE;
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.