https://gcc.gnu.org/g:4588887adc650d8fdaf6bc153930bf60038189d7

commit 4588887adc650d8fdaf6bc153930bf60038189d7
Author: Pan Li <pan2...@intel.com>
Date:   Sat Aug 17 09:25:58 2024 -0600

    RISC-V: Bugfix incorrect operand for vwsll auto-vect
    
    This patch would like to fix one ICE when rv64gcv_zvbb for vwsll.
    Consider below example.
    
    void vwsll_vv_test (short *restrict dst, char *restrict a,
                        int *restrict b, int n)
    {
      for (int i = 0; i < n; i++)
        dst[i] = a[i] << b[i];
    }
    
    It will hit the vwsll pattern with following operands.
    operand 0 -> (reg:RVVMF2HI 146 [ vect__7.13 ])
    operand 1 -> (reg:RVVMF4QI 165 [ vect_cst__33 ])
    operand 2 -> (reg:RVVM1SI 171 [ vect_cst__36 ])
    
    According to the ISA, operand 2 should be the same as operand 1.
    Aka operand 2 should have RVVMF4QI mode as above.  Thus,  add
    quad truncation for operand 2 before emit vwsll.
    
    The below test suites are passed for this patch.
    * The rv64gcv fully regression test.
    
            PR target/116280
    
    gcc/ChangeLog:
    
            * config/riscv/autovec-opt.md: Add quad truncation to
            align the mode requirement for vwsll.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/base/pr116280-1.c: New test.
            * gcc.target/riscv/rvv/base/pr116280-2.c: New test.
    
    (cherry picked from commit 06ae7bc1345a31a5f23dc86b348a1bef59bb3cc1)

Diff:
---
 gcc/config/riscv/autovec-opt.md                      |  4 ++++
 gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-1.c | 14 ++++++++++++++
 gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-2.c | 10 ++++++++++
 3 files changed, 28 insertions(+)

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index d7a3cfd4602..4b33a145c17 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -1546,6 +1546,10 @@
   "&& 1"
   [(const_int 0)]
   {
+    rtx truncated = gen_reg_rtx (<V_QUAD_TRUNC>mode);
+    emit_insn (gen_trunc<mode><v_quad_trunc>2 (truncated, operands[2]));
+    operands[2] = truncated;
+
     insn_code icode = code_for_pred_vwsll (<V_DOUBLE_TRUNC>mode);
     riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
     DONE;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-1.c
new file mode 100644
index 00000000000..8b8547e2c34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-1.c
@@ -0,0 +1,14 @@
+/* Test there is no ICE when compile.  */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvbb -mabi=lp64d -O3" } */
+
+short a;
+char b;
+
+void
+test (int e[][1][1], char f[][1][1][1][1]) {
+  for (int g; b;)
+    for (;;)
+      for (int h; h < 4073709551572ULL; h += 18446744073709551612U)
+        a = f[2][2][1][4073709551612][1] << e[1][1][g];
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-2.c
new file mode 100644
index 00000000000..02f2de66eff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116280-2.c
@@ -0,0 +1,10 @@
+/* Test there is no ICE when compile.  */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvbb -mabi=lp64d -O3" } */
+
+void
+test (short *restrict dst, char *restrict a, int *restrict b, int n)
+{
+  for (int i = 0; i < n; i++)
+    dst[i] = a[i] << b[i];
+}

Reply via email to