-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Exegesis][RISCV] Support C_LDSP for llvm-exegesis #169660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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. ```
|
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-tools-llvm-exegesis Author: Shaoce SUN (sunshaoce) ChangesFix error: Full diff: https://github.com/llvm/llvm-project/pull/169660.diff 2 Files Affected:
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);
}
|
|
|
||
| unsigned Opcode = I.getOpcode(); | ||
| if (Opcode == RISCV::C_LDSP || Opcode == RISCV::C_LWSP || | ||
| Opcode == RISCV::C_SDSP || Opcode == RISCV::C_SWSP) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to do the FP versions too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested some instructions, but none of them can be measured:
C_FLDSP: No strategy found to make the execution serial
C_FSDSP: No strategy found to make the execution serial
C_FLWSP: No strategy found to make the execution serial
C_FSWSP: No strategy found to make the execution serial
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In C_LDSP's case, it'll try to create an alias between the destination register of the previous load to the base register of the following instruction, which is always X2. But when it comes to C_FLDSP the same trick doesn't work because now the desination register is a floating point register, which is incompatible with X2.
|
Does the rest of llvm-exegesis need to know that we're accessing stack instead of the scratch memory it set up? If the offset is too large, can't it cause the stack access to page fault? |
| 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]+]]' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this will effectively generate sequence like
C_LDSP X10, X2, 0
C_LDSP X10, X2, 0
C_LDSP X10, X2, 0
...
But as you might also notice: this is not serial. Ideally it'll be great if we can generate
C_LDSP X2, X2, 0
C_LDSP X2, X2, 0
C_LDSP X2, X2, 0
...
To do this, we might need to teach it to use a different scratch memory register instead of X10.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the scratch register should be doable (with a register to register move in the snippet setup code), but ideally we would move snippet generation involving memory operands to use memory definitions and mappings. That requires support for subprocess execution mode though, which is a larger effort.
It doesn't need to "know" for the purchases of benchmarking, given it's just a load, but yes, it could definitely cause faults. The proper way to do this is to implement subprocess execution mode and then you can set the stack to a exegesis controlled section of memory. |
|
Thanks everyone for the guidance. I've now implemented the change to replace |
boomanaiden154
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess RISC-V is actually RISC so you do not get instructions like pushq or popq on X86 that also modify the value of the SP register, which is what typically makes supporting stack operations really difficult. Using the stack of the parent process is a bit of a hack though.
Overall, I think I'm probably fine with this patch. Please have someone who actually knows RISC-V sign off on this before landing.
mshockwave
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM w/ a minor comment
tangent to this PR: the Zcmp extension actually has stack push / pop, they're called |
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. ```
Fix error: