Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14628,8 +14628,8 @@ static SDValue combineBinOpToReduce(SDNode *N, SelectionDAG &DAG,
// (SLLI (SH*ADD x, y), c0), if c1-c0 equals to [1|2|3].
static SDValue transformAddShlImm(SDNode *N, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
// Perform this optimization only in the zba extension.
if (!Subtarget.hasStdExtZba())
// Perform this optimization only in the zba/xandesperf extension.
if (!Subtarget.hasStdExtZba() && !Subtarget.hasVendorXAndesPerf())
return SDValue();

// Skip for vector types and larger types.
Expand Down Expand Up @@ -15536,8 +15536,9 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
if (VT != Subtarget.getXLenVT())
return SDValue();

const bool HasShlAdd =
Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
const bool HasShlAdd = Subtarget.hasStdExtZba() ||
Subtarget.hasVendorXTHeadBa() ||
Subtarget.hasVendorXAndesPerf();

ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
if (!CNode)
Expand Down
53 changes: 46 additions & 7 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ class NDSRVInstRR<bits<7> funct7, string opcodestr>
let mayStore = 0;
}

class NDSRVInstLEA<bits<7> funct7, string opcodestr>
: RVInstR<funct7, 0b000, OPC_CUSTOM_2,
(outs GPR:$rd), (ins GPR:$rs2, GPR:$rs1),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment about why the operands are reversed.

opcodestr, "$rd, $rs1, $rs2">,
Sched<[WriteIALU, ReadIALU, ReadIALU]> {
let hasSideEffects = 0;
let mayLoad = 0;
let mayStore = 0;
}

// GP: ADDI, LB, LBU
class NDSRVInstLBGP<bits<2> funct2, string opcodestr>
: RVInst<(outs GPR:$rd), (ins simm18:$imm18),
Expand Down Expand Up @@ -321,9 +331,9 @@ def NDS_BNEC : NDSRVInstBC<0b110, "nds.bnec">;
def NDS_BFOS : NDSRVInstBFO<0b011, "nds.bfos">;
def NDS_BFOZ : NDSRVInstBFO<0b010, "nds.bfoz">;

def NDS_LEA_H : NDSRVInstRR<0b0000101, "nds.lea.h">;
def NDS_LEA_W : NDSRVInstRR<0b0000110, "nds.lea.w">;
def NDS_LEA_D : NDSRVInstRR<0b0000111, "nds.lea.d">;
def NDS_LEA_H : NDSRVInstLEA<0b0000101, "nds.lea.h">;
def NDS_LEA_W : NDSRVInstLEA<0b0000110, "nds.lea.w">;
def NDS_LEA_D : NDSRVInstLEA<0b0000111, "nds.lea.d">;

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

let Predicates = [HasVendorXAndesPerf, IsRV64] in {
def NDS_LEA_B_ZE : NDSRVInstRR<0b0001000, "nds.lea.b.ze">;
def NDS_LEA_H_ZE : NDSRVInstRR<0b0001001, "nds.lea.h.ze">;
def NDS_LEA_W_ZE : NDSRVInstRR<0b0001010, "nds.lea.w.ze">;
def NDS_LEA_D_ZE : NDSRVInstRR<0b0001011, "nds.lea.d.ze">;
def NDS_LEA_B_ZE : NDSRVInstLEA<0b0001000, "nds.lea.b.ze">;
def NDS_LEA_H_ZE : NDSRVInstLEA<0b0001001, "nds.lea.h.ze">;
def NDS_LEA_W_ZE : NDSRVInstLEA<0b0001010, "nds.lea.w.ze">;
def NDS_LEA_D_ZE : NDSRVInstLEA<0b0001011, "nds.lea.d.ze">;

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

def NDS_SDGP : NDSRVInstSDGP<0b111, "nds.sdgp">;
} // Predicates = [HasVendorXAndesPerf, IsRV64]
} // DecoderNamespace = "XAndes"

// Patterns

let Predicates = [HasVendorXAndesPerf] in {

defm : ShxAddPat<1, NDS_LEA_H>;
defm : ShxAddPat<2, NDS_LEA_W>;
defm : ShxAddPat<3, NDS_LEA_D>;

def : CSImm12MulBy4Pat<NDS_LEA_W>;
def : CSImm12MulBy8Pat<NDS_LEA_D>;
} // Predicates = [HasVendorXAndesPerf]

let Predicates = [HasVendorXAndesPerf, IsRV64] in {

defm : ADD_UWPat<NDS_LEA_B_ZE>;

defm : ShxAdd_UWPat<1, NDS_LEA_H_ZE>;
defm : ShxAdd_UWPat<2, NDS_LEA_W_ZE>;
defm : ShxAdd_UWPat<3, NDS_LEA_D_ZE>;

defm : Sh1Add_UWPat<NDS_LEA_H_ZE>;
defm : Sh2Add_UWPat<NDS_LEA_W_ZE>;
defm : Sh3Add_UWPat<NDS_LEA_D_ZE>;

def : Sh1AddPat<NDS_LEA_H_ZE>;
def : Sh2AddPat<NDS_LEA_W_ZE>;
def : Sh3AddPat<NDS_LEA_D_ZE>;
} // Predicates = [HasVendorXAndesPerf, IsRV64]
132 changes: 89 additions & 43 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,7 @@ def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (PACK GPR:$rs, (XLenVT X0))>;
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in
def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (PACKW GPR:$rs, (XLenVT X0))>;

let Predicates = [HasStdExtZba] in {

foreach i = {1,2,3} in {
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
multiclass ShxAddPat<int i, Instruction shxadd> {
def : Pat<(XLenVT (add_like_non_imm12 (shl GPR:$rs1, (XLenVT i)), GPR:$rs2)),
(shxadd GPR:$rs1, GPR:$rs2)>;
def : Pat<(XLenVT (riscv_shl_add GPR:$rs1, (XLenVT i), GPR:$rs2)),
Expand All @@ -674,15 +671,90 @@ foreach i = {1,2,3} in {
(shxadd pat:$rs1, GPR:$rs2)>;
}

def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
(SH2ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
class CSImm12MulBy4Pat<Instruction sh2add>
: Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
(sh2add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
GPR:$r)>;
def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
(SH3ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),

class CSImm12MulBy8Pat<Instruction sh3add>
: Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
(sh3add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
GPR:$r)>;

let Predicates = [HasStdExtZba] in {
foreach i = {1,2,3} in {
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
defm : ShxAddPat<i, shxadd>;
}

def : CSImm12MulBy4Pat<SH2ADD>;
def : CSImm12MulBy8Pat<SH3ADD>;
} // Predicates = [HasStdExtZba]

multiclass ADD_UWPat<Instruction add_uw> {
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
(add_uw GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (add_uw GPR:$rs, (XLenVT X0))>;
}

multiclass ShxAdd_UWPat<int i, Instruction shxadd_uw> {
def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)),
(XLenVT GPR:$rs2))),
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
(shxadd_uw GPR:$rs1, GPR:$rs2)>;

defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
// More complex cases use a ComplexPattern.
def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
(shxadd_uw pat:$rs1, GPR:$rs2)>;
}

multiclass Sh1Add_UWPat<Instruction sh1add_uw> {
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF),
(XLenVT GPR:$rs2))),
(sh1add_uw GPR:$rs1, GPR:$rs2)>;
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE),
(XLenVT GPR:$rs2))),
(sh1add_uw (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
}

multiclass Sh2Add_UWPat<Instruction sh2add_uw> {
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF),
(XLenVT GPR:$rs2))),
(sh2add_uw GPR:$rs1, GPR:$rs2)>;
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC),
(XLenVT GPR:$rs2))),
(sh2add_uw (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
}

multiclass Sh3Add_UWPat<Instruction sh3add_uw> {
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
(XLenVT GPR:$rs2))),
(sh3add_uw (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8),
(XLenVT GPR:$rs2))),
(sh3add_uw (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
}

class Sh1AddPat<Instruction sh1add>
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE),
(XLenVT GPR:$rs2))),
(sh1add (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;

class Sh2AddPat<Instruction sh2add>
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC),
(XLenVT GPR:$rs2))),
(sh2add (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;

class Sh3AddPat<Instruction sh3add>
: Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
(XLenVT GPR:$rs2))),
(sh3add (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;

let Predicates = [HasStdExtZba, IsRV64] in {
def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
(SLLI_UW GPR:$rs1, uimm5:$shamt)>;
Expand All @@ -691,47 +763,21 @@ def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),
(SLLI_UW (XLenVT (SRLI GPR:$rs1, Shifted32OnesMask:$mask)),
Shifted32OnesMask:$mask)>;
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
(ADD_UW GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, (XLenVT X0))>;

foreach i = {1,2,3} in {
defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");
def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)), (XLenVT GPR:$rs2))),
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
(shxadd_uw GPR:$rs1, GPR:$rs2)>;
}

def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), (XLenVT GPR:$rs2))),
(SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), (XLenVT GPR:$rs2))),
(SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), (XLenVT GPR:$rs2))),
(SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
defm : ADD_UWPat<ADD_UW>;

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

def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE), (XLenVT GPR:$rs2))),
(SH1ADD (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC), (XLenVT GPR:$rs2))),
(SH2ADD (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8), (XLenVT GPR:$rs2))),
(SH3ADD (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;

// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE), (XLenVT GPR:$rs2))),
(SH1ADD_UW (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC), (XLenVT GPR:$rs2))),
(SH2ADD_UW (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8), (XLenVT GPR:$rs2))),
(SH3ADD_UW (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
defm : Sh1Add_UWPat<SH1ADD_UW>;
defm : Sh2Add_UWPat<SH2ADD_UW>;
defm : Sh3Add_UWPat<SH3ADD_UW>;

def : Sh1AddPat<SH1ADD>;
def : Sh2AddPat<SH2ADD>;
def : Sh3AddPat<SH3ADD>;
} // Predicates = [HasStdExtZba, IsRV64]

let Predicates = [HasStdExtZbcOrZbkc] in {
Expand Down
Loading