131 Commits

Author SHA1 Message Date
Fangrui Song
858266d308 [LoongArch] Fix tests after comment change 2022-12-01 22:08:21 +00:00
gonglingqin
624401612c [LoongArch] Add remaining intrinsics for CRC check instructions
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
2022-12-01 09:40:50 +08:00
gonglingqin
5f9b4d8bad [LoongArch] Add codegen support for atomicrmw min/max operation on LA64
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
2022-11-30 17:45:18 +08:00
gonglingqin
a2d10bda18 [LoongArch] Add atomic ordering information for binary atomic operations
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
2022-11-28 19:51:20 +08:00
gonglingqin
eca62f9204 [LoongArch] Diagnose the behavior of reading and writing registers that do not conform to the hardware register size
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
2022-11-24 10:38:44 +08:00
gonglingqin
801c77bbfa [LoongArch] Support when the depth of __builtin_frame_address is greater than zero
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
2022-11-22 15:29:29 +08:00
gonglingqin
f6d411f557 [LoongArch] Make function name in error message consistent with the user input. NFC 2022-11-21 10:54:12 +08:00
gonglingqin
c2ec455f18 [LoongArch] Add intrinsics for ibar, break and syscall
Diagnostics for intrinsic input parameters have also been added.

Differential Revision: https://reviews.llvm.org/D138094
2022-11-21 09:31:26 +08:00
wanglei
6971c1b370 [LoongArch] Add support for tail call optimization
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
2022-11-19 17:36:06 +08:00
wanglei
0e4378c55e [LoongArch] Add emergency spill slot for CFR spill/reload
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
2022-11-19 14:35:31 +08:00
gonglingqin
825547247a [LoongArch] Eliminate extra un-accounted-for successors
Specifically:
```
*** Bad machine code: MBB has unexpected successors which are not branch targets, fallthrough, EHPads, or inlineasm_br targets. ***
- function:    atomicrmw_umax_i8_acquire
- basic block: %bb.3  (0x1b90bd8)

*** Bad machine code: Non-terminator instruction after the first terminator ***
- function:    atomicrmw_umax_i8_acquire
- basic block: %bb.3  (0x1b90bd8)
- instruction: DBAR 1792
```

Differential Revision: https://reviews.llvm.org/D137884
2022-11-17 09:44:59 +08:00
wanglei
7da2d69da6 [LoongArch] Transfer MI flags when expand PseudoCALL
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
2022-11-17 09:25:10 +08:00
gonglingqin
ddbb21bdb5 [LoongArch] Add immediate operand validity check for __builtin_loongarch_dbar
Differential Revision: https://reviews.llvm.org/D137809
2022-11-16 14:47:45 +08:00
gonglingqin
b97911c37b [LoongArch] Implement the TargetLowering::getRegisterByName hook
Only reserved registers can be read.

Differential Revision: https://reviews.llvm.org/D137532
2022-11-15 16:10:32 +08:00
Xiaodong Liu
03d07e181d [LoongArch] Handle register spill in BranchRelaxation pass
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
2022-11-15 09:55:40 +08:00
gonglingqin
19ae5391e3 [LoongArch] Expand atomicrmw fadd/fsub/fmin/fmax with CmpXChg
Differential Revision: https://reviews.llvm.org/D137311
2022-11-14 10:11:37 +08:00
wanglei
882ddab4c0 [LoongArch] Generate PCALAU12I + JIRL instruction pair for medium codemodel
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
2022-11-11 18:26:51 +08:00
wanglei
4edcf8ab9f [LoongArch] Moved expansion of PseudoCALL to LoongArchPreRAExpandPseudo pass
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
2022-11-11 18:04:56 +08:00
gonglingqin
da34aff90d [Clang][LoongArch] Implement __builtin_loongarch_crc_w_d_w builtin and add diagnostics
This patch adds support to prevent __builtin_loongarch_crc_w_d_w from compiling
on loongarch32 in the front end and adds diagnostics accordingly.

Reference: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/larchintrin.h#L175-L184

Depends on D136906

Differential Revision: https://reviews.llvm.org/D137316
2022-11-11 09:16:57 +08:00
wanglei
d20c54cbdb [LoongArch] Override TargetFrameLowering::spillCalleeSavedRegisters
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
2022-11-10 21:14:27 +08:00
wanglei
0436cf5f52 [LoongArch] Support parsing target specific flags for MIR
These hooks ensure that the LoongArch backend can serialize and parse
MIR correctly.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D137482
2022-11-10 20:53:20 +08:00
wanglei
7d5c8cb023 [LoongArch] Added spill/reload/copy support for CFRs
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
2022-11-10 20:12:18 +08:00
gonglingqin
85f08c4197 [Clang][LoongArch] Implement __builtin_loongarch_dbar builtin
Differential Revision: https://reviews.llvm.org/D136906
2022-11-10 17:27:44 +08:00
gonglingqin
71ec751886 [LoongArch] Fix atomic store pointer operand sequence error
Differential Revision: https://reviews.llvm.org/D137687
2022-11-10 17:03:06 +08:00
Xiaodong Liu
57ad3f1dc6 [LoongArch] Add support for the BranchRelaxation pass
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
2022-11-08 19:26:16 +08:00
wanglei
5adb090795 [LoongArch] Fix codegen for [su]itofp instructions
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
2022-11-03 11:40:50 +08:00
Weining Lu
e415cb1d61 [LoongArch] Support inline asm operand modifier 'z'
Print $zero register if operand is zero, otherwise print it normally.

Clang is highly compatible [1] with GCC inline assembly extensions,
allowing the same set of constraints, modifiers and operands as GCC
inline assembly. This patch tries to make it compatible regarding
LoongArch specific operand modifiers.

GCC supports many modifiers [2], but it seems that only x86 and msp430
are documented [3][4]. I don't know if any other modifiers are being
used except the 'z' in Linux [5].

[1]: https://clang.llvm.org/compatibility.html#inline-asm
[2]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/loongarch.cc#L4884-L4911
[3]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86Operandmodifiers
[4]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#msp430Operandmodifiers
[5]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L17

Differential Revision: https://reviews.llvm.org/D136841
2022-10-31 09:56:41 +08:00
gonglingqin
be8a2b98da [LoongArch] Replace assertion by error message while lowering RETURNADDR and FRAMEADDR
If `__builtin_frame_address` or `__builtin_return_address` is invoked with
non-zero argument, show an error message instead of a crash.

Reference: https://reviews.llvm.org/rG83b88441ad951fe99c30402930ef3cd661f2fd2b

Differential Revision: https://reviews.llvm.org/D136917
2022-10-31 09:19:00 +08:00
Weining Lu
cd0174aacb [Clang][LoongArch] Support inline asm constraint 'J'
'J' is defined in GCC [1] but not documented [2] while Linux [3] has
already used it in LoongArch port.

[1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/constraints.md#L61
[2]: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
[3]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L19

Differential Revision: https://reviews.llvm.org/D136835
2022-10-31 09:13:52 +08:00
wanglei
4e2364a285 [LoongArch] Add emergency spill slot for GPR for large frames
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
2022-10-28 17:51:53 +08:00
wanglei
f589e5067f [LoongArch] Split SP adjustment
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
2022-10-28 16:39:00 +08:00
gonglingqin
bba97c3c03 [LoongArch] Add codegen support for cmpxchg on LA64
Differential Revision: https://reviews.llvm.org/D135948
2022-10-27 21:18:17 +08:00
gonglingqin
3be059377e [LoongArch] Add support for ISD::FRAMEADDR and ISD::RETURNADDR
For now, only support lowering frame/return address for current frame.

Differential Revision: https://reviews.llvm.org/D136215
2022-10-24 15:12:28 +08:00
wanglei
daf067da04 [LoongArch] Stack realignment support
This patch adds support for stack realignment while adding support for
variable sized objects.

Differential Revision: https://reviews.llvm.org/D136074
2022-10-21 17:30:29 +08:00
wanglei
6790292062 [LoongArch] Modify ParserMethod for the simm26_b operand type
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
2022-10-21 17:01:46 +08:00
gonglingqin
0f4dc562bc [LoongArch] Fix 32-bit and 64-bit atomicrmw nand operand order errors
Differential Revision: https://reviews.llvm.org/D136220
2022-10-20 17:26:33 +08:00
Weining Lu
771aee91c8 Reland "[LoongArch] Fix codegen of atomicrmw nand"
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
2022-10-19 10:05:35 +08:00
Weining Lu
0f374ca5cd Revert "[LoongArch] Fix codegen of atomicrmw nand"
This reverts commit 9572406bbcb497f8c23c28daa762b55ee3219f41.

The author name is wrong.
2022-10-19 07:56:23 +08:00
Weining Lu
9572406bbc [LoongArch] Fix codegen of atomicrmw nand
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
2022-10-18 20:39:20 +08:00
wanglei
506e936871 [LoongArch] Fix wrong VariantKind for MO_GOT_PC_{HI/LO} flags
Differential Revision: https://reviews.llvm.org/D135946
2022-10-15 17:45:08 +08:00
gonglingqin
e632bb6543 [LoongArch] Add codegen support for atomicrmw umin/umax operation on LA64
Furthermore, use `beqz $rd, .BB` instead of `beq $rd, $zero, .BB`.

Differential Revision: https://reviews.llvm.org/D135525
2022-10-14 15:24:43 +08:00
WANG Xuerui
f017e92c1c [LoongArch] Add support for llvm.trap and llvm.debugtrap
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
2022-10-13 19:27:47 +08:00
WANG Xuerui
4e2dfd3589 [LoongArch] Updates for the LoongArch ELF psABI v2.01 revision
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
2022-10-13 19:12:26 +08:00
gonglingqin
ec2640bf3a [LoongArch] Handle missing CondCodes
Support SETLE/SETEQ and expand SETGE/SETNE/SETGT

Differential Revision: https://reviews.llvm.org/D135511
2022-10-12 21:26:57 +08:00
gonglingqin
b1d7a95e4e [LoongArch] Add earlyclobber of destination register to atomic instructions
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
2022-10-12 21:09:21 +08:00
Weining Lu
42b70793a1 Reland "[Clang][LoongArch] Add inline asm support for constraints k/m/ZB/ZC"
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
2022-10-11 19:51:48 +08:00
wanglei
64c42a4d70 [LoongArch] Define getSetCCResultType for setting vector setCC type
To avoid trigger "No default SetCC type for vectors!" Assertion.

Differential Revision: https://reviews.llvm.org/D135527
2022-10-11 19:05:14 +08:00
wanglei
d1b526fb95 [LoongArch] Add codegen support of GlobalTLSAddress lowering
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
2022-10-11 18:10:13 +08:00
gonglingqin
5593d36356 [LoongArch] Expand fptrunc store from f64 to f32
Differential Revision: https://reviews.llvm.org/D135510
2022-10-09 17:55:42 +08:00
WANG Xuerui
31327c29fb [LoongArch] Don't merge FrameIndex accesses into [F]{LD,ST}X
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
2022-10-09 13:04:21 +08:00