This is a suggestion from Richi in the PR.
The RISC-V backend calls the loop initialization routines during setup
for vsetvl insertion/optimization. Right now that uses LOOPS_NORMAL
which allows various adjustments to the loop structure. The interaction
between those CFG adjustments and asm goto support is putting the CFG
into an undesirable state.
There's potentially an issue in the CFG layout bits, but we can punt
that out by using AVOID_CFG_MODIFICATIONS when calling
loop_optimizer_init. My review of the vsetvl code doesn't show any
direct need for clean preheaders, latches, etc -- the biggest thing it
needs is for infinite loops to be connected to the exit block which is
handled outside of loop_optimizer_init.
So this is a workaround, but enough to get the PR off the regression list.
Waiting for pre-commit CI to do its thing, though it has already passed
riscv{32,64}-elf for me. Bootstrap on the Pioneer is in flight.
Jeff
PR rtl-optimization/121787
gcc/
* config/riscv/riscv-vsetvl.cc (pre_vsetvl): Adjust call to
loop_optimizer_init to avoid making CFG changes.
gcc/testsuite/
* gcc.target/riscv/pr121787-1.c: New test.
* gcc.target/riscv/pr121787-2.c: New test.
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 7b7003ff5fd..64fa809b801 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2422,7 +2422,7 @@ public:
{
/* Initialization of RTL_SSA. */
calculate_dominance_info (CDI_DOMINATORS);
- loop_optimizer_init (LOOPS_NORMAL);
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
/* Create FAKE edges for infinite loops. */
connect_infinite_loops_to_exit ();
df_analyze ();
diff --git a/gcc/testsuite/gcc.target/riscv/pr121787-1.c
b/gcc/testsuite/gcc.target/riscv/pr121787-1.c
new file mode 100644
index 00000000000..4180a545202
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr121787-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O" { target rv64 } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -O" { target rv32 } } */
+
+#include <stdint-gcc.h>
+typedef int a;
+int32_t b, e;
+int32_t **c;
+uint8_t d(int32_t *, int32_t *, uint16_t, const int32_t *, int32_t **);
+uint32_t f() {
+ uint16_t g;
+ d(0, &b, g, &b, c);
+ e = (__attribute__((__vector_size__(sizeof(a)))) a){}[4];
+}
+uint8_t d(int32_t *, int32_t *, uint16_t, const int32_t *, int32_t **) {
+ asm goto("" : : : : i);
+i:
+j:
+ asm goto("" : : : : j);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr121787-2.c
b/gcc/testsuite/gcc.target/riscv/pr121787-2.c
new file mode 100644
index 00000000000..f3be37b1a2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr121787-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O" { target rv64 } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32 -O" { target rv32 } } */
+
+#include <stdint-gcc.h>
+typedef int a;
+int32_t b, e;
+int32_t **c;
+uint8_t d(int32_t *, int32_t *, uint16_t, const int32_t *, int32_t **);
+uint32_t f(int a1) {
+ uint16_t g;
+ d(0, &b, g, &b, c);
+ e = (__attribute__((__vector_size__(sizeof(a)*16))) a){}[a1];
+}
+uint8_t d(int32_t *, int32_t *, uint16_t, const int32_t *, int32_t **) {
+ asm goto("#asm1" : : : : i);
+i:
+j:
+ asm goto("#asm2" : : : : j);
+}