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               |  2 +-
 .../gcc.target/riscv/rvv/autovec/pr125670.c   | 51 +++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr125670.c

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 497189cf185..f44813df3bf 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -53,7 +53,7 @@ (define_split
   {
     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
index 00000000000..7439b83d269
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr125670.c
@@ -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);
+}
-- 
2.54.0

Reply via email to