Skip to content

Commit 033e24a

Browse files
author
Yeting Kuo
committed
[VP][RISCV] Introduce vp.lrint/llrint and RISC-V support.
RISC-V implements vector lrint/llrint by vfcvt.x.f.v.
1 parent 6abf5e5 commit 033e24a

File tree

10 files changed

+898
-2
lines changed

10 files changed

+898
-2
lines changed

llvm/docs/LangRef.rst

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

15993+
.. _int_lrint:
15994+
1599315995
'``llvm.lrint.*``' Intrinsic
1599415996
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1599515997

@@ -16035,6 +16037,8 @@ would, but without setting errno. If the rounded value is too large to
1603516037
be stored in the result type, the return value is a non-deterministic
1603616038
value (equivalent to `freeze poison`).
1603716039

16040+
.. _int_llrint:
16041+
1603816042
'``llvm.llrint.*``' Intrinsic
1603916043
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1604016044

@@ -23344,6 +23348,100 @@ Examples:
2334423348
%t = call <4 x float> @llvm.trunc.v4f32(<4 x float> %a)
2334523349
%also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
2334623350

23351+
.. _int_vp_lrint:
23352+
23353+
'``llvm.vp.lrint.*``' Intrinsics
23354+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23355+
23356+
Syntax:
23357+
"""""""
23358+
This is an overloaded intrinsic.
23359+
23360+
::
23361+
23362+
declare <16 x i32> @llvm.vp.lrint.v16i32.v16f32(<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>)
23363+
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>)
23364+
declare <256 x i64> @llvm.vp.lrint.v256i64.v256f64(<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
23365+
23366+
Overview:
23367+
"""""""""
23368+
23369+
Predicated lrint of a vector of floating-point values.
23370+
23371+
23372+
Arguments:
23373+
""""""""""
23374+
23375+
The result is an integer vector and the first operand is a vector of :ref:`floating-point <t_floating>`
23376+
type with the same number of elements as the result vector type. The second
23377+
operand is the vector mask and has the same number of elements as the result
23378+
vector type. The third operand is the explicit vector length of the operation.
23379+
23380+
Semantics:
23381+
""""""""""
23382+
23383+
The '``llvm.vp.lrint``' intrinsic performs lrint (:ref:`lrint <int_lrint>`) of
23384+
the first vector operand on each enabled lane. The result on disabled lanes is a
23385+
:ref:`poison value <poisonvalues>`.
23386+
23387+
Examples:
23388+
"""""""""
23389+
23390+
.. code-block:: llvm
23391+
23392+
%r = call <4 x i32> @llvm.vp.lrint.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl)
23393+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23394+
23395+
%t = call <4 x i32> @llvm.lrint.v4f32(<4 x float> %a)
23396+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23397+
23398+
.. _int_vp_llrint:
23399+
23400+
'``llvm.vp.llrint.*``' Intrinsics
23401+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23402+
23403+
Syntax:
23404+
"""""""
23405+
This is an overloaded intrinsic.
23406+
23407+
::
23408+
23409+
declare <16 x i32> @llvm.vp.llrint.v16i32.v16f32(<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>)
23410+
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>)
23411+
declare <256 x i64> @llvm.vp.llrint.v256i64.v256f64(<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
23412+
23413+
Overview:
23414+
"""""""""
23415+
23416+
Predicated llrint of a vector of floating-point values.
23417+
23418+
23419+
Arguments:
23420+
""""""""""
23421+
The result is an integer vector and the first operand is a vector of :ref:`floating-point <t_floating>`
23422+
type with the same number of elements as the result vector type. The second
23423+
operand is the vector mask and has the same number of elements as the result
23424+
vector type. The third operand is the explicit vector length of the operation.
23425+
23426+
Semantics:
23427+
""""""""""
23428+
23429+
The '``llvm.vp.llrint``' intrinsic performs lrint (:ref:`llrint <int_llrint>`) of
23430+
the first vector operand on each enabled lane. The result on disabled lanes is a
23431+
:ref:`poison value <poisonvalues>`.
23432+
23433+
Examples:
23434+
"""""""""
23435+
23436+
.. code-block:: llvm
23437+
23438+
%r = call <4 x i32> @llvm.vp.llrint.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl)
23439+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23440+
23441+
%t = call <4 x i32> @llvm.llrint.v4f32(<4 x float> %a)
23442+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23443+
23444+
2334723445
.. _int_vp_bitreverse:
2334823446

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

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,6 +2036,14 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
20362036
[ LLVMMatchType<0>,
20372037
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
20382038
llvm_i32_ty]>;
2039+
def int_vp_lrint : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
2040+
[ llvm_anyvector_ty,
2041+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
2042+
llvm_i32_ty]>;
2043+
def int_vp_llrint : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
2044+
[ llvm_anyvector_ty,
2045+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
2046+
llvm_i32_ty]>;
20392047

20402048
// Casts
20412049
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
@@ -437,6 +437,18 @@ VP_PROPERTY_FUNCTIONAL_INTRINSIC(nearbyint)
437437
VP_PROPERTY_FUNCTIONAL_SDOPC(FNEARBYINT)
438438
END_REGISTER_VP(vp_nearbyint, VP_FNEARBYINT)
439439

440+
// llvm.vp.lrint(x,mask,vlen)
441+
BEGIN_REGISTER_VP(vp_lrint, 1, 2, VP_LRINT, 0)
442+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(lrint)
443+
VP_PROPERTY_FUNCTIONAL_SDOPC(LRINT)
444+
END_REGISTER_VP(vp_lrint, VP_LRINT)
445+
446+
// llvm.vp.llrint(x,mask,vlen)
447+
BEGIN_REGISTER_VP(vp_llrint, 1, 2, VP_LLRINT, 0)
448+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(llrint)
449+
VP_PROPERTY_FUNCTIONAL_SDOPC(LLRINT)
450+
END_REGISTER_VP(vp_llrint, VP_LLRINT)
451+
440452
///// } Floating-Point Arithmetic
441453

442454
///// 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/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
699699
ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
700700
ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
701701
ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
702-
ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::EXPERIMENTAL_VP_REVERSE,
702+
ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
703+
ISD::VP_LLRINT, ISD::EXPERIMENTAL_VP_REVERSE,
703704
ISD::EXPERIMENTAL_VP_SPLICE};
704705

705706
static const unsigned IntegerVecReduceOps[] = {
@@ -5807,6 +5808,11 @@ static unsigned getRISCVVLOp(SDValue Op) {
58075808
case ISD::FMAXNUM:
58085809
case ISD::VP_FMAXNUM:
58095810
return RISCVISD::VFMAX_VL;
5811+
case ISD::LRINT:
5812+
case ISD::VP_LRINT:
5813+
case ISD::LLRINT:
5814+
case ISD::VP_LLRINT:
5815+
return RISCVISD::VFCVT_X_F_VL;
58105816
}
58115817
// clang-format on
58125818
#undef OP_CASE
@@ -6793,6 +6799,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
67936799
case ISD::VP_UDIV:
67946800
case ISD::VP_SREM:
67956801
case ISD::VP_UREM:
6802+
case ISD::VP_LRINT:
6803+
case ISD::VP_LLRINT:
67966804
return lowerVPOp(Op, DAG);
67976805
case ISD::VP_AND:
67986806
case ISD::VP_OR:

0 commit comments

Comments
 (0)