[llvm] [llvm-mca][RISC-V] Remove duplicated use of SP from `c.addi4spn` (PR #189980)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 08:36:46 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Giorgio Marletta (giorgio-marletta)
<details>
<summary>Changes</summary>
`c.addi4spn` instruction implicitly uses the X2 (SP) register, but in
addition to being present in the Uses list, it is also modeled as an
explicit operand with the SP register class. This duplication causes
missed bypasses in llvm-mca when the instruction needs to read the SP
value written by a previous instruction.
For example, on a `sifive-u74` CPU, the following timeline excerpt
shows that the `c.addi4spn` is issues 2 cycles later than expected by
the GPR bypass:
```
Timeline view:
Index 012345678
[0,0] DeeE . . mv sp, a0
[0,1] . DeeE . addi a1, sp, 12
```
This patch removes SP from the Uses list, relying solely on the
explicit SP operand (as in `c.addi16sp`), which restores the expected
bypass behavior.
A test is added that checks the same scenario for `c.addi16sp` as well,
since a similar issue may also occur there.
---
Full diff: https://github.com/llvm/llvm-project/pull/189980.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoC.td (+1-1)
- (added) llvm/test/tools/llvm-mca/RISCV/SiFive7/sp-bypass.s (+81)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 8f76fa3b5bfd3..66648a8bea82f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -266,7 +266,7 @@ class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr>
let Predicates = [HasStdExtZca] in {
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def C_ADDI4SPN : RVInst16CIW<0b000, OPC_C0, (outs GPRC:$rd),
(ins SP:$rs1, uimm10_lsb00nonzero:$imm),
"c.addi4spn", "$rd, $rs1, $imm">,
diff --git a/llvm/test/tools/llvm-mca/RISCV/SiFive7/sp-bypass.s b/llvm/test/tools/llvm-mca/RISCV/SiFive7/sp-bypass.s
new file mode 100644
index 0000000000000..c9a7edcec6789
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/RISCV/SiFive7/sp-bypass.s
@@ -0,0 +1,81 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-u74 -timeline -iterations=1 < %s \
+# RUN: | FileCheck %s
+
+# Check that bypasses with SP operand work correctly
+
+c.mv sp, a0
+c.addi4spn a1, sp, 12
+addi sp, t0, 16
+c.addi16sp sp, -80
+addi t0, sp, 20
+
+# CHECK: Iterations: 1
+# CHECK-NEXT: Instructions: 5
+# CHECK-NEXT: Total Cycles: 7
+# CHECK-NEXT: Total uOps: 5
+
+# CHECK: Dispatch Width: 2
+# CHECK-NEXT: uOps Per Cycle: 0.71
+# CHECK-NEXT: IPC: 0.71
+# CHECK-NEXT: Block RThroughput: 2.5
+
+# CHECK: Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects (U)
+
+# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
+# CHECK-NEXT: 1 3 0.50 mv sp, a0
+# CHECK-NEXT: 1 3 0.50 addi a1, sp, 12
+# CHECK-NEXT: 1 3 0.50 addi sp, t0, 16
+# CHECK-NEXT: 1 3 0.50 addi sp, sp, -80
+# CHECK-NEXT: 1 3 0.50 addi t0, sp, 20
+
+# CHECK: Resources:
+# CHECK-NEXT: [0] - VLEN512SiFive7FDiv
+# CHECK-NEXT: [1] - VLEN512SiFive7IDiv
+# CHECK-NEXT: [2] - VLEN512SiFive7PipeA
+# CHECK-NEXT: [3] - VLEN512SiFive7PipeB
+# CHECK-NEXT: [4] - VLEN512SiFive7VA1
+# CHECK-NEXT: [5] - VLEN512SiFive7VCQ
+# CHECK-NEXT: [6] - VLEN512SiFive7VL
+# CHECK-NEXT: [7] - VLEN512SiFive7VS
+
+# CHECK: Resource pressure per iteration:
+# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
+# CHECK-NEXT: - - 2.00 3.00 - - - -
+
+# CHECK: Resource pressure by instruction:
+# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
+# CHECK-NEXT: - - - 1.00 - - - - mv sp, a0
+# CHECK-NEXT: - - 1.00 - - - - - addi a1, sp, 12
+# CHECK-NEXT: - - - 1.00 - - - - addi sp, t0, 16
+# CHECK-NEXT: - - 1.00 - - - - - addi sp, sp, -80
+# CHECK-NEXT: - - - 1.00 - - - - addi t0, sp, 20
+
+# CHECK: Timeline view:
+# CHECK-NEXT: Index 0123456
+
+# CHECK: [0,0] DeeE .. mv sp, a0
+# CHECK-NEXT: [0,1] .DeeE.. addi a1, sp, 12
+# CHECK-NEXT: [0,2] .DeeE.. addi sp, t0, 16
+# CHECK-NEXT: [0,3] . DeeE. addi sp, sp, -80
+# CHECK-NEXT: [0,4] . DeeE addi t0, sp, 20
+
+# CHECK: Average Wait times (based on the timeline view):
+# CHECK-NEXT: [0]: Executions
+# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
+# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
+# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage
+
+# CHECK: [0] [1] [2] [3]
+# CHECK-NEXT: 0. 1 0.0 0.0 0.0 mv sp, a0
+# CHECK-NEXT: 1. 1 0.0 0.0 0.0 addi a1, sp, 12
+# CHECK-NEXT: 2. 1 0.0 0.0 0.0 addi sp, t0, 16
+# CHECK-NEXT: 3. 1 0.0 0.0 0.0 addi sp, sp, -80
+# CHECK-NEXT: 4. 1 0.0 0.0 0.0 addi t0, sp, 20
+# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
``````````
</details>
https://github.com/llvm/llvm-project/pull/189980
More information about the llvm-commits
mailing list