The testcase

char a;
int b;
void e() {
  char *c = (char *)&b;
  int d = 0;
  for (; d < b; d++)
    a += c[d];
}

ICEs with -O2 -mgeneral-regs-only  -march=armv9-a

with a segfault in single cycle detection:

internal compiler error: Segmentation fault
//   446 | ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
//       | ^~~~~~~~~~~~~~~~~~~~
// 0xf3fc23 internal_error(char const*, ...)
//      ../../src/gcc/diagnostic-global-context.cc:787
// 0x976543 crash_signal
//      ../../src/gcc/toplev.cc:325
// 0x1e43f74 info_for_reduction(_loop_vec_info*, _slp_tree*)
//      ../../src/gcc/tree-vect-loop.cc:5060
// 0x1a7946f aarch64_force_single_cycle
//      ../../src/gcc/config/aarch64/aarch64.cc:18284

This is because the slp_node is null and so looking
up the reduction info fails.

With -mgeneral-regs the SIMD reduction instructions
become unavailable, so the vectorizer tries to emulate them.

This enters a branch in vectorizable_operation where
it looks like we forgot to update the costing code from
using stmt_vinfo to the slp_node during the SLP only
costing transition.  As such it uses the old interface which
does not provide the required SLP node and we ICE.

The fix is to use the slp_node instead of the stmt_info.

Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.

Pushed.

Thanks,
Tamar

gcc/ChangeLog:

        PR tree-optimization/127579
        * tree-vect-loop.cc (info_for_reduction):
        * tree-vect-stmts.cc (vectorizable_operation):

gcc/testsuite/ChangeLog:

        PR tree-optimization/127579
        * gcc.target/aarch64/pr127579.c: New test.

---
diff --git a/gcc/testsuite/gcc.target/aarch64/pr127579.c 
b/gcc/testsuite/gcc.target/aarch64/pr127579.c
new file mode 100644
index 
0000000000000000000000000000000000000000..1f9eb6af741c74d78d7b3d8f6e8e3f9a67e098dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr127579.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -mgeneral-regs-only -march=armv9-a" } */
+
+char a;
+int b;
+void e() {
+  char *c = (char *)&b;
+  int d = 0;
+  for (; d < b; d++)
+    a += c[d];
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 
e724a8f6086e1cb769a18a5a9a30f4fc8e96f115..99dda5b1e00540377440209cdef10ae2731004d0
 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -5041,6 +5041,7 @@ get_initial_defs_for_reduction (loop_vec_info loop_vinfo,
 vect_reduc_info
 info_for_reduction (loop_vec_info loop_vinfo, slp_tree node)
 {
+  gcc_assert (node);
   if (node->cycle_info.id == -1)
     return NULL;
   return loop_vinfo->reduc_infos[node->cycle_info.id];
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 
9cfec1bb4ac57b614840bf07071a4d05acdfc4b4..69e1bdc2cac7676f15bddd4898567bc2ad263d44
 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -6883,9 +6883,9 @@ vectorizable_operation (vec_info *vinfo,
          if (n != 0)
            {
              /* We also need to materialize two large constants.  */
-             record_stmt_cost (cost_vec, 2, scalar_stmt, stmt_info,
+             record_stmt_cost (cost_vec, 2, scalar_stmt, slp_node,
                                0, vect_prologue);
-             record_stmt_cost (cost_vec, n, scalar_stmt, stmt_info,
+             record_stmt_cost (cost_vec, n, scalar_stmt, slp_node,
                                0, vect_body);
            }
        }


-- 
diff --git a/gcc/testsuite/gcc.target/aarch64/pr127579.c b/gcc/testsuite/gcc.target/aarch64/pr127579.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f9eb6af741c74d78d7b3d8f6e8e3f9a67e098dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr127579.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -mgeneral-regs-only -march=armv9-a" } */
+
+char a;
+int b;
+void e() {
+  char *c = (char *)&b;
+  int d = 0;
+  for (; d < b; d++)
+    a += c[d];
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index e724a8f6086e1cb769a18a5a9a30f4fc8e96f115..99dda5b1e00540377440209cdef10ae2731004d0 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -5041,6 +5041,7 @@ get_initial_defs_for_reduction (loop_vec_info loop_vinfo,
 vect_reduc_info
 info_for_reduction (loop_vec_info loop_vinfo, slp_tree node)
 {
+  gcc_assert (node);
   if (node->cycle_info.id == -1)
     return NULL;
   return loop_vinfo->reduc_infos[node->cycle_info.id];
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 9cfec1bb4ac57b614840bf07071a4d05acdfc4b4..69e1bdc2cac7676f15bddd4898567bc2ad263d44 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -6883,9 +6883,9 @@ vectorizable_operation (vec_info *vinfo,
 	  if (n != 0)
 	    {
 	      /* We also need to materialize two large constants.  */
-	      record_stmt_cost (cost_vec, 2, scalar_stmt, stmt_info,
+	      record_stmt_cost (cost_vec, 2, scalar_stmt, slp_node,
 				0, vect_prologue);
-	      record_stmt_cost (cost_vec, n, scalar_stmt, stmt_info,
+	      record_stmt_cost (cost_vec, n, scalar_stmt, slp_node,
 				0, vect_body);
 	    }
 	}

Reply via email to