This change implements support for the `cr` and `cf` register
constraints (which allocate a RVC GPR or RVC FPR respectively), and the
`N` modifier (which prints the raw encoding of a register rather than
the name).
The intention behind these additions is to make it easier to use inline
assembly when assembling raw instructions that are not supported by the
compiler, for instance when experimenting with new instructions or when
supporting proprietary extensions outside the toolchain.
These implement part of my proposal in riscv-non-isa/riscv-c-api-doc#92
As part of the implementation, I felt there was not enough coverage of
inline assembly and the "in X" floating-point extensions, so I have
added more regression tests around these configurations.
Add a MCSubtargetInfo& operand so we can control the subtarget for the
new calls. The old signature is kept as a wrapper to pass *STI to
maintain compatibility.
By using EmitToStreamer we are able to compress the instructions when
possible.
This allows us to pass the STI we already have cached instead of
AsmPrinter::EmitToStreamer looking it up from the MachineFunction again.
My plan is to make EmitHwasanMemaccessSymbols use
RISCVAsmPrinter::EmitToStreamer instead of calling
MCStreamer::emitInstruction. To do that I need control of the
MCSubtargetInfo.
We passed a MCStreamer to the function but hardcoded *OutStreamer
instead of using it. It's very likely that OutStreamer is the only
streamer used, but lets not assume that without doing the audit.
The InitUndef pass currently uses target-specific pseudo instructions,
with one pseudo per register class.
Instead, add a generic pseudo instruction, which can be used by all
targets and register classes.
Commit 5cd8d53cac00f taught RISCVMergeBaseOffset to handle inline asm,
however
there is at least one case uncovered for integrated as.
In the example below compiler generates pcrel relocation
(mcmodel=medany)
```
volatile double double_val = 1.0;
void foo() {
asm volatile("fld f0, %0 \n\t" : : "m"(double_val) : "memory");
}
```
And fails with the folliwng error
```
error: could not find corresponding %pcrel_hi
| "fld f0, %0 \n\t"
<inline asm>:1:2: note: instantiated into assembly here
| fld f0, %pcrel_lo(.Lpcrel_hi0)(a0)
```
After transformations MachineFunction contains inline asm instructions
with
'.Lpcrel_hi0' symbol that is not defined in inline asm, but referenced.
```
... = AUIPC ...(riscv-pcrel-hi) @double_val, pre-instr-symbol <mcsymbol .Lpcrel_hi0>
INLINEASM &"fld f0, $0 \0A\09" ... target-flags(riscv-pcrel-lo) <mcsymbol .Lpcrel_hi0>
```
So, when AsmParser processes 'fld', it has to create a new symbol as
'.Lpcrel_hi0' already exists but not known to be referenced in inline
asm.
AsmParser avoids conflicts by renaming referenced by 'fld' symbol with
'.Lpcrel_hi00' name which does not exist. Resulting erroneous asm
```
.Lpcrel_hi0:
auipc a0, %pcrel_hi(double_val)
#APP
fld ft0, %pcrel_lo(.Lpcrel_hi00)(a0)
```
This change adds symbols used in memory operands to the list of
referenced ones.
Godbolt link: https://godbolt.org/z/aqrrsWKoK -- on the left you can
find incorrect labels for the integrated-as and on the right an error
when compiling to the binary object.
This introduces a new file, RISCVISAUtils.cpp and moves the rest of
RISCVISAInfo to the TargetParser library.
This will allow us to generate part of RISCVISAInfo.cpp using tablegen.
Walk all the ISA strings and set the subtarget bits for any extension we
find in any string.
This allows LTO output to have a ELF attributes from the union of all of
the files used to compile it.
This patch adds basic TLSDESC support in the RISC-V backend.
Specifically, we add new relocation types for TLSDESC, as prescribed in
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373, and add a
new pseudo instruction to simplify code generation.
This patch does not try to optimize the local dynamic case, which can be
improved in separate patches.
Linker side changes will also be handled separately.
The current implementation is only enabled when passing the new
`-enable-tlsdesc` codegen flag.
For inline asm with memory operands, we can merge the offset into
the second operand of memory constraint operands.
Differential Revision: https://reviews.llvm.org/D158062
Since #72467, `@plt` in assembly output "call foo@plt" is omitted. We
can trivially merge MO_PLT and MO_CALL without any functional change to
assembly/relocatable file output.
Earlier architectures use different call relocation types whether a PLT
is potentially needed: R_386_PLT32/R_386_PC32, R_68K_PLT32/R_68K_PC32,
R_SPARC_WDISP30/R_SPARC_WPLT320. However, as the PLT property is
per-symbol instead of per-call-site and linkers can optimize out a PLT,
the distinction has been confusing.
Arm made good names R_ARM_CALL/R_AARCH64_CALL. Let's use MO_CALL instead
of MO_PLT.
As follow-ups, we can merge fixup_riscv_call/fixup_riscv_call_plt and
VK_RISCV_CALL/VK_RISCV_CALL_PLT.
-Rename sub_32_hi to sub_gpr_odd
-Add dedicated sub_gpr_even.
-Rename sub_32 and sub_16 to sub_fpr32 and sub_fpr16.
-Remove start offset from sub_gpr_odd. AArch64 doesn't use non-zero offset for GPR
tuples so I don't think we need to.
This is preparation for a RV64 GPRPair for Zacas.
This patch adds stackmap support for RISC-V without targets (i.e. the nop patchable forms).
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D123496
After commit cedf2ea, `RISCVMergeBaseOffset` can handle `BlockAddress`
currently. But we didn't handle it in `PrintAsmMemoryOperand` so we
get `invalid operand in inline asm` error.
This patch fixes the error.
It maybe emit the .option directive without any follow up. Only emit the .option push/pop when there are supported extension difference between function and module.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D159399
For inline asm with memory operands, we can merge the offset into
the second operand of memory constraint operands.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D158062
Preparation for developing a new rounding mode insertion algorithm
that is going to be different between them since VXRM doesn't need
to be save/restored.
This also unifies the FRM handling in RISCVISelLowering.cpp between
scalar and vector.
Fixes outdated comments in RISCVAsmPrinter and sorts the predicate
function by the reverse order of the operands being skipped.
Reviewed By: eopXD
Differential Revision: https://reviews.llvm.org/D158326
In D146245, we have supported lowering inline asm `m` with offset
to `register+imm`, but we didn't handle the case that the offset
is the low part of global address.
This patch will emit `%lo(g)` when `g` is a global address.
Fixes#64656
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D157839
When function has different attributes from module, emit the .option <attribute> before the function body. This allows non-integrated assemblers to properly assemble the functions (which may contain instructions dependent on the extra target features).
Reviewed By: craig.topper, reames
Differential Revision: https://reviews.llvm.org/D155155
With `-fsanitize=kcfi` (Kernel Control-Flow Integrity), Clang emits
"kcfi" operand bundles to indirect call instructions. Similarly to
the target-specific lowering added in D119296, implement KCFI operand
bundle lowering for RISC-V.
This patch disables the generic KCFI pass for RISC-V in Clang, and
adds the KCFI machine function pass in `RISCVPassConfig::addPreSched`
to emit target-specific `KCFI_CHECK` pseudo instructions before calls
that have KCFI operand bundles. The machine function pass also bundles
the instructions to ensure we emit the checks immediately before the
calls, which is not possible with the generic pass.
`KCFI_CHECK` instructions are lowered in `RISCVAsmPrinter` to a
contiguous code sequence that traps if the expected hash in the
operand bundle doesn't match the hash before the target function
address. This patch emits an `ebreak` instruction for error handling
to match the Linux kernel's `BUG()` implementation. Just like for X86,
we also emit trap locations to a `.kcfi_traps` section to support
error handling, as we cannot embed additional information to the trap
instruction itself.
Relands commit 62fa708ceb027713b386c7e0efda994f8bdc27e2 with fixed
tests.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D148385
With `-fsanitize=kcfi` (Kernel Control-Flow Integrity), Clang emits
"kcfi" operand bundles to indirect call instructions. Similarly to
the target-specific lowering added in D119296, implement KCFI operand
bundle lowering for RISC-V.
This patch disables the generic KCFI pass for RISC-V in Clang, and
adds the KCFI machine function pass in `RISCVPassConfig::addPreSched`
to emit target-specific `KCFI_CHECK` pseudo instructions before calls
that have KCFI operand bundles. The machine function pass also bundles
the instructions to ensure we emit the checks immediately before the
calls, which is not possible with the generic pass.
`KCFI_CHECK` instructions are lowered in `RISCVAsmPrinter` to a
contiguous code sequence that traps if the expected hash in the
operand bundle doesn't match the hash before the target function
address. This patch emits an `ebreak` instruction for error handling
to match the Linux kernel's `BUG()` implementation. Just like for X86,
we also emit trap locations to a `.kcfi_traps` section to support
error handling, as we cannot embed additional information to the trap
instruction itself.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D148385
Depends on D151395.
This is the 2nd patch of the patch-set. For the cover letter of the
patch-set, please checkout D151395. This patch originates from
D121376.
This commit models vxrm by adding an immediate operand into intrinsics
and machine instructions of RVV fixed-point instruction `vaadd`,
`vaaddu`, `vasub`, and `vasubu`. This commit only covers intrinsics of
the four instructions, the proceeding patches of the patch-set will do
the same to other RVV fixed-point instructions.
The current naiive approach is to have a write to vxrm inserted before
every fixed-point instruction. This is done by the new added pass
`RISCVInsertReadWriteCSR`. The reason to name the pass in a more general
term is because we will also model rounding mode for the RVV floating-
point instructions. The approach will be improved in the future,
implementing partial redundancy elimination algorithms to it.
The original LLVM intrinsics and machine instructions, take `vaadd` as
an example, does not model the rounding mode is not removed in this
patch. That is, `int.riscv.vaadd.*` co-exists with
`int.riscv.vaadd.rm.*` after this patch. The next patch will add C
intrinsics of vaadd with an additional operand that models the control
of the rounding mode, in this patch, `int.riscv.vaadd.rm.*` will
replace `int.riscv.vaadd.*`.
Authored-by: ShihPo Hung <shihpo.hung@sifive.com>
Co-Authored-by: eop Chen <eop.chen@sifive.com>
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D151396
We can mostly get this from the operand info in MCInstrDesc.
The exception is the _TIED pseudos so I've added a new flag for those.
Reviewed By: frasercrmck
Differential Revision: https://reviews.llvm.org/D152313
This was used to know if we need to insert a dummy operand during
MCInstLowering. We can use the operand info from MCInstrDesc to
figure this out without needing a separate flag.
I'll remove the tablegen bits if there is consensus this is a good
idea.
Differential Revision: https://reviews.llvm.org/D152050
The separation here doesn't make much sense. I think it's a
leftover from the creation of the MC layer that has been
replicated to new targets.
By merging them we can avoid passing the AsmPrinter to the
MCInstLowering functions. We can make them member functions instead.
I think we can still do more integration of lowerSymbolOperand
and lowerRISCVVMachineInstrToMCInst, but I wanted to get feedback
on the direction first.
Reviewed By: asb, barannikov88
Differential Revision: https://reviews.llvm.org/D152311
Rather than having a separate pass to add the hint instructions,
emit them directly into the streamer during asm printing.
Reviewed By: BeMg, kito-cheng
Differential Revision: https://reviews.llvm.org/D149511
This adds an option to emit the command line -mattr/-march into the
attributes of an object file. This can be useful to get objdump to
disassemble instructions that aren't in the base without forcing
users to add a .attribute to the assembly file.
The binutils assembler does this by default.
Similar option exists for ARM. I will wire it to a clang option in
another patch. Similar to https://reviews.llvm.org/D31813
Reviewed By: asb, kito-cheng
Differential Revision: https://reviews.llvm.org/D148782
As part of D145584, we noticed that llvm was generating suboptimal code
for constraint m when the operand can be be lowered to reg+imm form: it
was being selected as a single register rather than register+imm. This
caused an unnecessary 'addi' to be gen for each m constraint.
This patch changes llvm to select register+imm. This might generate code
that cannot be assembled, but matches gcc's behavior.
Reviewed By: craig.topper, kito-cheng
Differential Revision: https://reviews.llvm.org/D146245
RISC-V vector instruction has register overlapping constraint for certain
instructions, and will cause illegal instruction trap if violated, we use
early clobber to model this constraint, but it can't prevent register allocator
allocated same or overlapped if the input register is undef value, so convert
IMPLICIT_DEF to temporary pseudo could prevent that happen, it's not best way
to resolve this. Ideally we should model the constraint right, but before we
model the constraint right, it's the approach to prevent that happen.
See also: https://github.com/llvm/llvm-project/issues/50157
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D129735
This reverts commit f1c4241fb6e50c507adafbe14faf82a755ab92ca.
It causes use-after-poison asan failures for
CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll and CodeGen/RISCV/regalloc-last-chance-recoloring-failure.ll
RISC-V vector instruction has register overlapping constraint for certain
instructions, and will cause illegal instruction trap if violated, we use
early clobber to model this constraint, but it can't prevent register allocator
allocated same or overlapped if the input register is undef value, so convert
IMPLICIT_DEF to temporary pseudo could prevent that happen, it's not best way
to resolve this. Ideally we should model the constraint right, but before we
model the constraint right, it's the approach to prevent that happen.
See also: https://github.com/llvm/llvm-project/issues/50157
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D129735
We were using an OR with X0 which is the canonical move for AArch64.
The canonical move for RISC-V is ADDI reg1, reg2, 0.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D142044
The STI object in the class is updated each time runOnMachineFunction
is called. That means STI will be based on the last function processed.
If that function has different attributes than the rest of the module
that could theoretically result in odd behavior.
Use the copy in TargetMachine instead. That will use the global
CPU and mattrs.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D142041
The MCSTI variable is initialized to TM.getMCSubtargetInfo(), but is
re-assigned in every call to runOnMachineFunction. emitAttributes is
called before any call to runOnMachineFunction, but it's not
immediately obvious.
This patch removes the MCSTI variable, and instead queries
TM.getMCSubtargetInfo() at the time emitAttributes is called.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D142037