From: Robin Dapp Date: Tue, 16 Jun 2026 12:54:48 +0000 (-0600) Subject: [PATCH] RISC-V: Fix splitter [PR125670]. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d815c8e374c85a36b8df244287ea1a2159cbd950;p=thirdparty%2Fgcc.git [PATCH] RISC-V: Fix splitter [PR125670]. 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. --- 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 @@ { emit_insn (gen_pred_mov (mode, operands[0], CONST1_RTX (mode), RVV_VUNDEF (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); +}