The following attempts to make using gimple_build easier during
vectorizer code generation by providing an overload of
vect_finish_stmt_generation that handles a built sequence.
In addition to inserting and finishing stmts on the sequence the
ultimate result is made to be based on the passed vectorizer
temporary (that gets us the fancy names).

I have converted one instance in vectorizable_conversion and
code-generating word_mode operations in vectorizable_operation.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

While this is no longer needed for the folding of .VEC_CONVERTs
it seems still useful.  For v2 I swapped the 'var' argument last
and made it optional (but not defaulted yet), also sanitized
against const qualified vector component types.

HJ reported some ICEs, but they seem unrelated.  I plan to push
this on Monday to give the CI a chance to pick this up.

Richard.

        * tree-vect-stmts.cc (vect_finish_stmt_generation): New
        overload for gimple_build sequences.
        (vectorizable_conversion): Convert one instance of
        vect_gimple_build to gimple_build plus
        vect_finish_stmt_generation.
        (vectorizable_operation): Use gimple_build for code-generating
        word_mode operations.

        * g++.dg/torture/20260817.C: New testcase.
---
 gcc/testsuite/g++.dg/torture/20260817.C |  30 +++++
 gcc/tree-vect-stmts.cc                  | 156 +++++++++++-------------
 2 files changed, 98 insertions(+), 88 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/20260817.C

diff --git a/gcc/testsuite/g++.dg/torture/20260817.C 
b/gcc/testsuite/g++.dg/torture/20260817.C
new file mode 100644
index 00000000000..6a33b3de30e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/20260817.C
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=x86-64-v4" { target { x86_64-*-* i?86-*-* } 
} } */
+
+extern int _M_current;
+extern int end ();
+struct color
+{
+  char r;
+  struct
+  {
+    unsigned char g;
+    unsigned char b;
+  } m_24bit;
+  color (char g, char b)
+  {
+    m_24bit.g = g;
+    m_24bit.b = b;
+  }
+};
+void
+set_style_bg_color (color)
+{
+  for (;;)
+    {
+      const unsigned char g = _M_current;
+      if (end ())
+break;
+      set_style_bg_color (color (g, _M_current));
+    }
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index a8a2ec62920..27dcbe23b74 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -1260,7 +1260,7 @@ vect_get_vec_defs (vec_info *, slp_tree slp_node,
 
 /* Helper function called by vect_finish_replace_stmt and
    vect_finish_stmt_generation.  Set the location of the new
-   statement and create and return a stmt_vec_info for it.  */
+   statement.  */
 
 static void
 vect_finish_stmt_generation_1 (vec_info *,
@@ -1285,8 +1285,7 @@ vect_finish_stmt_generation_1 (vec_info *,
 }
 
 /* Replace the scalar statement STMT_INFO with a new vector statement VEC_STMT,
-   which sets the same scalar result as STMT_INFO did.  Create and return a
-   stmt_vec_info for VEC_STMT.  */
+   which sets the same scalar result as STMT_INFO did.  */
 
 void
 vect_finish_replace_stmt (vec_info *vinfo,
@@ -1302,7 +1301,7 @@ vect_finish_replace_stmt (vec_info *vinfo,
 }
 
 /* Add VEC_STMT to the vectorized implementation of STMT_INFO and insert it
-   before *GSI.  Create and return a stmt_vec_info for VEC_STMT.  */
+   before *GSI.  */
 
 void
 vect_finish_stmt_generation (vec_info *vinfo,
@@ -1344,6 +1343,32 @@ vect_finish_stmt_generation (vec_info *vinfo,
   vect_finish_stmt_generation_1 (vinfo, stmt_info, vec_stmt);
 }
 
+/* Add the stmts in STMTS to the vectorized implementation of STMT_INFO and
+   insert them before *GSI.  Make sure the final stmt has a result
+   based on VAR if not NULL.  */
+
+static void
+vect_finish_stmt_generation (vec_info *vinfo,
+                            stmt_vec_info stmt_info, gimple_seq &stmts,
+                            gimple_stmt_iterator *gsi, tree var)
+{
+  auto si = gsi_start (stmts);
+  while (!gsi_end_p (si))
+    {
+      gimple *new_stmt = gsi_stmt (si);
+      gsi_remove (&si, false);
+      if (var && gsi_end_p (si))
+       {
+         tree lhs = gimple_get_lhs (new_stmt);
+         gcc_assert (!SSA_NAME_VAR (lhs));
+         if (TREE_TYPE (lhs) == TREE_TYPE (var))
+           SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
+       }
+      vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+    }
+}
+
+
 /* We want to vectorize a call to combined function CFN with function
    decl FNDECL, using VECTYPE_OUT as the type of the output and VECTYPE_IN
    as the types of all inputs.  Check whether this is possible using
@@ -5804,12 +5829,11 @@ vectorizable_conversion (vec_info *vinfo,
            }
          else
            {
-             new_stmt = vect_gimple_build (vec_dest, code1, vop0);
-             new_temp = make_ssa_name (vec_dest, new_stmt);
-             gimple_set_lhs (new_stmt, new_temp);
-             vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-
-             slp_node->push_vec_def (new_stmt);
+             gimple_seq stmts = NULL;
+             new_temp = gimple_build (&stmts, code1, vectype_out, vop0);
+             vect_finish_stmt_generation (vinfo, stmt_info,
+                                          stmts, gsi, vec_dest);
+             slp_node->push_vec_def (new_temp);
            }
        }
       break;
@@ -6968,20 +6992,12 @@ vectorizable_operation (vec_info *vinfo,
          /* Lower the operation.  This follows vector lowering.  */
          tree word_type = build_nonstandard_integer_type
                             (GET_MODE_BITSIZE (vec_mode).to_constant (), 1);
-         tree wvop0 = make_ssa_name (word_type);
-         new_stmt = gimple_build_assign (wvop0, VIEW_CONVERT_EXPR,
-                                         build1 (VIEW_CONVERT_EXPR,
-                                                 word_type, vop0));
-         vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+         gimple_seq stmts = NULL;
+         tree wvop0 = gimple_build (&stmts,
+                                    VIEW_CONVERT_EXPR, word_type, vop0);
          tree wvop1 = NULL_TREE;
          if (vop1)
-           {
-             wvop1 = make_ssa_name (word_type);
-             new_stmt = gimple_build_assign (wvop1, VIEW_CONVERT_EXPR,
-                                             build1 (VIEW_CONVERT_EXPR,
-                                                     word_type, vop1));
-             vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-           }
+           wvop1 = gimple_build (&stmts, VIEW_CONVERT_EXPR, word_type, vop1);
 
          tree result_low;
          if (code == PLUS_EXPR || code == MINUS_EXPR || code == NEGATE_EXPR)
@@ -6997,80 +7013,44 @@ vectorizable_operation (vec_info *vinfo,
              tree signs;
              if (code == PLUS_EXPR || code == MINUS_EXPR)
                {
-                 signs = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (signs,
-                                                 BIT_XOR_EXPR, wvop0, wvop1);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 tree b_low = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (b_low, BIT_AND_EXPR,
-                                                 wvop1, low_bits);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 tree a_low = make_ssa_name (word_type);
+                 signs = gimple_build (&stmts, BIT_XOR_EXPR,
+                                       word_type, wvop0, wvop1);
+                 tree b_low = gimple_build (&stmts, BIT_AND_EXPR,
+                                            word_type, wvop1, low_bits);
+                 tree a_low;
                  if (code == PLUS_EXPR)
-                   new_stmt = gimple_build_assign (a_low, BIT_AND_EXPR,
-                                                   wvop0, low_bits);
+                   a_low = gimple_build (&stmts, BIT_AND_EXPR,
+                                         word_type, wvop0, low_bits);
                  else
-                   new_stmt = gimple_build_assign (a_low, BIT_IOR_EXPR,
-                                                   wvop0, high_bits);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+                   a_low = gimple_build (&stmts, BIT_IOR_EXPR,
+                                         word_type, wvop0, high_bits);
                  if (code == MINUS_EXPR)
-                   {
-                     new_stmt = gimple_build_assign (NULL_TREE,
-                                                     BIT_NOT_EXPR, signs);
-                     signs = make_ssa_name (word_type);
-                     gimple_assign_set_lhs (new_stmt, signs);
-                     vect_finish_stmt_generation (vinfo, stmt_info,
-                                                  new_stmt, gsi);
-                   }
-                 new_stmt = gimple_build_assign (NULL_TREE, BIT_AND_EXPR,
-                                                 signs, high_bits);
-                 signs = make_ssa_name (word_type);
-                 gimple_assign_set_lhs (new_stmt, signs);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 result_low = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (result_low, code,
-                                                 a_low, b_low);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+                   signs = gimple_build (&stmts, BIT_NOT_EXPR,
+                                         word_type, signs);
+                 signs = gimple_build (&stmts, BIT_AND_EXPR,
+                                       word_type, signs, high_bits);
+                 result_low = gimple_build (&stmts, code,
+                                            word_type, a_low, b_low);
                }
              else /* if (code == NEGATE_EXPR) */
                {
-                 tree a_low = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (a_low, BIT_AND_EXPR,
-                                                 wvop0, low_bits);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 signs = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (signs, BIT_NOT_EXPR, wvop0);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 new_stmt = gimple_build_assign (NULL_TREE, BIT_AND_EXPR,
-                                                 signs, high_bits);
-                 signs = make_ssa_name (word_type);
-                 gimple_assign_set_lhs (new_stmt, signs);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-                 result_low = make_ssa_name (word_type);
-                 new_stmt = gimple_build_assign (result_low,
-                                                 MINUS_EXPR, high_bits, a_low);
-                 vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+                 tree a_low = gimple_build (&stmts, BIT_AND_EXPR,
+                                            word_type, wvop0, low_bits);
+                 signs = gimple_build (&stmts, BIT_NOT_EXPR,
+                                       word_type, wvop0);
+                 signs = gimple_build (&stmts, BIT_AND_EXPR,
+                                       word_type, signs, high_bits);
+                 result_low = gimple_build (&stmts, MINUS_EXPR,
+                                            word_type, high_bits, a_low);
                }
-             new_stmt = gimple_build_assign (NULL_TREE, BIT_XOR_EXPR,
-                                             result_low, signs);
-             result_low = make_ssa_name (word_type);
-             gimple_assign_set_lhs (new_stmt, result_low);
-             vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+             result_low = gimple_build (&stmts, BIT_XOR_EXPR,
+                                        word_type, result_low, signs);
            }
          else
-           {
-             new_stmt = gimple_build_assign (NULL_TREE, code, wvop0, wvop1);
-             result_low = make_ssa_name (word_type);
-             gimple_assign_set_lhs (new_stmt, result_low);
-             vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
-
-           }
-         new_stmt = gimple_build_assign (NULL_TREE, VIEW_CONVERT_EXPR,
-                                         build1 (VIEW_CONVERT_EXPR,
-                                                 vectype, result_low));
-         new_temp = make_ssa_name (vectype);
-         gimple_assign_set_lhs (new_stmt, new_temp);
-         vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+           result_low = gimple_build (&stmts, code, word_type, wvop0, wvop1);
+         new_temp = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                  vectype, result_low);
+         vect_finish_stmt_generation (vinfo, stmt_info, stmts, gsi, vec_dest);
        }
       else if ((masked_loop_p || len_loop_p) && mask_out_inactive)
        {
@@ -7174,7 +7154,7 @@ vectorizable_operation (vec_info *vinfo,
                                       new_stmt, gsi);
        }
 
-      slp_node->push_vec_def (new_stmt);
+      slp_node->push_vec_def (new_temp);
     }
 
   vec_oprnds0.release ();
-- 
2.51.0

Reply via email to