Skip to content

Commit e510fc7

Browse files
authored
[VP][RISCV] Introduce vp.lrint/llrint and RISC-V support. (#82627)
RISC-V implements vector lrint/llrint by vfcvt.x.f.v.
1 parent 4216a30 commit e510fc7

File tree

12 files changed

+903
-3
lines changed

12 files changed

+903
-3
lines changed

llvm/docs/LangRef.rst

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16021,6 +16021,8 @@ functions would, but without setting errno. If the rounded value is
1602116021
too large to be stored in the result type, the return value is a
1602216022
non-deterministic value (equivalent to `freeze poison`).
1602316023

16024+
.. _int_lrint:
16025+
1602416026
'``llvm.lrint.*``' Intrinsic
1602516027
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1602616028

@@ -16066,6 +16068,8 @@ would, but without setting errno. If the rounded value is too large to
1606616068
be stored in the result type, the return value is a non-deterministic
1606716069
value (equivalent to `freeze poison`).
1606816070

16071+
.. _int_llrint:
16072+
1606916073
'``llvm.llrint.*``' Intrinsic
1607016074
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1607116075

@@ -23382,6 +23386,100 @@ Examples:
2338223386
%t = call <4 x float> @llvm.trunc.v4f32(<4 x float> %a)
2338323387
%also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
2338423388

23389+
.. _int_vp_lrint:
23390+
23391+
'``llvm.vp.lrint.*``' Intrinsics
23392+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23393+
23394+
Syntax:
23395+
"""""""
23396+
This is an overloaded intrinsic.
23397+
23398+
::
23399+
23400+
declare <16 x i32> @llvm.vp.lrint.v16i32.v16f32(<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>)
23401+
declare <vscale x 4 x i32> @llvm.vp.lrint.nxv4i32.nxv4f32(<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23402+
declare <256 x i64> @llvm.vp.lrint.v256i64.v256f64(<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
23403+
23404+
Overview:
23405+
"""""""""
23406+
23407+
Predicated lrint of a vector of floating-point values.
23408+
23409+
23410+
Arguments:
23411+
""""""""""
23412+
23413+
The result is an integer vector and the first operand is a vector of :ref:`floating-point <t_floating>`
23414+
type with the same number of elements as the result vector type. The second
23415+
operand is the vector mask and has the same number of elements as the result
23416+
vector type. The third operand is the explicit vector length of the operation.
23417+
23418+
Semantics:
23419+
""""""""""
23420+
23421+
The '``llvm.vp.lrint``' intrinsic performs lrint (:ref:`lrint <int_lrint>`) of
23422+
the first vector operand on each enabled lane. The result on disabled lanes is a
23423+
:ref:`poison value <poisonvalues>`.
23424+
23425+
Examples:
23426+
"""""""""
23427+
23428+
.. code-block:: llvm
23429+
23430+
%r = call <4 x i32> @llvm.vp.lrint.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl)
23431+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23432+
23433+
%t = call <4 x i32> @llvm.lrint.v4f32(<4 x float> %a)
23434+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23435+
23436+
.. _int_vp_llrint:
23437+
23438+
'``llvm.vp.llrint.*``' Intrinsics
23439+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23440+
23441+
Syntax:
23442+
"""""""
23443+
This is an overloaded intrinsic.
23444+
23445+
::
23446+
23447+
declare <16 x i32> @llvm.vp.llrint.v16i32.v16f32(<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>)
23448+
declare <vscale x 4 x i32> @llvm.vp.llrint.nxv4i32.nxv4f32(<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23449+
declare <256 x i64> @llvm.vp.llrint.v256i64.v256f64(<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
23450+
23451+
Overview:
23452+
"""""""""
23453+
23454+
Predicated llrint of a vector of floating-point values.
23455+
23456+
23457+
Arguments:
23458+
""""""""""
23459+
The result is an integer vector and the first operand is a vector of :ref:`floating-point <t_floating>`
23460+
type with the same number of elements as the result vector type. The second
23461+
operand is the vector mask and has the same number of elements as the result
23462+
vector type. The third operand is the explicit vector length of the operation.
23463+
23464+
Semantics:
23465+
""""""""""
23466+
23467+
The '``llvm.vp.llrint``' intrinsic performs lrint (:ref:`llrint <int_llrint>`) of
23468+
the first vector operand on each enabled lane. The result on disabled lanes is a
23469+
:ref:`poison value <poisonvalues>`.
23470+
23471+
Examples:
23472+
"""""""""
23473+
23474+
.. code-block:: llvm
23475+
23476+
%r = call <4 x i32> @llvm.vp.llrint.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl)
23477+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23478+
23479+
%t = call <4 x i32> @llvm.llrint.v4f32(<4 x float> %a)
23480+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23481+
23482+
2338523483
.. _int_vp_bitreverse:
2338623484

2338723485
'``llvm.vp.bitreverse.*``' Intrinsics

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,14 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
20572057
[ LLVMMatchType<0>,
20582058
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
20592059
llvm_i32_ty]>;
2060+
def int_vp_lrint : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
2061+
[ llvm_anyvector_ty,
2062+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
2063+
llvm_i32_ty]>;
2064+
def int_vp_llrint : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
2065+
[ llvm_anyvector_ty,
2066+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
2067+
llvm_i32_ty]>;
20602068

20612069
// Casts
20622070
def int_vp_trunc : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],

llvm/include/llvm/IR/VPIntrinsics.def

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,18 @@ VP_PROPERTY_FUNCTIONAL_INTRINSIC(nearbyint)
461461
VP_PROPERTY_FUNCTIONAL_SDOPC(FNEARBYINT)
462462
END_REGISTER_VP(vp_nearbyint, VP_FNEARBYINT)
463463

464+
// llvm.vp.lrint(x,mask,vlen)
465+
BEGIN_REGISTER_VP(vp_lrint, 1, 2, VP_LRINT, 0)
466+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(lrint)
467+
VP_PROPERTY_FUNCTIONAL_SDOPC(LRINT)
468+
END_REGISTER_VP(vp_lrint, VP_LRINT)
469+
470+
// llvm.vp.llrint(x,mask,vlen)
471+
BEGIN_REGISTER_VP(vp_llrint, 1, 2, VP_LLRINT, 0)
472+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(llrint)
473+
VP_PROPERTY_FUNCTIONAL_SDOPC(LLRINT)
474+
END_REGISTER_VP(vp_llrint, VP_LLRINT)
475+
464476
///// } Floating-Point Arithmetic
465477

466478
///// Type Casts {

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,9 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
11021102
case ISD::FRINT:
11031103
case ISD::VP_FRINT:
11041104
case ISD::LRINT:
1105+
case ISD::VP_LRINT:
11051106
case ISD::LLRINT:
1107+
case ISD::VP_LLRINT:
11061108
case ISD::FROUND:
11071109
case ISD::VP_FROUND:
11081110
case ISD::FROUNDEVEN:
@@ -4263,6 +4265,8 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
42634265

42644266
case ISD::LRINT:
42654267
case ISD::LLRINT:
4268+
case ISD::VP_LRINT:
4269+
case ISD::VP_LLRINT:
42664270
Res = WidenVecRes_XRINT(N);
42674271
break;
42684272

@@ -4869,7 +4873,15 @@ SDValue DAGTypeLegalizer::WidenVecRes_XRINT(SDNode *N) {
48694873
if (WidenNumElts != SrcVT.getVectorElementCount())
48704874
return DAG.UnrollVectorOp(N, WidenNumElts.getKnownMinValue());
48714875

4872-
return DAG.getNode(N->getOpcode(), dl, WidenVT, Src);
4876+
if (N->getNumOperands() == 1)
4877+
return DAG.getNode(N->getOpcode(), dl, WidenVT, Src);
4878+
4879+
assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
4880+
assert(N->isVPOpcode() && "Expected VP opcode");
4881+
4882+
SDValue Mask =
4883+
GetWidenedMask(N->getOperand(1), WidenVT.getVectorElementCount());
4884+
return DAG.getNode(N->getOpcode(), dl, WidenVT, Src, Mask, N->getOperand(2));
48734885
}
48744886

48754887
SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(SDNode *N) {

llvm/lib/IR/IntrinsicInst.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,8 @@ Function *VPIntrinsic::getDeclarationForParams(Module *M, Intrinsic::ID VPID,
666666
case Intrinsic::vp_fpext:
667667
case Intrinsic::vp_ptrtoint:
668668
case Intrinsic::vp_inttoptr:
669+
case Intrinsic::vp_lrint:
670+
case Intrinsic::vp_llrint:
669671
VPFunc =
670672
Intrinsic::getDeclaration(M, VPID, {ReturnType, Params[0]->getType()});
671673
break;

llvm/lib/IR/Verifier.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6183,9 +6183,11 @@ void Verifier::visitVPIntrinsic(VPIntrinsic &VPI) {
61836183
break;
61846184
case Intrinsic::vp_fptoui:
61856185
case Intrinsic::vp_fptosi:
6186+
case Intrinsic::vp_lrint:
6187+
case Intrinsic::vp_llrint:
61866188
Check(
61876189
RetTy->isIntOrIntVectorTy() && ValTy->isFPOrFPVectorTy(),
6188-
"llvm.vp.fptoui or llvm.vp.fptosi intrinsic first argument element "
6190+
"llvm.vp.fptoui, llvm.vp.fptosi, llvm.vp.lrint or llvm.vp.llrint" "intrinsic first argument element "
61896191
"type must be floating-point and result element type must be integer",
61906192
*VPCast);
61916193
break;

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
706706
ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
707707
ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
708708
ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
709-
ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::EXPERIMENTAL_VP_REVERSE,
709+
ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
710+
ISD::VP_LLRINT, ISD::EXPERIMENTAL_VP_REVERSE,
710711
ISD::EXPERIMENTAL_VP_SPLICE};
711712

712713
static const unsigned IntegerVecReduceOps[] = {
@@ -5811,6 +5812,11 @@ static unsigned getRISCVVLOp(SDValue Op) {
58115812
case ISD::FMAXNUM:
58125813
case ISD::VP_FMAXNUM:
58135814
return RISCVISD::VFMAX_VL;
5815+
case ISD::LRINT:
5816+
case ISD::VP_LRINT:
5817+
case ISD::LLRINT:
5818+
case ISD::VP_LLRINT:
5819+
return RISCVISD::VFCVT_X_F_VL;
58145820
}
58155821
// clang-format on
58165822
#undef OP_CASE
@@ -6801,6 +6807,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
68016807
case ISD::VP_USUBSAT:
68026808
case ISD::VP_SADDSAT:
68036809
case ISD::VP_SSUBSAT:
6810+
case ISD::VP_LRINT:
6811+
case ISD::VP_LLRINT:
68046812
return lowerVPOp(Op, DAG);
68056813
case ISD::VP_AND:
68066814
case ISD::VP_OR:

0 commit comments

Comments
 (0)