https://gcc.gnu.org/g:b870cb81038f703c970ce4eb7c70991f544405b0

commit b870cb81038f703c970ce4eb7c70991f544405b0
Author: Robin Dapp <rd...@ventanamicro.com>
Date:   Wed Jul 31 16:54:03 2024 +0200

    RISC-V: Correct mode_idx attribute for viwalu wx variants [PR116149].
    
    In PR116149 we choose a wrong vector length which causes wrong values in
    a reduction.  The problem happens in avlprop where we choose the
    number of units in the instruction's mode as vector length.  For the
    non-scalar variants the respective operand has the correct non-widened
    mode.  For the scalar variants, however, the same operand has a scalar
    mode which obviously only has one unit.  This makes us choose VL = 1
    leaving three elements undisturbed (so potentially -1).  Those end up
    in the reduction causing the wrong result.
    
    This patch adjusts the mode_idx just for the scalar variants of the
    affected instruction patterns.
    
    gcc/ChangeLog:
    
            PR target/116149
    
            * config/riscv/vector.md: Fix mode_idx attribute of scalar
            widen add/sub variants.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/autovec/pr116149.c: New test.
    
    (cherry picked from commit f15cd1802129454029f7fcc8ee3ddd56a86cdad8)

Diff:
---
 gcc/config/riscv/vector.md                            |  2 ++
 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index bcedf3d79e2..d4d9bd87e91 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -4016,6 +4016,7 @@
   "TARGET_VECTOR"
   "vwadd<any_extend:u>.wx\t%0,%3,%z4%p1"
   [(set_attr "type" "viwalu")
+   (set_attr "mode_idx" "3")
    (set_attr "mode" "<V_DOUBLE_TRUNC>")])
 
 (define_insn "@pred_single_widen_sub<any_extend:su><mode>_extended_scalar"
@@ -4038,6 +4039,7 @@
   "TARGET_VECTOR"
   "vwsub<any_extend:u>.wx\t%0,%3,%z4%p1"
   [(set_attr "type" "viwalu")
+   (set_attr "mode_idx" "3")
    (set_attr "mode" "<V_DOUBLE_TRUNC>")])
 
 (define_insn "@pred_widen_mulsu<mode>"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c
new file mode 100644
index 00000000000..4f5927b96fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116149.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=zvl" 
} */
+
+long a;
+short b[60000];
+short c[20];
+int main() {
+  for (short d = 0; d < 20; d += 3) {
+    c[d] = 0;
+    for (int e = 0; e < 20; e += 2)
+      for (int f = 1; f < 20; f += 2)
+        a += (unsigned)b[f + e];
+  }
+  if (a != 0)
+    __builtin_abort ();
+}
+
+/* { dg-final { scan-assembler-times "vsetivli\tzero,1" 0 } } */

Reply via email to