]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] RISC-V: Fix splitter [PR125670].
authorRobin Dapp <rdapp.gcc@gmail.com>
Tue, 16 Jun 2026 12:54:48 +0000 (06:54 -0600)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Tue, 16 Jun 2026 12:54:48 +0000 (06:54 -0600)
Hi,

In the PR we ICE during vsetvl, expecting a register in the VL operand
slot which only contains an immediate 4.  Non-VLMAX insns with immediate
length have a NULL_RTX in that slot.

However, during a split, we erroneously use operand[5] instead of
operand[6].  operand[5] is the mask policy and happened to be "1".
"1" indicates a VLMAX insn in the avl_type operand.  This caused the
wrong turn in vsetvl.

The patch just corrects the operand number.

Regtested on rv64gcv_zvl512b.  Going to wait for the CI.

Regards
 Robin

PR target/125670

gcc/ChangeLog:

* config/riscv/autovec-opt.md: Use avl_type operand number.

gcc/testsuite/ChangeLog:

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

gcc/config/riscv/autovec-opt.md
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr125670.c [new file with mode: 0644]

index 497189cf18523e7c45180a7028a6cff8e1064444..f44813df3bf22501219036f97989069afeca254f 100644 (file)
@@ -53,7 +53,7 @@
   {
     emit_insn (gen_pred_mov (<MODE>mode, operands[0], CONST1_RTX (<MODE>mode),
                             RVV_VUNDEF (<MODE>mode), operands[3],
-                            operands[4], operands[5]));
+                            operands[4], operands[6]));
     DONE;
   }
 )
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr125670.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr125670.c
new file mode 100644 (file)
index 0000000..7439b83
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O3  -mcpu=spacemit-x60 -mabi=lp64d -w -std=gnu89" } */
+
+unsigned int
+f1 (int diff)
+{
+  return ((unsigned int) (diff < 0 ? -diff : diff));
+}
+
+unsigned int
+f2 (unsigned int diff)
+{
+  return ((unsigned int) ((signed int) diff < 0 ? -diff : diff));
+}
+
+unsigned long long
+f3 (long long diff)
+{
+  return ((unsigned long long) (diff < 0 ? -diff : diff));
+}
+
+unsigned long long
+f4 (unsigned long long diff)
+{
+  return ((unsigned long long) ((signed long long) diff < 0 ? -diff : diff));
+}
+
+main ()
+{
+  int i;
+  for (i = 0; i <= 10; i++)
+    {
+      if (f1 (i) != i)
+       abort ();
+      if (f1 (-i) != i)
+       abort ();
+      if (f2 (i) != i)
+       abort ();
+      if (f2 (-i) != i)
+       abort ();
+      if (f3 ((long long) i) != i)
+       abort ();
+      if (f3 ((long long) -i) != i)
+       abort ();
+      if (f4 ((long long) i) != i)
+       abort ();
+      if (f4 ((long long) -i) != i)
+       abort ();
+    }
+  exit (0);
+}