[llvm] [Exegesis][RISCV] Support C_LDSP for llvm-exegesis (PR #169660)

Shaoce SUN via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 1 09:34:29 PST 2025


https://github.com/sunshaoce updated https://github.com/llvm/llvm-project/pull/169660

>From a8fdd09b93b589e025f4a39a7d6016747d1148f3 Mon Sep 17 00:00:00 2001
From: Shaoce SUN <sunshaoce at outlook.com>
Date: Wed, 26 Nov 2025 22:34:05 +0800
Subject: [PATCH 1/3] [Exegesis][RISCV] Support C_LDSP for llvm-exegesis

Fix error:
```
*** Bad machine code: Illegal physical register for instruction ***
- function:    foo
- basic block: %bb.0  (0x5e2262bd3f20)
- instruction: $x10 = C_LDSP $x10, 0
- operand 1:   $x10
$x10 is not a SP register.
llvm-exegesis error: The machine function failed verification.
```
---
 .../tools/llvm-exegesis/RISCV/latency-by-extension-C.s   | 9 +++++++++
 llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp            | 8 ++++++++
 2 files changed, 17 insertions(+)

diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
index 9e94f024ed116..8189d252cd96c 100644
--- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
+++ b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
@@ -46,3 +46,12 @@ C_SRLI-NEXT: key:
 C_SRLI-NEXT:   instructions:
 C_SRLI-NEXT:     - 'C_SRLI [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]'
 C_SRLI-DAG: ...
+
+# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_LDSP -mattr=+c | FileCheck --check-prefix=C_LDSP %s
+
+C_LDSP:      ---
+C_LDSP-NEXT: mode: latency
+C_LDSP-NEXT: key:
+C_LDSP-NEXT:   instructions:
+C_LDSP-NEXT:     - 'C_LDSP [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]'
+C_LDSP-DAG: ...
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
index ea830bd5f753d..9460743e34ce8 100644
--- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
@@ -819,6 +819,14 @@ void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT,
 
   assert(MemOp.isReg() && "Memory operand expected to be register");
 
+  unsigned Opcode = I.getOpcode();
+  if (Opcode == RISCV::C_LDSP || Opcode == RISCV::C_LWSP ||
+      Opcode == RISCV::C_SDSP || Opcode == RISCV::C_SWSP) {
+    // Force base register to SP (X2)
+    IT.getValueFor(MemOp) = MCOperand::createReg(RISCV::X2);
+    return;
+  }
+
   IT.getValueFor(MemOp) = MCOperand::createReg(Reg);
 }
 

>From aba68de98b0945f451e4dc604ed6afdd13be64e2 Mon Sep 17 00:00:00 2001
From: Shaoce SUN <sunshaoce at outlook.com>
Date: Thu, 27 Nov 2025 00:14:04 +0800
Subject: [PATCH 2/3] update test

---
 llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
index 8189d252cd96c..2b09863b21f31 100644
--- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
+++ b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
@@ -53,5 +53,5 @@ C_LDSP:      ---
 C_LDSP-NEXT: mode: latency
 C_LDSP-NEXT: key:
 C_LDSP-NEXT:   instructions:
-C_LDSP-NEXT:     - 'C_LDSP [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]'
+C_LDSP-NEXT:     - 'C_LDSP [[REG111:X[0-9]+]] X2 [[IMM11:i_0x[0-9]+]]'
 C_LDSP-DAG: ...

>From 624a2c7ae6a3145ceeddb6aeee6c0a83f244c4c0 Mon Sep 17 00:00:00 2001
From: Shaoce SUN <sunshaoce at outlook.com>
Date: Tue, 2 Dec 2025 01:18:26 +0800
Subject: [PATCH 3/3] fixup! override rd in fillMemoryOperands

---
 .../tools/llvm-exegesis/RISCV/latency-by-extension-C.s     | 2 +-
 llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp              | 1 +
 llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp    | 7 ++++++-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
index 2b09863b21f31..cf4f1bf0f6b84 100644
--- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
+++ b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
@@ -53,5 +53,5 @@ C_LDSP:      ---
 C_LDSP-NEXT: mode: latency
 C_LDSP-NEXT: key:
 C_LDSP-NEXT:   instructions:
-C_LDSP-NEXT:     - 'C_LDSP [[REG111:X[0-9]+]] X2 [[IMM11:i_0x[0-9]+]]'
+C_LDSP-NEXT:     - 'C_LDSP X2 X2 [[IMM11:i_0x[0-9]+]]'
 C_LDSP-DAG: ...
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
index 9460743e34ce8..6f439359b51a5 100644
--- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
@@ -823,6 +823,7 @@ void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT,
   if (Opcode == RISCV::C_LDSP || Opcode == RISCV::C_LWSP ||
       Opcode == RISCV::C_SDSP || Opcode == RISCV::C_SWSP) {
     // Force base register to SP (X2)
+    IT.getValueFor(I.Operands[0]) = MCOperand::createReg(RISCV::X2);
     IT.getValueFor(MemOp) = MCOperand::createReg(RISCV::X2);
     return;
   }
diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
index 707e6ee2d434b..71b2d71e084e1 100644
--- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
@@ -142,7 +142,12 @@ static void appendCodeTemplates(const LLVMState &State,
         return;
 
       ET.fillMemoryOperands(Variant, ScratchMemoryRegister, 0);
-      Variant.getValueFor(DefOp) = MCOperand::createReg(ScratchMemoryRegister);
+
+      // Only force the def register to ScratchMemoryRegister if the target
+      // hasn't assigned a value yet.
+      MCOperand &DefVal = Variant.getValueFor(DefOp);
+      if (!DefVal.isValid())
+        DefVal = MCOperand::createReg(ScratchMemoryRegister);
 
       CodeTemplate CT;
       CT.Execution = ExecutionModeBit;



More information about the llvm-commits mailing list