Skip to content

Commit a788a1a

Browse files
authored
[RISCV] Implement codegen for XAndesPerf lea instructions (#137925)
This patch add the patterns for generating XAndesPerf lea instructions. The operation of LEA family instructions is: rd = rs1 + rs2 * (the number of bytes) The variants with *.ze suffix are RV64 only and its operation is: rd = rs1 + ZE32(rs2[31:0]) * (the number of bytes)
1 parent 918cdae commit a788a1a

File tree

5 files changed

+1440
-55
lines changed

5 files changed

+1440
-55
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14516,8 +14516,8 @@ static SDValue combineBinOpToReduce(SDNode *N, SelectionDAG &DAG,
1451614516
// (SLLI (SH*ADD x, y), c0), if c1-c0 equals to [1|2|3].
1451714517
static SDValue transformAddShlImm(SDNode *N, SelectionDAG &DAG,
1451814518
const RISCVSubtarget &Subtarget) {
14519-
// Perform this optimization only in the zba extension.
14520-
if (!Subtarget.hasStdExtZba())
14519+
// Perform this optimization only in the zba/xandesperf extension.
14520+
if (!Subtarget.hasStdExtZba() && !Subtarget.hasVendorXAndesPerf())
1452114521
return SDValue();
1452214522

1452314523
// Skip for vector types and larger types.
@@ -15448,8 +15448,9 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1544815448
if (VT != Subtarget.getXLenVT())
1544915449
return SDValue();
1545015450

15451-
const bool HasShlAdd =
15452-
Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
15451+
const bool HasShlAdd = Subtarget.hasStdExtZba() ||
15452+
Subtarget.hasVendorXTHeadBa() ||
15453+
Subtarget.hasVendorXAndesPerf();
1545315454

1545415455
ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
1545515456
if (!CNode)

llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ class NDSRVInstRR<bits<7> funct7, string opcodestr>
135135
let mayStore = 0;
136136
}
137137

138+
class NDSRVInstLEA<bits<7> funct7, string opcodestr>
139+
: RVInstR<funct7, 0b000, OPC_CUSTOM_2,
140+
(outs GPR:$rd), (ins GPR:$rs2, GPR:$rs1),
141+
opcodestr, "$rd, $rs1, $rs2">,
142+
Sched<[WriteIALU, ReadIALU, ReadIALU]> {
143+
let hasSideEffects = 0;
144+
let mayLoad = 0;
145+
let mayStore = 0;
146+
}
147+
138148
// GP: ADDI, LB, LBU
139149
class NDSRVInstLBGP<bits<2> funct2, string opcodestr>
140150
: RVInst<(outs GPR:$rd), (ins simm18:$imm18),
@@ -321,9 +331,9 @@ def NDS_BNEC : NDSRVInstBC<0b110, "nds.bnec">;
321331
def NDS_BFOS : NDSRVInstBFO<0b011, "nds.bfos">;
322332
def NDS_BFOZ : NDSRVInstBFO<0b010, "nds.bfoz">;
323333

324-
def NDS_LEA_H : NDSRVInstRR<0b0000101, "nds.lea.h">;
325-
def NDS_LEA_W : NDSRVInstRR<0b0000110, "nds.lea.w">;
326-
def NDS_LEA_D : NDSRVInstRR<0b0000111, "nds.lea.d">;
334+
def NDS_LEA_H : NDSRVInstLEA<0b0000101, "nds.lea.h">;
335+
def NDS_LEA_W : NDSRVInstLEA<0b0000110, "nds.lea.w">;
336+
def NDS_LEA_D : NDSRVInstLEA<0b0000111, "nds.lea.d">;
327337

328338
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
329339
def NDS_ADDIGP : NDSRVInstLBGP<0b01, "nds.addigp">;
@@ -345,14 +355,43 @@ def NDS_FLMISM : NDSRVInstRR<0b0010011, "nds.flmism">;
345355
} // Predicates = [HasVendorXAndesPerf]
346356

347357
let Predicates = [HasVendorXAndesPerf, IsRV64] in {
348-
def NDS_LEA_B_ZE : NDSRVInstRR<0b0001000, "nds.lea.b.ze">;
349-
def NDS_LEA_H_ZE : NDSRVInstRR<0b0001001, "nds.lea.h.ze">;
350-
def NDS_LEA_W_ZE : NDSRVInstRR<0b0001010, "nds.lea.w.ze">;
351-
def NDS_LEA_D_ZE : NDSRVInstRR<0b0001011, "nds.lea.d.ze">;
358+
def NDS_LEA_B_ZE : NDSRVInstLEA<0b0001000, "nds.lea.b.ze">;
359+
def NDS_LEA_H_ZE : NDSRVInstLEA<0b0001001, "nds.lea.h.ze">;
360+
def NDS_LEA_W_ZE : NDSRVInstLEA<0b0001010, "nds.lea.w.ze">;
361+
def NDS_LEA_D_ZE : NDSRVInstLEA<0b0001011, "nds.lea.d.ze">;
352362

353363
def NDS_LWUGP : NDSRVInstLWGP<0b110, "nds.lwugp">;
354364
def NDS_LDGP : NDSRVInstLDGP<0b011, "nds.ldgp">;
355365

356366
def NDS_SDGP : NDSRVInstSDGP<0b111, "nds.sdgp">;
357367
} // Predicates = [HasVendorXAndesPerf, IsRV64]
358368
} // DecoderNamespace = "XAndes"
369+
370+
// Patterns
371+
372+
let Predicates = [HasVendorXAndesPerf] in {
373+
374+
defm : ShxAddPat<1, NDS_LEA_H>;
375+
defm : ShxAddPat<2, NDS_LEA_W>;
376+
defm : ShxAddPat<3, NDS_LEA_D>;
377+
378+
def : CSImm12MulBy4Pat<NDS_LEA_W>;
379+
def : CSImm12MulBy8Pat<NDS_LEA_D>;
380+
} // Predicates = [HasVendorXAndesPerf]
381+
382+
let Predicates = [HasVendorXAndesPerf, IsRV64] in {
383+
384+
defm : ADD_UWPat<NDS_LEA_B_ZE>;
385+
386+
defm : ShxAdd_UWPat<1, NDS_LEA_H_ZE>;
387+
defm : ShxAdd_UWPat<2, NDS_LEA_W_ZE>;
388+
defm : ShxAdd_UWPat<3, NDS_LEA_D_ZE>;
389+
390+
defm : Sh1Add_UWPat<NDS_LEA_H_ZE>;
391+
defm : Sh2Add_UWPat<NDS_LEA_W_ZE>;
392+
defm : Sh3Add_UWPat<NDS_LEA_D_ZE>;
393+
394+
def : Sh1AddPat<NDS_LEA_H_ZE>;
395+
def : Sh2AddPat<NDS_LEA_W_ZE>;
396+
def : Sh3AddPat<NDS_LEA_D_ZE>;
397+
} // Predicates = [HasVendorXAndesPerf, IsRV64]

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -672,10 +672,7 @@ def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (PACK GPR:$rs, (XLenVT X0))>;
672672
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in
673673
def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (PACKW GPR:$rs, (XLenVT X0))>;
674674

675-
let Predicates = [HasStdExtZba] in {
676-
677-
foreach i = {1,2,3} in {
678-
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
675+
multiclass ShxAddPat<int i, Instruction shxadd> {
679676
def : Pat<(XLenVT (add_like_non_imm12 (shl GPR:$rs1, (XLenVT i)), GPR:$rs2)),
680677
(shxadd GPR:$rs1, GPR:$rs2)>;
681678
def : Pat<(XLenVT (riscv_shl_add GPR:$rs1, (XLenVT i), GPR:$rs2)),
@@ -687,15 +684,90 @@ foreach i = {1,2,3} in {
687684
(shxadd pat:$rs1, GPR:$rs2)>;
688685
}
689686

690-
def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
691-
(SH2ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
687+
class CSImm12MulBy4Pat<Instruction sh2add>
688+
: Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
689+
(sh2add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
692690
GPR:$r)>;
693-
def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
694-
(SH3ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
691+
692+
class CSImm12MulBy8Pat<Instruction sh3add>
693+
: Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
694+
(sh3add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
695695
GPR:$r)>;
696696

697+
let Predicates = [HasStdExtZba] in {
698+
foreach i = {1,2,3} in {
699+
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
700+
defm : ShxAddPat<i, shxadd>;
701+
}
702+
703+
def : CSImm12MulBy4Pat<SH2ADD>;
704+
def : CSImm12MulBy8Pat<SH3ADD>;
697705
} // Predicates = [HasStdExtZba]
698706

707+
multiclass ADD_UWPat<Instruction add_uw> {
708+
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
709+
(add_uw GPR:$rs1, GPR:$rs2)>;
710+
def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (add_uw GPR:$rs, (XLenVT X0))>;
711+
}
712+
713+
multiclass ShxAdd_UWPat<int i, Instruction shxadd_uw> {
714+
def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)),
715+
(XLenVT GPR:$rs2))),
716+
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
717+
def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
718+
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
719+
720+
defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
721+
// More complex cases use a ComplexPattern.
722+
def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
723+
(shxadd_uw pat:$rs1, GPR:$rs2)>;
724+
}
725+
726+
multiclass Sh1Add_UWPat<Instruction sh1add_uw> {
727+
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF),
728+
(XLenVT GPR:$rs2))),
729+
(sh1add_uw GPR:$rs1, GPR:$rs2)>;
730+
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
731+
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE),
732+
(XLenVT GPR:$rs2))),
733+
(sh1add_uw (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
734+
}
735+
736+
multiclass Sh2Add_UWPat<Instruction sh2add_uw> {
737+
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF),
738+
(XLenVT GPR:$rs2))),
739+
(sh2add_uw GPR:$rs1, GPR:$rs2)>;
740+
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
741+
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC),
742+
(XLenVT GPR:$rs2))),
743+
(sh2add_uw (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
744+
}
745+
746+
multiclass Sh3Add_UWPat<Instruction sh3add_uw> {
747+
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
748+
(XLenVT GPR:$rs2))),
749+
(sh3add_uw (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
750+
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
751+
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8),
752+
(XLenVT GPR:$rs2))),
753+
(sh3add_uw (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
754+
}
755+
756+
class Sh1AddPat<Instruction sh1add>
757+
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE),
758+
(XLenVT GPR:$rs2))),
759+
(sh1add (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
760+
761+
class Sh2AddPat<Instruction sh2add>
762+
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC),
763+
(XLenVT GPR:$rs2))),
764+
(sh2add (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
765+
766+
class Sh3AddPat<Instruction sh3add>
767+
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
768+
(XLenVT GPR:$rs2))),
769+
(sh3add (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
770+
699771
let Predicates = [HasStdExtZba, IsRV64] in {
700772
def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
701773
(SLLI_UW GPR:$rs1, uimm5:$shamt)>;
@@ -704,47 +776,21 @@ def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
704776
def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),
705777
(SLLI_UW (XLenVT (SRLI GPR:$rs1, Shifted32OnesMask:$mask)),
706778
Shifted32OnesMask:$mask)>;
707-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
708-
(ADD_UW GPR:$rs1, GPR:$rs2)>;
709-
def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, (XLenVT X0))>;
710779

711-
foreach i = {1,2,3} in {
712-
defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");
713-
def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)), (XLenVT GPR:$rs2))),
714-
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
715-
def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
716-
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
717-
}
718-
719-
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), (XLenVT GPR:$rs2))),
720-
(SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
721-
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), (XLenVT GPR:$rs2))),
722-
(SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
723-
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), (XLenVT GPR:$rs2))),
724-
(SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
780+
defm : ADD_UWPat<ADD_UW>;
725781

726-
// More complex cases use a ComplexPattern.
727782
foreach i = {1,2,3} in {
728-
defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
729-
def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
730-
(!cast<Instruction>("SH"#i#"ADD_UW") pat:$rs1, GPR:$rs2)>;
783+
defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");
784+
defm : ShxAdd_UWPat<i, shxadd_uw>;
731785
}
732786

733-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE), (XLenVT GPR:$rs2))),
734-
(SH1ADD (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
735-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC), (XLenVT GPR:$rs2))),
736-
(SH2ADD (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
737-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8), (XLenVT GPR:$rs2))),
738-
(SH3ADD (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
739-
740-
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
741-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE), (XLenVT GPR:$rs2))),
742-
(SH1ADD_UW (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
743-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC), (XLenVT GPR:$rs2))),
744-
(SH2ADD_UW (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
745-
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8), (XLenVT GPR:$rs2))),
746-
(SH3ADD_UW (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
787+
defm : Sh1Add_UWPat<SH1ADD_UW>;
788+
defm : Sh2Add_UWPat<SH2ADD_UW>;
789+
defm : Sh3Add_UWPat<SH3ADD_UW>;
747790

791+
def : Sh1AddPat<SH1ADD>;
792+
def : Sh2AddPat<SH2ADD>;
793+
def : Sh3AddPat<SH3ADD>;
748794
} // Predicates = [HasStdExtZba, IsRV64]
749795

750796
let Predicates = [HasStdExtZbcOrZbkc] in {

0 commit comments

Comments
 (0)