In RISCV's relocations, some relocations are comprised of two relocation types. For example, R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO12_I compose a PC relative relocation. In general the compiler will set a label in the position of R_RISCV_PCREL_HI20. So, to test the R_RISCV_PCREL_LO12_I relocation, we need decode instruction at position of the label points to R_RISCV_PCREL_HI20 plus 4 (the size of a riscv non-compress instruction).
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Why can't you just add a label for the instruction you want to test?
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp | ||
---|---|---|
568 | Don't change formatting for code you didn't touch | |
llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s | ||
25 | This is just (named_data - test_pcrel32) & 0xfff sign-extended from 12 to 64 bits. The + 0x800 for the HI is to compensate for the sign extension for the LO, feeding it back into the LO calculation is backwards and results in circular reasoning. |
Actually I really like the idea of allowing offsets here. Avoiding artificial labels has two benefits: improved readability, and clearer layout control on MachO where labels implicitly start new subsections.
This is just (named_data - test_pcrel32) & 0xfff sign-extended from 12 to 64 bits. The + 0x800 for the HI is to compensate for the sign extension for the LO, feeding it back into the LO calculation is backwards and results in circular reasoning.
I don't know RISCV, so I defer to Jessica here.
Side note: Some comparisons may be easier to express with the bit-slicing operator. E.g. this example from MachO_arm64_relocations.s:
# jitlink-check: decode_operand(test_local_call, 0)[25:0] = (named_func - test_local_call)[27:2] .globl test_local_call .p2align 2 test_local_call: bl named_func
Please address Jessica's feedback, but otherwise LGTM. Thanks Stephen!
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp | ||
---|---|---|
240–247 | You should error out for the other binop tokens with an unexpected token error. |
llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s | ||
---|---|---|
25 |
@jrtc27 Thank you for reminding me! You're right! By thinking again, here is my understanding: If the pc relative value is 0x00001fff, if don't add 0x800, then the value will be split to high 20bits(0x00001) and low 12bits(0xfff). However, the low 12bits will be considered as a signed number. so the MSB of 0xfff which originally represent 2^11 now changed to -2^11. The difference is 2^12. So we need to add 0x800 to compensate the difference. Are there any errors in my understanding? |
llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s | ||
---|---|---|
25 | 2^12 is 0x1000. You're conditionally adding 0x1000 to the hi20 value based on whether the 12th bit is set which, given hi20 throws away the low 12 bits, is the same as unconditionally adding 0x800 and relying on the carry bit of 0x800 + 0x800 to give you 0x1000. |
Thanks, lhames! Bit-slicing looks like a great idea! I will change it.
# jitlink-check: decode_operand(test_local_call, 0)[25:0] = (named_func - test_local_call)[27:2] .globl test_local_call .p2align 2 test_local_call: bl named_funcPlease address Jessica's feedback, but otherwise LGTM. Thanks Stephen!
Ok! I will!
llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s | ||
---|---|---|
25 | (... & 0xfff)[11:0] is a strange thing to write, you don't need both |
LGTM.
Note: I don't know what is the current standard for the ExecutionEngine test exhaustiveness, but the error condition, the subtracted offset, and the invalid offset cases aren't exercised in the tests.
Testing of the ExecutionEngine libraries is basic (though reasonably effective) -- definitely not exhaustive, but improving.
Testing of the test infrastructure itself (e.g. the jitlink checker) is currently non-existent.
Improving library testing is the higher priority, but more testing of the test tools would be nice too.
You should error out for the other binop tokens with an unexpected token error.