https://gcc.gnu.org/g:8c7c10e82d661785181f199fdc6b24890b30a54e

commit r17-4161-g8c7c10e82d661785181f199fdc6b24890b30a54e
Author: Richard Biener <[email protected]>
Date:   Fri Sep 11 10:31:58 2026 +0200

    tree-optimization/127310 - ICE with lane-reducing reduction
    
    The following fixes an issue with wrong loop mask registering
    due to the costing code adjusting ncopies_for_cost before we
    use it for mask registering.
    
            PR tree-optimization/127310
            * tree-vect-loop.cc (vectorizable_lane_reducing): Apply
            costing after registering loop masks.
    
            * gcc.dg/vect/vect-pr127310.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/vect-pr127310.c | 29 +++++++++++++++++++++++
 gcc/tree-vect-loop.cc                     | 38 +++++++++++++++----------------
 2 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr127310.c 
b/gcc/testsuite/gcc.dg/vect/vect-pr127310.c
new file mode 100644
index 000000000000..815b631c0659
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr127310.c
@@ -0,0 +1,29 @@
+/* { dg-additional-options "-march=armv8-a+sve" { target aarch64_sve_hw } } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noipa)) unsigned int
+mixed_dot_induction (unsigned int n)
+{
+  unsigned int sum = 0;
+  for (unsigned int i = 0; i < n; ++i)
+    sum += (signed char) i * (unsigned char) (i * 17 + 3);
+  return sum;
+}
+
+int
+main ()
+{
+  unsigned int expected = 0;
+  check_vect ();
+#pragma GCC novector
+  for (unsigned int n = 0; n <= 1025; ++n)
+    {
+      if (mixed_dot_induction (n) != expected)
+       __builtin_abort ();
+      int x = (int) (n & 127) - (int) (n & 128);
+      int y = (n * 17 + 3) & 255;
+      expected += x * y;
+    }
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 19e7a6fa884f..4a0492381422 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6866,25 +6866,6 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
     }
   gcc_assert (ncopies_for_cost >= 1);
 
-  if (vect_is_emulated_mixed_dot_prod (slp_node))
-    {
-      /* We need extra two invariants: one that contains the minimum signed
-        value and one that contains half of its negative.  */
-      int prologue_stmts = 2;
-      unsigned cost = record_stmt_cost (cost_vec, prologue_stmts,
-                                       scalar_to_vec, slp_node, 0,
-                                       vect_prologue);
-      if (dump_enabled_p ())
-       dump_printf (MSG_NOTE, "vectorizable_lane_reducing: "
-                    "extra prologue_cost = %d .\n", cost);
-
-      /* Three dot-products and a subtraction.  */
-      ncopies_for_cost *= 4;
-    }
-
-  record_stmt_cost (cost_vec, (int) ncopies_for_cost, vector_stmt, slp_node,
-                   0, vect_body);
-
   if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo))
     {
       enum tree_code code = gimple_assign_rhs_code (stmt);
@@ -6905,6 +6886,25 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
        }
     }
 
+  if (vect_is_emulated_mixed_dot_prod (slp_node))
+    {
+      /* We need extra two invariants: one that contains the minimum signed
+        value and one that contains half of its negative.  */
+      int prologue_stmts = 2;
+      unsigned cost = record_stmt_cost (cost_vec, prologue_stmts,
+                                       scalar_to_vec, slp_node, 0,
+                                       vect_prologue);
+      if (dump_enabled_p ())
+       dump_printf (MSG_NOTE, "vectorizable_lane_reducing: "
+                    "extra prologue_cost = %d .\n", cost);
+
+      /* Three dot-products and a subtraction.  */
+      ncopies_for_cost *= 4;
+    }
+
+  record_stmt_cost (cost_vec, (int) ncopies_for_cost, vector_stmt, slp_node,
+                   0, vect_body);
+
   /* Transform via vect_transform_reduction.  */
   SLP_TREE_TYPE (slp_node) = reduc_vec_info_type;
   return true;

Reply via email to