Skip to content

Commit 7a6568d

Browse files
[RISCV] Support LLVM IR intrinsics for XAndesVSIntLoad (#147493)
This patch adds LLVM IR intrinsic support for XAndesVSIntLoad. The document for the intrinsics can be found at: https://github.com/andestech/andes-vector-intrinsic-doc/blob/ast-v5_4_0-release-v5/auto-generated/andes-v5/intrinsic_funcs/04_andes_vector_int4_load_extension.adoc The clang part will be added in a later patch. --------- Co-authored-by: Lino Hsing-Yu Peng <linopeng@andestech.com>
1 parent 68494ae commit 7a6568d

File tree

7 files changed

+563
-0
lines changed

7 files changed

+563
-0
lines changed

llvm/include/llvm/IR/IntrinsicsRISCVXAndes.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ let TargetPrefix = "riscv" in {
1515
def int_riscv_nds_vfwcvt_s_bf16 : RISCVConversionUnMasked;
1616
def int_riscv_nds_vfncvt_bf16_s : RISCVConversionUnMaskedRoundingMode;
1717

18+
// Andes Vector INT4 Load Extension
19+
defm nds_vln : RISCVUSLoad;
20+
defm nds_vlnu : RISCVUSLoad;
21+
1822
// Andes Vector Packed FP16 Extension
1923
defm nds_vfpmadt : RISCVBinaryAAXRoundingMode;
2024
defm nds_vfpmadb : RISCVBinaryAAXRoundingMode;

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace RISCV {
4848
#define GET_RISCVVSETable_IMPL
4949
#define GET_RISCVVLXTable_IMPL
5050
#define GET_RISCVVSXTable_IMPL
51+
#define GET_RISCVNDSVLNTable_IMPL
5152
#include "RISCVGenSearchableTables.inc"
5253
} // namespace RISCV
5354

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,14 @@ struct VLX_VSXPseudo {
749749
uint16_t Pseudo;
750750
};
751751

752+
struct NDSVLNPseudo {
753+
uint16_t Masked : 1;
754+
uint16_t Unsigned : 1;
755+
uint16_t Log2SEW : 3;
756+
uint16_t LMUL : 3;
757+
uint16_t Pseudo;
758+
};
759+
752760
#define GET_RISCVVSSEGTable_DECL
753761
#define GET_RISCVVLSEGTable_DECL
754762
#define GET_RISCVVLXSEGTable_DECL
@@ -757,6 +765,7 @@ struct VLX_VSXPseudo {
757765
#define GET_RISCVVSETable_DECL
758766
#define GET_RISCVVLXTable_DECL
759767
#define GET_RISCVVSXTable_DECL
768+
#define GET_RISCVNDSVLNTable_DECL
760769
#include "RISCVGenSearchableTables.inc"
761770
} // namespace RISCV
762771

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,6 +2299,37 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
22992299
ReplaceNode(Node, Load);
23002300
return;
23012301
}
2302+
case Intrinsic::riscv_nds_vln:
2303+
case Intrinsic::riscv_nds_vln_mask:
2304+
case Intrinsic::riscv_nds_vlnu:
2305+
case Intrinsic::riscv_nds_vlnu_mask: {
2306+
bool IsMasked = IntNo == Intrinsic::riscv_nds_vln_mask ||
2307+
IntNo == Intrinsic::riscv_nds_vlnu_mask;
2308+
bool IsUnsigned = IntNo == Intrinsic::riscv_nds_vlnu ||
2309+
IntNo == Intrinsic::riscv_nds_vlnu_mask;
2310+
2311+
MVT VT = Node->getSimpleValueType(0);
2312+
unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
2313+
unsigned CurOp = 2;
2314+
SmallVector<SDValue, 8> Operands;
2315+
2316+
Operands.push_back(Node->getOperand(CurOp++));
2317+
addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked,
2318+
/*IsStridedOrIndexed=*/false, Operands,
2319+
/*IsLoad=*/true);
2320+
2321+
RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
2322+
const RISCV::NDSVLNPseudo *P = RISCV::getNDSVLNPseudo(
2323+
IsMasked, IsUnsigned, Log2SEW, static_cast<unsigned>(LMUL));
2324+
MachineSDNode *Load =
2325+
CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
2326+
2327+
if (auto *MemOp = dyn_cast<MemSDNode>(Node))
2328+
CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
2329+
2330+
ReplaceNode(Node, Load);
2331+
return;
2332+
}
23022333
}
23032334
break;
23042335
}

llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ def Log2 : SDNodeXForm<imm, [{
6464
return CurDAG->getTargetConstant(Imm, SDLoc(N), N->getValueType(0));
6565
}]>;
6666

67+
//===----------------------------------------------------------------------===//
68+
// Pseudo table
69+
//===----------------------------------------------------------------------===//
70+
71+
class RISCVNDSVLN<bit M, bit U, bits<3> S, bits<3> L> {
72+
bits<1> Masked = M;
73+
bits<1> Unsigned = U;
74+
bits<3> Log2SEW = S;
75+
bits<3> LMUL = L;
76+
Pseudo Pseudo = !cast<Pseudo>(NAME);
77+
}
78+
79+
def RISCVNDSVLNTable : GenericTable {
80+
let FilterClass = "RISCVNDSVLN";
81+
let CppTypeName = "NDSVLNPseudo";
82+
let Fields = ["Masked", "Unsigned", "Log2SEW", "LMUL", "Pseudo"];
83+
let PrimaryKey = ["Masked", "Unsigned", "Log2SEW", "LMUL"];
84+
let PrimaryKeyName = "getNDSVLNPseudo";
85+
}
86+
6787
//===----------------------------------------------------------------------===//
6888
// Instruction Class Templates
6989
//===----------------------------------------------------------------------===//
@@ -416,6 +436,39 @@ class NDSRVInstVLN<bits<5> funct5, string opcodestr>
416436
let RVVConstraint = VMConstraint;
417437
}
418438

439+
class VPseudoVLN8NoMask<VReg RetClass, bit U> :
440+
Pseudo<(outs RetClass:$rd),
441+
(ins RetClass:$dest,
442+
GPRMemZeroOffset:$rs1,
443+
AVL:$vl, sew:$sew, vec_policy:$policy), []>,
444+
RISCVVPseudo,
445+
RISCVNDSVLN</*Masked*/0, /*Unsigned*/U, !logtwo(8), VLMul> {
446+
let mayLoad = 1;
447+
let mayStore = 0;
448+
let hasSideEffects = 0;
449+
let HasVLOp = 1;
450+
let HasSEWOp = 1;
451+
let HasVecPolicyOp = 1;
452+
let Constraints = "$rd = $dest";
453+
}
454+
455+
class VPseudoVLN8Mask<VReg RetClass, bit U> :
456+
Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
457+
(ins GetVRegNoV0<RetClass>.R:$passthru,
458+
GPRMemZeroOffset:$rs1,
459+
VMaskOp:$vm, AVL:$vl, sew:$sew, vec_policy:$policy), []>,
460+
RISCVVPseudo,
461+
RISCVNDSVLN</*Masked*/1, /*Unsigned*/U, !logtwo(8), VLMul> {
462+
let mayLoad = 1;
463+
let mayStore = 0;
464+
let hasSideEffects = 0;
465+
let HasVLOp = 1;
466+
let HasSEWOp = 1;
467+
let HasVecPolicyOp = 1;
468+
let UsesMaskPolicy = 1;
469+
let Constraints = "$rd = $passthru";
470+
}
471+
419472
//===----------------------------------------------------------------------===//
420473
// Multiclass
421474
//===----------------------------------------------------------------------===//
@@ -465,6 +518,22 @@ multiclass VPatConversionBF16_S<string intrinsic, string instruction> {
465518
}
466519
}
467520

521+
multiclass VPseudoVLN8<bit U> {
522+
foreach lmul = MxSet<8>.m in {
523+
defvar LInfo = lmul.MX;
524+
defvar vreg = lmul.vrclass;
525+
let VLMul = lmul.value in {
526+
def "_V_" # LInfo :
527+
VPseudoVLN8NoMask<vreg, U>,
528+
VLESched<LInfo>;
529+
def "_V_" # LInfo # "_MASK" :
530+
VPseudoVLN8Mask<vreg, U>,
531+
RISCVMaskedPseudo<MaskIdx=2>,
532+
VLESched<LInfo>;
533+
}
534+
}
535+
}
536+
468537
let fprclass = !cast<RegisterClass>("FPR32") in
469538
def SCALAR_F16_FPR32 : FPR_Info<16>;
470539

@@ -684,6 +753,11 @@ defm : VPatConversionS_BF16<"int_riscv_nds_vfwcvt_s_bf16",
684753
defm : VPatConversionBF16_S<"int_riscv_nds_vfncvt_bf16_s",
685754
"PseudoNDS_VFNCVT_BF16">;
686755

756+
let Predicates = [HasVendorXAndesVSIntLoad] in {
757+
defm PseudoNDS_VLN8 : VPseudoVLN8<0>;
758+
defm PseudoNDS_VLNU8 : VPseudoVLN8<1>;
759+
} // Predicates = [HasVendorXAndesVSIntLoad]
760+
687761
let Predicates = [HasVendorXAndesVPackFPH],
688762
mayRaiseFPException = true in {
689763
defm PseudoNDS_VFPMADT : VPseudoVFPMAD_VF_RM;

0 commit comments

Comments
 (0)