After D137316 implements the intrinsics of the first crc check instruction
and related diagnosis, this patch implements the intrinsics of all remaining
crc check instructions.
Differential Revision: https://reviews.llvm.org/D138418
This patch is required by OpenMP. After applying this patch, OpenMP regression
test passed. To reduce review difficulty caused by too large patches,
atomicrmw min/max operations on LA32 will be added later.
Differential Revision: https://reviews.llvm.org/D138177
This patch also implements not emit fence in atomic binary operation
when AtomicOrdering is monotonic and fixes the issue of loading from
non ptr parameters.
The processing of other levels of AtomicOrdering will be added later.
Differential Revision: https://reviews.llvm.org/D138481
When reading or writing a register that does not conform to the size of a
hardware register, an error message is generated instead of a compiler crash.
Differential Revision: https://reviews.llvm.org/D138008
As discussed in D137541, it supports processing when the depth of
__builtin_frame_address is greater than 0 instead of reporting an error.
Unsafe calls rely on the '-Wframe-address' option for diagnosis.
Differential Revision: https://reviews.llvm.org/D138084
This patch adds tail call support to the LoongArch backend. When
appropriate, use the `b` or `jr` instruction for tail calls (the
`pcalau12i+jirl` instruction pair when use medium codemodel).
This patch also modifies the inappropriate operand name:
simm26_bl -> simm26_symbol
This has been modeled after RISCV's tail call opt.
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137889
When all registers have been allocated and CFR needs to be saved on the
stack, an emergency spill slot is required. Because CFR's spill and
reload require a general purpose register to transfer.
The attached test case was bugpoint-reduced down from
`MultiSource/Benchmarks/mafft/Lalignmm.c` in the test-suite.
Without this patch, llc will crash and report the following errors:
```
LLVM ERROR: Error while trying to spill R4 from class GPR: Cannot scavenge register without an emergency spill slot!
```
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D138007
When expanding a PseudoCALL, the corresponding flags (e.g. nomerge)
need to be passed to the new instruction.
This patch also adds test for the nomerge attribute.
The `nomerge` attribute was added during `LowerCall`, but was lost
during expand PseudoCALL. Now add it back.
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137888
When the range of the unconditional branch is overflow, the indirect
branch way is used. The case when there is no scavenged register for
indirect branch needs to spill register to stack.
Reviewed By: SixWeining, wangleiat
Differential Revision: https://reviews.llvm.org/D137821
In LoongArch, when `CodeModel=Medium`, it just increases the jumping
ability of function calls relative to PC, from 2^28 to 2^32.
Depends on D137393
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137394
This patch moves the expansion of the `PseudoCALL` insturction to
`LoongArchPreRAExpandPseudo` pass. This helps to expand into different
instruction sequences according to different CodeModels.
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137393
When using `llvm.returnaddress` intrinsic, special handling is required
for the spill of the `RA` register. Otherwise it will cause the verifier
fail in some cases (e.g. pr17377.c of the GCC C Torture Suite).
Specifically:
```
*** Bad machine code: Using an undefined physical register ***
- function: f
- basic block: %bb.0 entry (0xd94d18)
- instruction: ST_D killed $r1, $r22, -40 :: (store (s64) into %stack.2)
- operand 0: killed $r1
```
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137387
These hooks ensure that the LoongArch backend can serialize and parse
MIR correctly.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D137482
1, spill/reload
When a function call is made immediately after a floating point
comparison, the result of the comparison needs to be spilled before
function call and reloaded after the function returns.
2, copy
Support `GPR` to `CFR` and `CFR` to `GRP` copys. Therefore, the correct
register class can be used in the pattern template, and the hard-coding
of mutual coping of `CFR` and `GRP` is eliminated, reducing redundant
comparison instructions.
Note: Since the `COPY` instruction between CFRs is not provided in
LoongArch, we only use `$fcc0` in the register allocation.
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137004
When the branch target is out of the range represented by the current
branch instruction's immediate, branch relaxation is required. There
are three types of immediate for branch instructions on LoongArch,
including simm16, simm21 and simm26. And the real branch target
address is PC + sext(simmXX << 2). In addition, the indirect branch
way is implemented to support larger branch target.
BranchRelaxation pass calls `RenumberBlocks` to renumber all of the
machine basic blocks in the function. So the machine basic blocks
number changed in some test cases.
Differential Revision: https://reviews.llvm.org/D137233
This patch fixes codegen for `[su]itofp` instructions.
In LoongArch, a legal int-to-float conversion is done in two steps:
1. Move the data from `GPR` to `FPR`. (FRLen >= GRLen)
2. Conversion in `FPR`. (the data in `FPR` is treated as a signed value)
Based on the above features, when the type's BitWidth meets the
requirements, all `SINT_TO_FP` are legal, all `UINT_TO_FP` are expand
and lowered to libcall when appropriate.
The only special case is, LoongArch64 with `+f,-d` features. At this
point, custom processing is required for `[SU]INT_TO_FP`. Of course, we
can also ignore it and use libcall directly.
Differential Revision: https://reviews.llvm.org/D136916
An emergency spill slot is created when the stack size cannot be
represented by an 11-bit signed number.
This patch also modifies how the `sp` is adjusted in the prologue.
`RegScavenger` will place the spill instruction before the prologue
if a VReg is created in the prologue. This will pollute the caller's
stack data. Therefore, until there is better way, we just use the
`addi.w/d` instruction for stack adjustment to ensure that VReg will
not be created. (RISCV has the same issue #58286)
Due to the addition of emergency spill slot, some test cases that use
exact stacksize need to be updated.
Differential Revision: https://reviews.llvm.org/D135757
This patch split the SP adjustment to reduce the instructions in
prologue and epilogue. In this way, the offset of the callee saved
register could fit in a single store.
Similar to D68011(RISCV).
Differential Revision: https://reviews.llvm.org/D136222
Modify the ParserMethod of `simm26_b` operand type to `parseImmediate`.
Before that, for the `simm26_b` operand type, the same ParserMethod
was used as `simm26_bl`. When using the internal assembler to process
the blockaddress with `asm` instruction, the wrong blockaddress symbol
would be generated due to the call to the `getOrCreateSymbol()`
interface.
Differential Revision: https://reviews.llvm.org/D136073
Fix invalid RISCV-like MI being emitted for performing the `not`
operation: the LoongArch `xori` zero-extends the immediate, hence is
not equivalent to RISCV `xori`. The LoongArch `not` is a `nor` with
zero.
Patch by lrzlin (Lin Runze).
Differential Revision: https://reviews.llvm.org/D136021
Fix invalid RISCV-like MI being emitted for performing the `not`
operation: the LoongArch `xori` zero-extends the immediate, hence is
not equivalent to RISCV `xori`. The LoongArch `not` is a `nor` with
zero.
Differential Revision: https://reviews.llvm.org/D136021
Similar to D69390 for RISCV, use a guaranteed non-existing insn for
llvm.trap and the break insn for llvm.debugtrap.
Differential Revision: https://reviews.llvm.org/D134365
The e_flags of existing object files are all 0x3 which happens to be
compatible. From this commit on, all LoongArch objects produced with
upstream LLVM will be of object file ABI v1, which is already supported
by binutils' master branch (to be released as 2.40), and is allowed by
the same binutils version to interlink with v0 objects so the existing
distributions have time to migrate.
Differential Revision: https://reviews.llvm.org/D134601
If the AM* atomic memory access instruction has the same register number as
rd and rj, the execution will trigger an Instruction Non-defined Exception.
If the AM* atomic memory access instruction has the same register number as
rd and rk, the execution result is uncertain.
Reference: https://github.com/loongson/LoongArch-Documentation
Differential Revision: https://reviews.llvm.org/D135641
Reference: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
k: A memory operand whose address is formed by a base register and
(optionally scaled) index register.
m: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as st.w and ld.w.
ZB: An address that is held in a general-purpose register. The offset
is zero.
ZC: A memory operand whose address is formed by a base register and
offset that is suitable for use in instructions with the same
addressing mode as ll.w and sc.w.
Note:
The INLINEASM SDNode flags in below tests are updated because the new
introduced enum `Constraint_k` is added before `Constraint_m`.
llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-inline-asm.ll
llvm/test/CodeGen/X86/callbr-asm-kill.mir
This patch passes `ninja check-all` on a X86 machine with all official
targets and the LoongArch target enabled.
Differential Revision: https://reviews.llvm.org/D134638
There are static and dynamic TLS address lowering in DAG stage according
to different TLS models.
TLS address will be lowered to pseudo instruction and then expanded by
the `LoongArch Pre-RA pseudo instruction expansion` pass.
Differential Revision: https://reviews.llvm.org/D134713
Otherwise eliminateFrameIndex cannot figure out how to fixup the stack
offset with its stateless logic, because there wouldn't be an immediate
slot for it to trivially write to, and it may not be easy to transform
the surrounding code to make it work.
This fixes a fairly common crash when compiling moderately complex code with
Clang.
Differential Revision: https://reviews.llvm.org/D135251