Skip to content

Commit 53393e2

Browse files
heihertstellar
authored andcommitted
[LoongArch] Prevent R0/R1 allocation for rj operand of [G]CSRXCHG (llvm#140862)
The `[G]CSRXCHG` instruction must not use R0 or R1 as the `rj` operand, as encoding `rj` as 0 or 1 will be interpreted as `[G]CSRRD` OR `[G]CSRWR`, respectively, rather than `[G]CSRXCHG`. This patch introduces a new register class `GPRNoR0R1` and updates the `[G]CSRXCHG` instruction definition to use it for the `rj` operand, ensuring the register allocator avoids assigning R0 or R1. Fixes llvm#140842 (cherry picked from commit bd8578c)
1 parent 6fcb1c1 commit 53393e2

File tree

6 files changed

+44
-4
lines changed

6 files changed

+44
-4
lines changed

llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,6 +1663,9 @@ LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
16631663
return Match_Success;
16641664
}
16651665

1666+
if (Kind == MCK_GPRNoR0R1 && (Reg == LoongArch::R0 || Reg == LoongArch::R1))
1667+
return Match_RequiresOpnd2NotR0R1;
1668+
16661669
return Match_InvalidOperand;
16671670
}
16681671

llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
6262
return MCDisassembler::Success;
6363
}
6464

65+
static DecodeStatus
66+
DecodeGPRNoR0R1RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
67+
const MCDisassembler *Decoder) {
68+
if (RegNo <= 1)
69+
return MCDisassembler::Fail;
70+
return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
71+
}
72+
6573
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
6674
uint64_t Address,
6775
const MCDisassembler *Decoder) {

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,7 +2351,7 @@ let hasSideEffects = 1, Constraints = "$rd = $dst" in {
23512351
def CSRWR : FmtCSR<0x04000020, (outs GPR:$dst),
23522352
(ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">;
23532353
def CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst),
2354-
(ins GPR:$rd, GPR:$rj, uimm14:$csr_num),
2354+
(ins GPR:$rd, GPRNoR0R1:$rj, uimm14:$csr_num),
23552355
"$rd, $rj, $csr_num">;
23562356
} // hasSideEffects = 1, Constraints = "$rd = $dst"
23572357

@@ -2398,8 +2398,8 @@ def IDLE : MISC_I15<0x06488000>;
23982398
def : Pat<(loongarch_csrrd uimm14:$imm14), (CSRRD uimm14:$imm14)>;
23992399
def : Pat<(loongarch_csrwr GPR:$rd, uimm14:$imm14),
24002400
(CSRWR GPR:$rd, uimm14:$imm14)>;
2401-
def : Pat<(loongarch_csrxchg GPR:$rd, GPR:$rj, uimm14:$imm14),
2402-
(CSRXCHG GPR:$rd, GPR:$rj, uimm14:$imm14)>;
2401+
def : Pat<(loongarch_csrxchg GPR:$rd, GPRNoR0R1:$rj, uimm14:$imm14),
2402+
(CSRXCHG GPR:$rd, GPRNoR0R1:$rj, uimm14:$imm14)>;
24032403

24042404
def : Pat<(loongarch_iocsrrd_b GPR:$rj), (IOCSRRD_B GPR:$rj)>;
24052405
def : Pat<(loongarch_iocsrrd_h GPR:$rj), (IOCSRRD_H GPR:$rj)>;

llvm/lib/Target/LoongArch/LoongArchLVZInstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let Constraints = "$rd = $dst" in {
2323
def GCSRWR : FmtCSR<0x05000020, (outs GPR:$dst),
2424
(ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">;
2525
def GCSRXCHG : FmtCSRXCHG<0x05000000, (outs GPR:$dst),
26-
(ins GPR:$rd, GPR:$rj, uimm14:$csr_num),
26+
(ins GPR:$rd, GPRNoR0R1:$rj, uimm14:$csr_num),
2727
"$rd, $rj, $csr_num">;
2828
} // Constraints = "$rd = $dst"
2929

llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ def GPRT : GPRRegisterClass<(add // a0...a7, t0...t8
127127
// prediction.
128128
def GPRJR : GPRRegisterClass<(sub GPR, R1)>;
129129

130+
// Don't use R0 or R1 for the rj operand of [G]CSRXCHG, because when rj is
131+
// encoded as 0 or 1, the instruction is interpreted as [G]CSRRD or [G]CSRWR,
132+
// respectively, rather than [G]CSRXCHG.
133+
def GPRNoR0R1 : GPRRegisterClass<(sub GPR, R0, R1)>;
134+
130135
// Floating point registers
131136

132137
let RegAltNameIndices = [RegAliasName] in {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
2+
; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
3+
4+
declare i32 @llvm.loongarch.csrxchg.w(i32, i32, i32 immarg)
5+
6+
;; Check that the rj operand of csrxchg is not R0.
7+
define void @csrxchg_w_rj_not_r0(i32 signext %a) {
8+
; CHECK-NOT: csrxchg ${{[a-z]*}}, $r0, 0
9+
; CHECK-NOT: csrxchg ${{[a-z]*}}, $zero, 0
10+
entry:
11+
%0 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 0, i32 0)
12+
ret void
13+
}
14+
15+
;; Check that the rj operand of csrxchg is not R1.
16+
define i32 @csrxchg_w_rj_not_r1() {
17+
; CHECK-NOT: csrxchg ${{[a-z]*}}, $r1, 0
18+
; CHECK-NOT: csrxchg ${{[a-z]*}}, $ra, 0
19+
entry:
20+
%0 = tail call i32 asm "", "=r,r,i,{r4},{r5},{r6},{r7},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},{r16},{r17},{r18},{r19},{r20},{r23},{r24},{r25},{r26},{r27},{r28},{r29},{r30},{r31},0"(i32 4, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
21+
%1 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %0, i32 4, i32 0)
22+
%2 = tail call i32 asm "", "=r,r,i,{r4},{r5},{r6},{r7},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},{r16},{r17},{r18},{r19},{r20},{r23},{r24},{r25},{r26},{r27},{r28},{r29},{r30},{r31},0"(i32 4, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 %1)
23+
ret i32 %2
24+
}

0 commit comments

Comments
 (0)