From a8fdd09b93b589e025f4a39a7d6016747d1148f3 Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Wed, 26 Nov 2025 22:34:05 +0800 Subject: [PATCH 1/4] [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 Date: Thu, 27 Nov 2025 00:14:04 +0800 Subject: [PATCH 2/4] 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 Date: Tue, 2 Dec 2025 01:18:26 +0800 Subject: [PATCH 3/4] 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; From 525c095a08e7d3a1c5df6ed2592b2001db70e865 Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Thu, 4 Dec 2025 11:56:21 +0800 Subject: [PATCH 4/4] Address comments --- llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp index 6f439359b51a5..74633bedad450 100644 --- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp @@ -822,8 +822,8 @@ void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT, 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(I.Operands[0]) = MCOperand::createReg(RISCV::X2); + // Force base register to SP (X2) IT.getValueFor(MemOp) = MCOperand::createReg(RISCV::X2); return; }