-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[RISCV] Support .option {no}exact #122483
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
Changes from 11 commits
8d8ed46
eba37b2
f6b0186
546f52c
3d9113d
dece4a6
c70f679
4e2aaee
b832095
32f3944
8133e9d
3fc5749
c8bf695
7dc2322
61bdfeb
2c62a5b
318afee
58a0f1b
a764474
859b430
6c10814
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
|
|
||
| #include "RISCVAsmBackend.h" | ||
| #include "RISCVMCExpr.h" | ||
| #include "RISCVMCTargetDesc.h" | ||
|
||
| #include "llvm/ADT/APInt.h" | ||
| #include "llvm/MC/MCAsmInfo.h" | ||
| #include "llvm/MC/MCAssembler.h" | ||
|
|
@@ -171,8 +172,39 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced( | |
| } | ||
| } | ||
|
|
||
| // Given a compressed control flow instruction this function returns | ||
| // the expanded instruction. | ||
| static unsigned getRelaxedOpcode(unsigned Op) { | ||
| switch (Op) { | ||
| default: | ||
| return Op; | ||
| case RISCV::C_BEQZ: | ||
| return RISCV::BEQ; | ||
| case RISCV::C_BNEZ: | ||
| return RISCV::BNE; | ||
| case RISCV::C_J: | ||
| case RISCV::C_JAL: // fall through. | ||
| return RISCV::JAL; | ||
| case RISCV::BEQ: | ||
| return RISCV::PseudoLongBEQ; | ||
| case RISCV::BNE: | ||
| return RISCV::PseudoLongBNE; | ||
| case RISCV::BLT: | ||
| return RISCV::PseudoLongBLT; | ||
| case RISCV::BGE: | ||
| return RISCV::PseudoLongBGE; | ||
| case RISCV::BLTU: | ||
| return RISCV::PseudoLongBLTU; | ||
| case RISCV::BGEU: | ||
| return RISCV::PseudoLongBGEU; | ||
| } | ||
| } | ||
|
|
||
| void RISCVAsmBackend::relaxInstruction(MCInst &Inst, | ||
| const MCSubtargetInfo &STI) const { | ||
| if (STI.hasFeature(RISCV::FeatureExactAssembly)) | ||
| return; | ||
|
|
||
| MCInst Res; | ||
| switch (Inst.getOpcode()) { | ||
| default: | ||
|
|
@@ -341,36 +373,14 @@ std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(const MCAssembler &Asm, | |
| return std::make_pair(Expr.evaluateKnownAbsolute(Value, Asm), false); | ||
| } | ||
|
|
||
| // Given a compressed control flow instruction this function returns | ||
| // the expanded instruction. | ||
| unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const { | ||
| switch (Op) { | ||
| default: | ||
| return Op; | ||
| case RISCV::C_BEQZ: | ||
| return RISCV::BEQ; | ||
| case RISCV::C_BNEZ: | ||
| return RISCV::BNE; | ||
| case RISCV::C_J: | ||
| case RISCV::C_JAL: // fall through. | ||
| return RISCV::JAL; | ||
| case RISCV::BEQ: | ||
| return RISCV::PseudoLongBEQ; | ||
| case RISCV::BNE: | ||
| return RISCV::PseudoLongBNE; | ||
| case RISCV::BLT: | ||
| return RISCV::PseudoLongBLT; | ||
| case RISCV::BGE: | ||
| return RISCV::PseudoLongBGE; | ||
| case RISCV::BLTU: | ||
| return RISCV::PseudoLongBLTU; | ||
| case RISCV::BGEU: | ||
| return RISCV::PseudoLongBGEU; | ||
| } | ||
| } | ||
|
|
||
| bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst, | ||
| const MCSubtargetInfo &STI) const { | ||
| // This function has access to two STIs, the member of the AsmBackend, and the | ||
| // one passed as an argument. The latter is more specific, so we query it for | ||
| // specific features. | ||
| if (STI.hasFeature(RISCV::FeatureExactAssembly)) | ||
| return false; | ||
|
|
||
| return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode(); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| # RUN: llvm-mc -triple riscv32 -show-encoding -mattr=+c %s \ | ||
| # RUN: | FileCheck -check-prefixes=CHECK,CHECK-ALIAS %s | ||
| # RUN: llvm-mc -triple riscv32 -show-encoding -mattr=+c \ | ||
| # RUN: -M no-aliases %s | FileCheck -check-prefixes=CHECK,CHECK-INST %s | ||
| # RUN: llvm-mc -triple riscv32 -filetype=obj -mattr=+c %s \ | ||
| # RUN: | llvm-objdump --triple=riscv32 --mattr=+c --no-print-imm-hex -d - \ | ||
| # RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s | ||
| # RUN: llvm-mc -triple riscv32 -filetype=obj -mattr=+c %s \ | ||
| # RUN: | llvm-objdump --triple=riscv32 --mattr=+c --no-print-imm-hex -d -M no-aliases - \ | ||
|
||
| # RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s | ||
|
|
||
| # RUN: llvm-mc -triple riscv64 -show-encoding -mattr=+c %s \ | ||
| # RUN: | FileCheck -check-prefixes=CHECK-ALIAS %s | ||
| # RUN: llvm-mc -triple riscv64 -show-encoding -mattr=+c \ | ||
| # RUN: -M no-aliases %s | FileCheck -check-prefixes=CHECK-INST %s | ||
| # RUN: llvm-mc -triple riscv64 -filetype=obj -mattr=+c %s \ | ||
| # RUN: | llvm-objdump --triple=riscv64 --mattr=+c --no-print-imm-hex -d - \ | ||
| # RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-ALIAS %s | ||
| # RUN: llvm-mc -triple riscv64 -filetype=obj -mattr=+c %s \ | ||
| # RUN: | llvm-objdump --triple=riscv64 --mattr=+c --no-print-imm-hex -d -M no-aliases - \ | ||
| # RUN: | FileCheck -check-prefixes=CHECK-BYTES,CHECK-INST %s | ||
|
|
||
|
|
||
| ## `.option exact` disables a variety of assembler behaviour: | ||
| ## - automatic compression | ||
| ## - branch relaxation (of short branches to longer equivalent sequences) | ||
| ## - linker relaxation (emitting R_RISCV_RELAX) | ||
| ## `.option noexact` enables these behaviours again. It is also the default. | ||
|
|
||
| ## This test only checks the automatic compression part of this behaviour. | ||
|
|
||
| # CHECK-BYTES: 4108 | ||
| # CHECK-INST: c.lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x08,0x41] | ||
| lw a0, 0(a0) | ||
|
|
||
| # CHECK-BYTES: 4108 | ||
| # CHECK-INST: c.lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x08,0x41] | ||
| c.lw a0, 0(a0) | ||
|
|
||
| # CHECK: .option exact | ||
| .option exact | ||
|
|
||
| # CHECK-BYTES: 00052503 | ||
| # CHECK-INST: lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x03,0x25,0x05,0x00] | ||
| lw a0, 0(a0) | ||
|
|
||
| # CHECK-BYTES: 4108 | ||
| # CHECK-INST: c.lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x08,0x41] | ||
| c.lw a0, 0(a0) | ||
|
|
||
| # CHECK: .option noexact | ||
| .option noexact | ||
|
|
||
| # CHECK-BYTES: 4108 | ||
| # CHECK-INST: c.lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x08,0x41] | ||
| lw a0, 0(a0) | ||
|
|
||
| # CHECK-BYTES: 4108 | ||
| # CHECK-INST: c.lw a0, 0(a0) | ||
| # CHECK-ALIAS: lw a0, 0(a0) | ||
| # CHECK: # encoding: [0x08,0x41] | ||
| c.lw a0, 0(a0) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| ; RUN: llc -mtriple=riscv32 -mattr=+relax,+c %s --filetype=obj -o - \ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move to test/CodeGen/RISCV?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, yeah, this location was a little iffy, happier to have an |
||
| ; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -M no-aliases -dr - \ | ||
| ; RUN: | FileCheck %s | ||
|
|
||
| define i32 @foo(ptr noundef %f) nounwind { | ||
| ; CHECK-LABEL: <foo>: | ||
| ; CHECK: auipc ra, 0x0 | ||
| ; CHECK-NEXT: R_RISCV_CALL_PLT undefined | ||
| ; CHECK-NEXT: jalr ra, 0x0(ra) | ||
| ; CHECK-NEXT: lw a0, 0x0(a0) | ||
| ; CHECK-NEXT: c.jr ra | ||
|
|
||
| entry: | ||
| %0 = tail call i32 asm sideeffect " | ||
| .option exact | ||
| call undefined@plt | ||
| lw $0, ($1) | ||
| .option noexact", "=^cr,^cr"(ptr %f) | ||
| ret i32 %0 | ||
| } | ||
|
|
||
|
||
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.
while you're here. oxford comma
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.
Done
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.
Learnt, the community is a good place to learn new English phrases. :-)