[gcc(refs/vendors/riscv/heads/gcc-14-with-riscv-opts)] RISC-V: Fix vl_used_by_non_rvv_insn logic of vsetvl pass
Jeff Law
law@gcc.gnu.org
Sun Sep 29 16:34:36 GMT 2024
https://gcc.gnu.org/g:7a987a1f5d78e5bb5b8bf2f16421a033a2a012cb
commit 7a987a1f5d78e5bb5b8bf2f16421a033a2a012cb
Author: garthlei <garthlei@linux.alibaba.com>
Date: Wed Sep 11 17:09:37 2024 +0800
RISC-V: Fix vl_used_by_non_rvv_insn logic of vsetvl pass
This patch fixes a bug in the current vsetvl pass. The current pass uses
`m_vl` to determine whether the dest operand has been used by non-RVV
instructions. However, `m_vl` may have been modified as a result of an
`update_avl` call, and thus would be no longer the dest operand of the
original instruction. This can lead to incorrect vsetvl eliminations, as is
shown in the testcase. In this patch, we create a `dest_vl` variable for
this scenerio.
gcc/ChangeLog:
* config/riscv/riscv-vsetvl.cc: Use `dest_vl` for dest VL operand
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c: New test.
(cherry picked from commit c08e493ceee47bbeb466eeef100be7c1dd01a4e5)
Diff:
---
gcc/config/riscv/riscv-vsetvl.cc | 16 +++++++++++-----
.../gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c | 17 +++++++++++++++++
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index bbea2b5fd4f3..7a5984f358dc 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -1001,6 +1001,9 @@ public:
void parse_insn (insn_info *insn)
{
+ /* The VL dest of the insn */
+ rtx dest_vl = NULL_RTX;
+
m_insn = insn;
m_bb = insn->bb ();
/* Return if it is debug insn for the consistency with optimize == 0. */
@@ -1034,7 +1037,10 @@ public:
if (m_avl)
{
if (vsetvl_insn_p (insn->rtl ()) || has_vlmax_avl ())
- m_vl = ::get_vl (insn->rtl ());
+ {
+ m_vl = ::get_vl (insn->rtl ());
+ dest_vl = m_vl;
+ }
if (has_nonvlmax_reg_avl ())
m_avl_def = find_access (insn->uses (), REGNO (m_avl))->def ();
@@ -1131,22 +1137,22 @@ public:
}
/* Determine if dest operand(vl) has been used by non-RVV instructions. */
- if (has_vl ())
+ if (dest_vl)
{
const hash_set<use_info *> vl_uses
- = get_all_real_uses (get_insn (), REGNO (get_vl ()));
+ = get_all_real_uses (get_insn (), REGNO (dest_vl));
for (use_info *use : vl_uses)
{
gcc_assert (use->insn ()->is_real ());
rtx_insn *rinsn = use->insn ()->rtl ();
if (!has_vl_op (rinsn)
- || count_regno_occurrences (rinsn, REGNO (get_vl ())) != 1)
+ || count_regno_occurrences (rinsn, REGNO (dest_vl)) != 1)
{
m_vl_used_by_non_rvv_insn = true;
break;
}
rtx avl = ::get_avl (rinsn);
- if (!avl || !REG_P (avl) || REGNO (get_vl ()) != REGNO (avl))
+ if (!avl || !REG_P (avl) || REGNO (dest_vl) != REGNO (avl))
{
m_vl_used_by_non_rvv_insn = true;
break;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c
new file mode 100644
index 000000000000..c155f5613d27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O2 -fdump-rtl-vsetvl-details" } */
+
+#include <riscv_vector.h>
+
+uint64_t a[2], b[2];
+
+void
+foo ()
+{
+ size_t vl = __riscv_vsetvl_e64m1 (2);
+ vuint64m1_t vx = __riscv_vle64_v_u64m1 (a, vl);
+ vx = __riscv_vslide1down_vx_u64m1 (vx, 0xffffffffull, vl);
+ __riscv_vse64_v_u64m1 (b, vx, vl);
+}
+
+/* { dg-final { scan-rtl-dump-not "Eliminate insn" "vsetvl" } } */
More information about the Gcc-cvs
mailing list