The instruction scheduler appears to be speculatively hoisting vsetvl
insns outside of their basic block without checking for data
dependencies. This resulted in a situation where the following occurs

        vsetvli a5,a1,e32,m1,tu,ma
        vle32.v v2,0(a0)
        sub     a1,a1,a5 <-- a1 potentially set to 0
        sh2add  a0,a5,a0
        vfmacc.vv       v1,v2,v2
        vsetvli a5,a1,e32,m1,tu,ma <-- incompatible vinfo. update vl to 0
        beq     a1,zero,.L12 <-- check if avl is 0

This patch would essentially delay the vsetvl update to after the branch
to prevent unnecessarily updating the vinfo at the end of a basic block.

Since this is purely a performance related patch, gate the target hook
with an opt flag to see the fallout.

        PR 117974

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_sched_can_speculate_insn):
        (TARGET_SCHED_CAN_SPECULATE_INSN): Implement.
        * config/riscv/riscv.opt: Add temporary opt.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/vsetvl/pr117974.c: New test.

Signed-off-by: Edwin Lu <e...@rivosinc.com>
---
V2: add testcase
V3: add opt flag to test performance
---
 gcc/config/riscv/riscv.cc                     | 25 +++++++++++++++++++
 gcc/config/riscv/riscv.opt                    |  4 +++
 .../gcc.target/riscv/rvv/vsetvl/pr117974.c    | 17 +++++++++++++
 3 files changed, 46 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6e14126e3a4..7203594b526 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -10209,6 +10209,28 @@ riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn 
*insn, int cost,
   return new_cost;
 }

+/* Implement TARGET_SCHED_CAN_SPECULATE_INSN hook.  Return true if insn can
+   can be scheduled for speculative execution.  Reject vsetvl instructions to
+   prevent the scheduler from hoisting them out of basic blocks without
+   checking for data dependencies PR117974.  */
+static bool
+riscv_sched_can_speculate_insn (rtx_insn *insn)
+{
+  /* Gate speculative scheduling of vsetvl instructions behind opt flag
+     for performance testing purposes.  */
+  if (!vsetvl_speculative_sched)
+    return true;
+
+  switch (get_attr_type (insn))
+    {
+      case TYPE_VSETVL:
+      case TYPE_VSETVL_PRE:
+       return false;
+      default:
+       return true;
+    }
+}
+
 /* Auxiliary function to emit RISC-V ELF attribute. */
 static void
 riscv_emit_attribute ()
@@ -14055,6 +14077,9 @@ bool need_shadow_stack_push_pop_p ()
 #undef  TARGET_SCHED_ADJUST_COST
 #define TARGET_SCHED_ADJUST_COST riscv_sched_adjust_cost

+#undef TARGET_SCHED_CAN_SPECULATE_INSN
+#define TARGET_SCHED_CAN_SPECULATE_INSN riscv_sched_can_speculate_insn
+
 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall

diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 7515c8ea13d..486ba746d99 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -681,3 +681,7 @@ Specifies whether the fence.tso instruction should be used.
 mautovec-segment
 Target Integer Var(riscv_mautovec_segment) Init(1)
 Enable (default) or disable generation of vector segment load/store 
instructions.
+
+-param=vsetvl-speculative-sched
+Target Undocumented Uinteger Var(vsetvl_speculative_sched) Init(0)
+-param=vsetvl-speculative-sched Enable speculative scheduling of vsetvl 
instructions.
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c
new file mode 100644
index 00000000000..97839427987
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr117974.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=zvl 
-Ofast" } */
+/* { dg-additional-options "--param=vsetvl-speculative-sched" } */
+
+float g(float q[], int N){
+    float dqnorm = 0.0;
+
+    #pragma GCC unroll 4
+
+    for (int i=0; i < N; i++) {
+        dqnorm = dqnorm + q[i] * q[i];
+    }
+    return dqnorm;
+}
+
+/* { dg-final { scan-assembler-times {beq\s+[a-x0-9]+,zero,.L12\s+vsetvli} 3 } 
} */
+
--
2.43.0

Reply via email to