Skip to content

Commit a8b96ea

Browse files
committed
[RISCV] Implement vssseg intrinsics.
Define vlsseg intrinsics and pseudo instructions. Lower vlsseg intrinsics to pseudo instructions in RISCVDAGToDAGISel. Differential Revision: https://reviews.llvm.org/D94863
1 parent e5e3290 commit a8b96ea

File tree

6 files changed

+9318
-17
lines changed

6 files changed

+9318
-17
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,26 @@ let TargetPrefix = "riscv" in {
540540
llvm_anyint_ty]),
541541
[NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
542542

543+
// For stride segment store
544+
// Input: (value, pointer, offset, vl)
545+
class RISCVSSegStore<int nf>
546+
: Intrinsic<[],
547+
!listconcat([llvm_anyvector_ty],
548+
!listsplat(LLVMMatchType<0>, !add(nf, -1)),
549+
[LLVMPointerToElt<0>, llvm_anyint_ty,
550+
LLVMMatchType<1>]),
551+
[NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
552+
// For stride segment store with mask
553+
// Input: (value, pointer, offset, mask, vl)
554+
class RISCVSSegStoreMask<int nf>
555+
: Intrinsic<[],
556+
!listconcat([llvm_anyvector_ty],
557+
!listsplat(LLVMMatchType<0>, !add(nf, -1)),
558+
[LLVMPointerToElt<0>, llvm_anyint_ty,
559+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
560+
LLVMMatchType<1>]),
561+
[NoCapture<ArgIndex<nf>>, IntrWriteMem]>, RISCVVIntrinsic;
562+
543563
multiclass RISCVUSLoad {
544564
def "int_riscv_" # NAME : RISCVUSLoad;
545565
def "int_riscv_" # NAME # "_mask" : RISCVUSLoadMask;
@@ -654,6 +674,10 @@ let TargetPrefix = "riscv" in {
654674
def "int_riscv_" # NAME : RISCVUSSegStore<nf>;
655675
def "int_riscv_" # NAME # "_mask" : RISCVUSSegStoreMask<nf>;
656676
}
677+
multiclass RISCVSSegStore<int nf> {
678+
def "int_riscv_" # NAME : RISCVSSegStore<nf>;
679+
def "int_riscv_" # NAME # "_mask" : RISCVSSegStoreMask<nf>;
680+
}
657681

658682
defm vle : RISCVUSLoad;
659683
defm vleff : RISCVUSLoad;
@@ -949,6 +973,7 @@ let TargetPrefix = "riscv" in {
949973
defm vlseg # nf : RISCVUSSegLoad<nf>;
950974
defm vlsseg # nf : RISCVSSegLoad<nf>;
951975
defm vsseg # nf : RISCVUSSegStore<nf>;
976+
defm vssseg # nf : RISCVSSegStore<nf>;
952977
}
953978

954979
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -220,43 +220,63 @@ void RISCVDAGToDAGISel::selectVLSEGMask(SDNode *Node, unsigned IntNo,
220220
CurDAG->RemoveDeadNode(Node);
221221
}
222222

223-
void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, unsigned IntNo) {
223+
void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, unsigned IntNo,
224+
bool IsStrided) {
224225
SDLoc DL(Node);
225226
unsigned NF = Node->getNumOperands() - 4;
227+
if (IsStrided)
228+
NF--;
226229
EVT VT = Node->getOperand(2)->getValueType(0);
227230
unsigned ScalarSize = VT.getScalarSizeInBits();
228231
MVT XLenVT = Subtarget->getXLenVT();
229232
RISCVVLMUL LMUL = getLMUL(VT);
230233
SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
231234
SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
232235
SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
233-
SDValue Operands[] = {StoreVal,
234-
Node->getOperand(2 + NF), // Base pointer.
235-
Node->getOperand(3 + NF), // VL.
236-
SEW, Node->getOperand(0)}; // Chain
236+
SmallVector<SDValue, 6> Operands;
237+
Operands.push_back(StoreVal);
238+
Operands.push_back(Node->getOperand(2 + NF)); // Base pointer.
239+
if (IsStrided) {
240+
Operands.push_back(Node->getOperand(3 + NF)); // Stride.
241+
Operands.push_back(Node->getOperand(4 + NF)); // VL.
242+
} else {
243+
Operands.push_back(Node->getOperand(3 + NF)); // VL.
244+
}
245+
Operands.push_back(SEW);
246+
Operands.push_back(Node->getOperand(0)); // Chain.
237247
const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
238248
IntNo, ScalarSize, static_cast<unsigned>(LMUL));
239249
SDNode *Store =
240250
CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
241251
ReplaceNode(Node, Store);
242252
}
243253

244-
void RISCVDAGToDAGISel::selectVSSEGMask(SDNode *Node, unsigned IntNo) {
254+
void RISCVDAGToDAGISel::selectVSSEGMask(SDNode *Node, unsigned IntNo,
255+
bool IsStrided) {
245256
SDLoc DL(Node);
246257
unsigned NF = Node->getNumOperands() - 5;
258+
if (IsStrided)
259+
NF--;
247260
EVT VT = Node->getOperand(2)->getValueType(0);
248261
unsigned ScalarSize = VT.getScalarSizeInBits();
249262
MVT XLenVT = Subtarget->getXLenVT();
250263
RISCVVLMUL LMUL = getLMUL(VT);
251264
SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
252265
SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
253266
SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
254-
SDValue Operands[] = {StoreVal,
255-
Node->getOperand(2 + NF), // Base pointer.
256-
Node->getOperand(3 + NF), // Mask.
257-
Node->getOperand(4 + NF), // VL.
258-
SEW,
259-
Node->getOperand(0)}; // Chain
267+
SmallVector<SDValue, 7> Operands;
268+
Operands.push_back(StoreVal);
269+
Operands.push_back(Node->getOperand(2 + NF)); // Base pointer.
270+
if (IsStrided) {
271+
Operands.push_back(Node->getOperand(3 + NF)); // Stride.
272+
Operands.push_back(Node->getOperand(4 + NF)); // Mask.
273+
Operands.push_back(Node->getOperand(5 + NF)); // VL.
274+
} else {
275+
Operands.push_back(Node->getOperand(3 + NF)); // Mask.
276+
Operands.push_back(Node->getOperand(4 + NF)); // VL.
277+
}
278+
Operands.push_back(SEW);
279+
Operands.push_back(Node->getOperand(0)); // Chain.
260280
const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
261281
IntNo, ScalarSize, static_cast<unsigned>(LMUL));
262282
SDNode *Store =
@@ -439,7 +459,7 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
439459
case Intrinsic::riscv_vsseg6:
440460
case Intrinsic::riscv_vsseg7:
441461
case Intrinsic::riscv_vsseg8: {
442-
selectVSSEG(Node, IntNo);
462+
selectVSSEG(Node, IntNo, /*IsStrided=*/false);
443463
return;
444464
}
445465
case Intrinsic::riscv_vsseg2_mask:
@@ -449,7 +469,27 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
449469
case Intrinsic::riscv_vsseg6_mask:
450470
case Intrinsic::riscv_vsseg7_mask:
451471
case Intrinsic::riscv_vsseg8_mask: {
452-
selectVSSEGMask(Node, IntNo);
472+
selectVSSEGMask(Node, IntNo, /*IsStrided=*/false);
473+
return;
474+
}
475+
case Intrinsic::riscv_vssseg2:
476+
case Intrinsic::riscv_vssseg3:
477+
case Intrinsic::riscv_vssseg4:
478+
case Intrinsic::riscv_vssseg5:
479+
case Intrinsic::riscv_vssseg6:
480+
case Intrinsic::riscv_vssseg7:
481+
case Intrinsic::riscv_vssseg8: {
482+
selectVSSEG(Node, IntNo, /*IsStrided=*/true);
483+
return;
484+
}
485+
case Intrinsic::riscv_vssseg2_mask:
486+
case Intrinsic::riscv_vssseg3_mask:
487+
case Intrinsic::riscv_vssseg4_mask:
488+
case Intrinsic::riscv_vssseg5_mask:
489+
case Intrinsic::riscv_vssseg6_mask:
490+
case Intrinsic::riscv_vssseg7_mask:
491+
case Intrinsic::riscv_vssseg8_mask: {
492+
selectVSSEGMask(Node, IntNo, /*IsStrided=*/true);
453493
return;
454494
}
455495
}

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
5757

5858
void selectVLSEG(SDNode *Node, unsigned IntNo, bool IsStrided);
5959
void selectVLSEGMask(SDNode *Node, unsigned IntNo, bool IsStrided);
60-
void selectVSSEG(SDNode *Node, unsigned IntNo);
61-
void selectVSSEGMask(SDNode *Node, unsigned IntNo);
60+
void selectVSSEG(SDNode *Node, unsigned IntNo, bool IsStrided);
61+
void selectVSSEGMask(SDNode *Node, unsigned IntNo, bool IsStrided);
6262

6363
// Include the pieces autogenerated from the target description.
6464
#include "RISCVGenDAGISel.inc"

llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ class PseudoToVInst<string PseudoInst> {
440440
class ToLowerCase<string Upper> {
441441
string L = !subst("VLSEG", "vlseg",
442442
!subst("VLSSEG", "vlsseg",
443-
!subst("VSSEG", "vsseg", Upper)));
443+
!subst("VSSEG", "vsseg",
444+
!subst("VSSSEG", "vssseg", Upper))));
444445
}
445446

446447
// Example: PseudoVLSEG2E32_V_M2 -> int_riscv_vlseg2
@@ -1076,6 +1077,38 @@ class VPseudoUSSegStoreMask<VReg ValClass, bits<11> EEW>:
10761077
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
10771078
}
10781079

1080+
class VPseudoSSegStoreNoMask<VReg ValClass, bits<11> EEW>:
1081+
Pseudo<(outs),
1082+
(ins ValClass:$rd, GPR:$rs1, GPR: $offset, GPR:$vl, ixlenimm:$sew),[]>,
1083+
RISCVVPseudo,
1084+
RISCVZvlsseg<PseudoToIntrinsic<NAME, false>.Intrinsic, EEW, VLMul> {
1085+
let mayLoad = 0;
1086+
let mayStore = 1;
1087+
let hasSideEffects = 0;
1088+
let usesCustomInserter = 1;
1089+
let Uses = [VL, VTYPE];
1090+
let HasVLOp = 1;
1091+
let HasSEWOp = 1;
1092+
let HasDummyMask = 1;
1093+
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
1094+
}
1095+
1096+
class VPseudoSSegStoreMask<VReg ValClass, bits<11> EEW>:
1097+
Pseudo<(outs),
1098+
(ins ValClass:$rd, GPR:$rs1, GPR: $offset,
1099+
VMaskOp:$vm, GPR:$vl, ixlenimm:$sew),[]>,
1100+
RISCVVPseudo,
1101+
RISCVZvlsseg<PseudoToIntrinsic<NAME, true>.Intrinsic, EEW, VLMul> {
1102+
let mayLoad = 0;
1103+
let mayStore = 1;
1104+
let hasSideEffects = 0;
1105+
let usesCustomInserter = 1;
1106+
let Uses = [VL, VTYPE];
1107+
let HasVLOp = 1;
1108+
let HasSEWOp = 1;
1109+
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
1110+
}
1111+
10791112
multiclass VPseudoUSLoad {
10801113
foreach lmul = MxList.m in {
10811114
defvar LInfo = lmul.MX;
@@ -1629,6 +1662,21 @@ multiclass VPseudoUSSegStore {
16291662
}
16301663
}
16311664

1665+
multiclass VPseudoSSegStore {
1666+
foreach eew = EEWList in {
1667+
foreach lmul = MxSet<eew>.m in {
1668+
defvar LInfo = lmul.MX;
1669+
let VLMul = lmul.value in {
1670+
foreach nf = NFSet<lmul>.L in {
1671+
defvar vreg = SegRegClass<lmul, nf>.RC;
1672+
def nf # "E" # eew # "_V_" # LInfo : VPseudoSSegStoreNoMask<vreg, eew>;
1673+
def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSSegStoreMask<vreg, eew>;
1674+
}
1675+
}
1676+
}
1677+
}
1678+
}
1679+
16321680
//===----------------------------------------------------------------------===//
16331681
// Helpers to define the intrinsic patterns.
16341682
//===----------------------------------------------------------------------===//
@@ -2830,6 +2878,7 @@ foreach eew = EEWList in {
28302878
defm PseudoVLSEG : VPseudoUSSegLoad;
28312879
defm PseudoVLSSEG : VPseudoSSegLoad;
28322880
defm PseudoVSSEG : VPseudoUSSegStore;
2881+
defm PseudoVSSSEG : VPseudoSSegStore;
28332882

28342883
//===----------------------------------------------------------------------===//
28352884
// 8. Vector AMO Operations

0 commit comments

Comments
 (0)