Skip to content

Commit b787353

Browse files
yetingkYeting Kuo
authored andcommitted
[VP][RISCV] Introduce experimental.vp.popcount and RISC-V support.
This is similar to vp.ctpop. But this is counts the whole source mask and vp.ctpop counts each lane of its source.
1 parent d49e9d8 commit b787353

File tree

11 files changed

+672
-0
lines changed

11 files changed

+672
-0
lines changed

llvm/docs/LangRef.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21761,6 +21761,40 @@ This intrinsic reverses the order of the first ``evl`` elements in a vector.
2176121761
The lanes in the result vector disabled by ``mask`` are ``poison``. The
2176221762
elements past ``evl`` are poison.
2176321763

21764+
21765+
.. _int_experimental_vp_popcount:
21766+
21767+
21768+
'``llvm.experimental.vp.popcount``' Intrinsic
21769+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21770+
21771+
Syntax:
21772+
"""""""
21773+
This is an overloaded intrinsic.
21774+
21775+
::
21776+
21777+
declare i32 @llvm.experimental.vp.popcount.v2i1(<2 x i1> %vec, <2 x i1> %mask, i32 %evl)
21778+
declare i32 @llvm.experimental.vp.popcount.nxv2i1(<vscale x 4 x i1> %vec, <vscale x 4 x i1> %mask, i32 %evl)
21779+
21780+
Overview:
21781+
"""""""""
21782+
21783+
Predicated population count of a vector mask.
21784+
21785+
Arguments:
21786+
""""""""""
21787+
21788+
The first and second argument are vector masks and have same number of elements.
21789+
The third argument is the explicit vector length of the operation.
21790+
21791+
Semantics:
21792+
""""""""""
21793+
21794+
This intrinsic population counts first ``evl`` elements in a vector.
21795+
The lanes in the result vector disabled by ``mask`` are ``poison``. The
21796+
elements past ``evl`` are poison.
21797+
2176421798
.. _int_vp_load:
2176521799

2176621800
'``llvm.vp.load``' Intrinsic

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,10 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
21622162
llvm_anyvector_ty,
21632163
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
21642164
llvm_i32_ty]>;
2165+
def int_experimental_vp_popcount: DefaultAttrsIntrinsic<[llvm_i32_ty],
2166+
[ llvm_anyvector_ty,
2167+
LLVMMatchType<0>,
2168+
llvm_i32_ty]>;
21652169
}
21662170

21672171
let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn, ImmArg<ArgIndex<1>>] in {

llvm/include/llvm/IR/VPIntrinsics.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,12 @@ END_REGISTER_VP(experimental_vp_reverse, EXPERIMENTAL_VP_REVERSE)
710710

711711
///// } Shuffles
712712

713+
// llvm.experimental.vp.popcount(x,mask,vlen)
714+
BEGIN_REGISTER_VP(experimental_vp_popcount, 1, 2,
715+
EXPERIMENTAL_VP_POPCOUNT, 0)
716+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(experimental_vp_popcount)
717+
END_REGISTER_VP(experimental_vp_popcount, EXPERIMENTAL_VP_POPCOUNT)
718+
713719
#undef BEGIN_REGISTER_VP
714720
#undef BEGIN_REGISTER_VP_INTRINSIC
715721
#undef BEGIN_REGISTER_VP_SDNODE

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
305305
case ISD::LLRINT:
306306
Res = PromoteIntRes_XRINT(N);
307307
break;
308+
309+
case ISD::EXPERIMENTAL_VP_POPCOUNT:
310+
Res = PromoteIntRes_VP_POPCOUNT(N);
311+
break;
308312
}
309313

310314
// If the result is null then the sub-method took care of registering it.
@@ -5882,6 +5886,12 @@ SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
58825886
return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0));
58835887
}
58845888

5889+
SDValue DAGTypeLegalizer::PromoteIntRes_VP_POPCOUNT(SDNode *N) {
5890+
SDLoc dl(N);
5891+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5892+
return DAG.getNode(N->getOpcode(), dl, NVT, N->ops());
5893+
}
5894+
58855895
SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_SUBVECTOR(SDNode *N) {
58865896
SDLoc dl(N);
58875897
// The result type is equal to the first input operand's type, so the

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
365365
SDValue PromoteIntRes_FunnelShift(SDNode *N);
366366
SDValue PromoteIntRes_VPFunnelShift(SDNode *N);
367367
SDValue PromoteIntRes_IS_FPCLASS(SDNode *N);
368+
SDValue PromoteIntRes_VP_POPCOUNT(SDNode *N);
368369

369370
// Integer Operand Promotion.
370371
bool PromoteIntegerOperand(SDNode *N, unsigned OpNo);
@@ -916,6 +917,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
916917
SDValue SplitVecOp_FP_ROUND(SDNode *N);
917918
SDValue SplitVecOp_FPOpDifferentTypes(SDNode *N);
918919
SDValue SplitVecOp_FP_TO_XINT_SAT(SDNode *N);
920+
SDValue SplitVecOp_VP_POPCOUNT(SDNode *N, unsigned OpNo);
919921

920922
//===--------------------------------------------------------------------===//
921923
// Vector Widening Support: LegalizeVectorTypes.cpp
@@ -1023,6 +1025,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
10231025
SDValue WidenVecOp_VECREDUCE_SEQ(SDNode *N);
10241026
SDValue WidenVecOp_VP_REDUCE(SDNode *N);
10251027
SDValue WidenVecOp_ExpOp(SDNode *N);
1028+
SDValue WidenVecOp_VP_POPCOUNT(SDNode *N);
10261029

10271030
/// Helper function to generate a set of operations to perform
10281031
/// a vector operation for a wider type.

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3085,6 +3085,9 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
30853085
case ISD::VP_REDUCE_FMIN:
30863086
Res = SplitVecOp_VP_REDUCE(N, OpNo);
30873087
break;
3088+
case ISD::EXPERIMENTAL_VP_POPCOUNT:
3089+
Res = SplitVecOp_VP_POPCOUNT(N, OpNo);
3090+
break;
30883091
}
30893092

30903093
// If the result is null, the sub-method took care of registering results etc.
@@ -4031,6 +4034,31 @@ SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) {
40314034
return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
40324035
}
40334036

4037+
SDValue DAGTypeLegalizer::SplitVecOp_VP_POPCOUNT(SDNode *N, unsigned OpNo) {
4038+
assert(N->isVPOpcode() && "Expected VP opcode");
4039+
assert(OpNo == 0 && "Can only split first operand");
4040+
4041+
unsigned Opc = N->getOpcode();
4042+
EVT ResVT = N->getValueType(0);
4043+
SDValue Lo, Hi;
4044+
SDLoc dl(N);
4045+
4046+
SDValue VecOp = N->getOperand(OpNo);
4047+
EVT VecVT = VecOp.getValueType();
4048+
assert(VecVT.isVector() && "Can only split reduce vector operand");
4049+
GetSplitVector(VecOp, Lo, Hi);
4050+
4051+
SDValue MaskLo, MaskHi;
4052+
std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
4053+
4054+
SDValue EVLLo, EVLHi;
4055+
std::tie(EVLLo, EVLHi) = DAG.SplitEVL(N->getOperand(2), VecVT, dl);
4056+
4057+
SDValue ResLo = DAG.getNode(Opc, dl, ResVT, {Lo, MaskLo, EVLLo});
4058+
SDValue ResHi = DAG.getNode(Opc, dl, ResVT, {Hi, MaskHi, EVLHi});
4059+
return DAG.getNode(ISD::ADD, dl, ResVT, ResLo, ResHi);
4060+
}
4061+
40344062
//===----------------------------------------------------------------------===//
40354063
// Result Vector Widening
40364064
//===----------------------------------------------------------------------===//
@@ -6120,6 +6148,9 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
61206148
case ISD::VP_REDUCE_FMIN:
61216149
Res = WidenVecOp_VP_REDUCE(N);
61226150
break;
6151+
case ISD::EXPERIMENTAL_VP_POPCOUNT:
6152+
Res = WidenVecOp_VP_POPCOUNT(N);
6153+
break;
61236154
}
61246155

61256156
// If Res is null, the sub-method took care of registering the result.
@@ -6883,6 +6914,13 @@ SDValue DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode *N) {
68836914
DAG.getVectorIdxConstant(0, DL));
68846915
}
68856916

6917+
SDValue DAGTypeLegalizer::WidenVecOp_VP_POPCOUNT(SDNode *N) {
6918+
EVT ResVT = N->getValueType(0);
6919+
SDValue Op = GetWidenedVector(N->getOperand(0));
6920+
SDValue Mask = GetWidenedVector(N->getOperand(1));
6921+
return DAG.getNode(N->getOpcode(), SDLoc(N), ResVT, Op, Mask,
6922+
N->getOperand(2));
6923+
}
68866924
//===----------------------------------------------------------------------===//
68876925
// Vector Widening Utilities
68886926
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
766766
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
767767

768768
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
769+
setOperationAction(ISD::EXPERIMENTAL_VP_POPCOUNT, VT, Custom);
769770

770771
setOperationPromotedToType(
771772
ISD::VECTOR_SPLICE, VT,
@@ -1140,6 +1141,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
11401141
VT, Custom);
11411142

11421143
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1144+
setOperationAction(ISD::EXPERIMENTAL_VP_POPCOUNT, VT, Custom);
11431145
continue;
11441146
}
11451147

@@ -6607,6 +6609,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
66076609
return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget);
66086610
case ISD::EXPERIMENTAL_VP_REVERSE:
66096611
return lowerVPReverseExperimental(Op, DAG);
6612+
case ISD::EXPERIMENTAL_VP_POPCOUNT:
6613+
return lowerVPPopcountExperimental(Op, DAG);
66106614
}
66116615
}
66126616

@@ -19744,6 +19748,34 @@ bool RISCVTargetLowering::lowerInterleaveIntrinsicToStore(IntrinsicInst *II,
1974419748
return true;
1974519749
}
1974619750

19751+
SDValue
19752+
RISCVTargetLowering::lowerVPPopcountExperimental(SDValue N,
19753+
SelectionDAG &DAG) const {
19754+
SDValue Op = N.getOperand(0);
19755+
SDValue Mask = N.getOperand(1);
19756+
MVT VT = Op.getSimpleValueType();
19757+
SDLoc DL(N);
19758+
MVT XLenVT = Subtarget.getXLenVT();
19759+
19760+
bool IsUnMasked = ISD::isConstantSplatVectorAllOnes(Mask.getNode());
19761+
19762+
MVT ContainerVT = VT;
19763+
if (VT.isFixedLengthVector()) {
19764+
ContainerVT = getContainerForFixedLengthVector(VT);
19765+
Op = convertToScalableVector(ContainerVT, Op, DAG, Subtarget);
19766+
Mask = convertToScalableVector(ContainerVT, Mask, DAG, Subtarget);
19767+
}
19768+
19769+
if (IsUnMasked)
19770+
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Subtarget.getXLenVT(),
19771+
DAG.getConstant(Intrinsic::riscv_vcpop, DL, XLenVT), Op,
19772+
N->getOperand(2));
19773+
19774+
return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Subtarget.getXLenVT(),
19775+
DAG.getConstant(Intrinsic::riscv_vcpop_mask, DL, XLenVT),
19776+
Op, Mask, N->getOperand(2));
19777+
}
19778+
1974719779
MachineInstr *
1974819780
RISCVTargetLowering::EmitKCFICheck(MachineBasicBlock &MBB,
1974919781
MachineBasicBlock::instr_iterator &MBBI,

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,7 @@ class RISCVTargetLowering : public TargetLowering {
905905
SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const;
906906
SDValue lowerVPSetCCMaskOp(SDValue Op, SelectionDAG &DAG) const;
907907
SDValue lowerVPReverseExperimental(SDValue Op, SelectionDAG &DAG) const;
908+
SDValue lowerVPPopcountExperimental(SDValue Op, SelectionDAG &DAG) const;
908909
SDValue lowerVPFPIntConvOp(SDValue Op, SelectionDAG &DAG) const;
909910
SDValue lowerVPStridedLoad(SDValue Op, SelectionDAG &DAG) const;
910911
SDValue lowerVPStridedStore(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)