]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
forwprop: Handle nop-conversion for maybe_ident. [PR123925]
authorRobin Dapp <rdapp@oss.qualcomm.com>
Mon, 2 Feb 2026 20:48:05 +0000 (21:48 +0100)
committerRobin Dapp <rdapp@oss.qualcomm.com>
Thu, 5 Feb 2026 09:52:40 +0000 (10:52 +0100)
The same handling for nop conversions we did in the !maybe_ident case is
also necessary in for maybe_ident.  This patch performs the necessary
preprocessing before the if and unifies the nop-conversion handling.

PR tree-optimization/123925

gcc/ChangeLog:

* tree-ssa-forwprop.cc (simplify_vector_constructor):
Add nop-conversion handling for maybe_ident.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/pr123925.c: New test.

Signed-off-by: Robin Dapp <rdapp@oss.qualcomm.com>
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.cc

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123925.c
new file mode 100644 (file)
index 0000000..c209387
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target riscv_v_ok } */
+/* { dg-add-options riscv_v } */
+/* { dg-additional-options "-std=gnu99" } */
+
+typedef __attribute__((__vector_size__ (8))) unsigned char U;
+typedef __attribute__((__vector_size__ (8))) signed long V;
+
+signed char s;
+V v;
+
+void
+__attribute__ ((noipa))
+foo (U u, V *r)
+{
+  __builtin_memmove (&s, &u, 1);
+  v += s;
+  *r = v;
+}
+
+int
+main ()
+{
+  V x;
+  foo ((U) {248}, &x);
+  if (x[0] != -8)
+    __builtin_abort();
+}
index cea5e70dd75b6622da2806cb5cafb1f8a6924a56..74e2875d769365bb6935bd90374d0b043335962b 100644 (file)
@@ -3975,14 +3975,29 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
   if (refnelts < nelts)
     return false;
 
+  /* Determine the element type for the conversion source.
+     As orig_elem_type keeps track of the original type, check
+     if we need to perform a sign swap after permuting.
+     We need to be able to construct a vector type from the element
+     type which is not possible for e.g. BitInt or pointers
+     so pun with an integer type if needed.   */
+  tree perm_eltype = TREE_TYPE (TREE_TYPE (orig[0]));
+  bool sign_change_p = false;
+  if (conv_code != ERROR_MARK
+      && orig_elem_type[0]
+      && TYPE_SIGN (orig_elem_type[0]) != TYPE_SIGN (perm_eltype))
+    {
+      perm_eltype = signed_or_unsigned_type_for
+       (TYPE_UNSIGNED (orig_elem_type[0]), perm_eltype);
+      sign_change_p = true;
+    }
+  tree conv_src_type = build_vector_type (perm_eltype, nelts);
+
   if (maybe_ident)
     {
-      tree conv_src_type
-       = (nelts != refnelts
-          ? (conv_code != ERROR_MARK
-             ? build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])), nelts)
-             : type)
-          : TREE_TYPE (orig[0]));
+      /* When there is no conversion, use the target type directly.  */
+      if (conv_code == ERROR_MARK && nelts != refnelts)
+       conv_src_type = type;
       if (conv_code != ERROR_MARK
          && !supportable_convert_operation (conv_code, type, conv_src_type,
                                             &conv_code))
@@ -4104,6 +4119,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
          gsi_insert_before (gsi, lowpart, GSI_SAME_STMT);
          orig[0] = gimple_assign_lhs (lowpart);
        }
+      else if (sign_change_p)
+       {
+         gassign *conv
+           = gimple_build_assign (make_ssa_name (conv_src_type),
+                                  build1 (VIEW_CONVERT_EXPR, conv_src_type,
+                                          orig[0]));
+         gsi_insert_before (gsi, conv, GSI_SAME_STMT);
+         orig[0] = gimple_assign_lhs (conv);
+       }
       if (conv_code == ERROR_MARK)
        {
          tree src_type = TREE_TYPE (orig[0]);
@@ -4135,22 +4159,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
          && orig[1] == error_mark_node
          && !maybe_blend[0])
        return false;
-      tree mask_type, perm_type, conv_src_type;
+      tree mask_type, perm_type;
       perm_type = TREE_TYPE (orig[0]);
-      /* Determine the element type for the conversion source.
-        As orig_elem_type keeps track of the original type, check
-        if we need to perform a sign swap after permuting.
-        We need to be able to construct a vector type from the element
-        type which is not possible for e.g. BitInt or pointers
-        so pun with an integer type if needed.  */
-      tree conv_elem_type = TREE_TYPE (perm_type);
-      if (conv_code != ERROR_MARK
-         && orig_elem_type[0]
-         && TYPE_SIGN (orig_elem_type[0]) != TYPE_SIGN (conv_elem_type))
-       conv_elem_type = signed_or_unsigned_type_for (TYPE_UNSIGNED
-                                                     (orig_elem_type[0]),
-                                                     conv_elem_type);
-      conv_src_type = build_vector_type (conv_elem_type, nelts);
       if (conv_code != ERROR_MARK
          && !supportable_convert_operation (conv_code, type, conv_src_type,
                                             &conv_code))
@@ -4280,8 +4290,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
       /* Otherwise, we can still have an intermediate sign change.
         ??? In that case we have two subsequent conversions.
         We should be able to merge them.  */
-      else if (conv_code != ERROR_MARK
-              && tree_nop_conversion_p (conv_src_type, perm_type))
+      else if (sign_change_p)
        res = gimple_build (&stmts, VIEW_CONVERT_EXPR, conv_src_type, res);
       /* Finally, apply the conversion.  */
       if (conv_code != ERROR_MARK)