Skip to content

Commit 850dde0

Browse files
authored
[RISCV][VP] Introduce vp saturating addition/subtraction and RISC-V support. (#82370)
This patch also pick the MatchContext framework from DAGCombiner to an indiviual header file to make the framework be used from other files in llvm/lib/CodeGen/SelectionDAG/.
1 parent afd4690 commit 850dde0

18 files changed

+15521
-157
lines changed

llvm/docs/LangRef.rst

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16749,6 +16749,7 @@ an operation is greater than the maximum value, the result is set (or
1674916749
"clamped") to this maximum. If it is below the minimum, it is clamped to this
1675016750
minimum.
1675116751

16752+
.. _int_sadd_sat:
1675216753

1675316754
'``llvm.sadd.sat.*``' Intrinsics
1675416755
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16798,6 +16799,8 @@ Examples
1679816799
%res = call i4 @llvm.sadd.sat.i4(i4 -4, i4 -5) ; %res = -8
1679916800

1680016801

16802+
.. _int_uadd_sat:
16803+
1680116804
'``llvm.uadd.sat.*``' Intrinsics
1680216805
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1680316806

@@ -16845,6 +16848,8 @@ Examples
1684516848
%res = call i4 @llvm.uadd.sat.i4(i4 8, i4 8) ; %res = 15
1684616849

1684716850

16851+
.. _int_ssub_sat:
16852+
1684816853
'``llvm.ssub.sat.*``' Intrinsics
1684916854
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1685016855

@@ -16893,6 +16898,8 @@ Examples
1689316898
%res = call i4 @llvm.ssub.sat.i4(i4 4, i4 -5) ; %res = 7
1689416899

1689516900

16901+
.. _int_usub_sat:
16902+
1689616903
'``llvm.usub.sat.*``' Intrinsics
1689716904
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1689816905

@@ -23610,6 +23617,202 @@ Examples:
2361023617
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
2361123618

2361223619

23620+
.. _int_vp_sadd_sat:
23621+
23622+
'``llvm.vp.sadd.sat.*``' Intrinsics
23623+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23624+
23625+
Syntax:
23626+
"""""""
23627+
This is an overloaded intrinsic.
23628+
23629+
::
23630+
23631+
declare <16 x i32> @llvm.vp.sadd.sat.v16i32 (<16 x i32> <left_op> <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>)
23632+
declare <vscale x 4 x i32> @llvm.vp.sadd.sat.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23633+
declare <256 x i64> @llvm.vp.sadd.sat.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
23634+
23635+
Overview:
23636+
"""""""""
23637+
23638+
Predicated signed saturating addition of two vectors of integers.
23639+
23640+
23641+
Arguments:
23642+
""""""""""
23643+
23644+
The first two operands and the result have the same vector of integer type. The
23645+
third operand is the vector mask and has the same number of elements as the
23646+
result vector type. The fourth operand is the explicit vector length of the
23647+
operation.
23648+
23649+
Semantics:
23650+
""""""""""
23651+
23652+
The '``llvm.vp.sadd.sat``' intrinsic performs sadd.sat (:ref:`sadd.sat <int_sadd_sat>`)
23653+
of the first and second vector operands on each enabled lane. The result on
23654+
disabled lanes is a :ref:`poison value <poisonvalues>`.
23655+
23656+
23657+
Examples:
23658+
"""""""""
23659+
23660+
.. code-block:: llvm
23661+
23662+
%r = call <4 x i32> @llvm.vp.sadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl)
23663+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23664+
23665+
%t = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
23666+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23667+
23668+
23669+
.. _int_vp_uadd_sat:
23670+
23671+
'``llvm.vp.uadd.sat.*``' Intrinsics
23672+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23673+
23674+
Syntax:
23675+
"""""""
23676+
This is an overloaded intrinsic.
23677+
23678+
::
23679+
23680+
declare <16 x i32> @llvm.vp.uadd.sat.v16i32 (<16 x i32> <left_op> <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>)
23681+
declare <vscale x 4 x i32> @llvm.vp.uadd.sat.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23682+
declare <256 x i64> @llvm.vp.uadd.sat.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
23683+
23684+
Overview:
23685+
"""""""""
23686+
23687+
Predicated unsigned saturating addition of two vectors of integers.
23688+
23689+
23690+
Arguments:
23691+
""""""""""
23692+
23693+
The first two operands and the result have the same vector of integer type. The
23694+
third operand is the vector mask and has the same number of elements as the
23695+
result vector type. The fourth operand is the explicit vector length of the
23696+
operation.
23697+
23698+
Semantics:
23699+
""""""""""
23700+
23701+
The '``llvm.vp.uadd.sat``' intrinsic performs uadd.sat (:ref:`uadd.sat <int_uadd_sat>`)
23702+
of the first and second vector operands on each enabled lane. The result on
23703+
disabled lanes is a :ref:`poison value <poisonvalues>`.
23704+
23705+
23706+
Examples:
23707+
"""""""""
23708+
23709+
.. code-block:: llvm
23710+
23711+
%r = call <4 x i32> @llvm.vp.uadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl)
23712+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23713+
23714+
%t = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
23715+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23716+
23717+
23718+
.. _int_vp_ssub_sat:
23719+
23720+
'``llvm.vp.ssub.sat.*``' Intrinsics
23721+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23722+
23723+
Syntax:
23724+
"""""""
23725+
This is an overloaded intrinsic.
23726+
23727+
::
23728+
23729+
declare <16 x i32> @llvm.vp.ssub.sat.v16i32 (<16 x i32> <left_op> <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>)
23730+
declare <vscale x 4 x i32> @llvm.vp.ssub.sat.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23731+
declare <256 x i64> @llvm.vp.ssub.sat.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
23732+
23733+
Overview:
23734+
"""""""""
23735+
23736+
Predicated signed saturating subtraction of two vectors of integers.
23737+
23738+
23739+
Arguments:
23740+
""""""""""
23741+
23742+
The first two operands and the result have the same vector of integer type. The
23743+
third operand is the vector mask and has the same number of elements as the
23744+
result vector type. The fourth operand is the explicit vector length of the
23745+
operation.
23746+
23747+
Semantics:
23748+
""""""""""
23749+
23750+
The '``llvm.vp.ssub.sat``' intrinsic performs ssub.sat (:ref:`ssub.sat <int_ssub_sat>`)
23751+
of the first and second vector operands on each enabled lane. The result on
23752+
disabled lanes is a :ref:`poison value <poisonvalues>`.
23753+
23754+
23755+
Examples:
23756+
"""""""""
23757+
23758+
.. code-block:: llvm
23759+
23760+
%r = call <4 x i32> @llvm.vp.ssub.sat.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl)
23761+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23762+
23763+
%t = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
23764+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23765+
23766+
23767+
.. _int_vp_usub_sat:
23768+
23769+
'``llvm.vp.usub.sat.*``' Intrinsics
23770+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23771+
23772+
Syntax:
23773+
"""""""
23774+
This is an overloaded intrinsic.
23775+
23776+
::
23777+
23778+
declare <16 x i32> @llvm.vp.usub.sat.v16i32 (<16 x i32> <left_op> <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>)
23779+
declare <vscale x 4 x i32> @llvm.vp.usub.sat.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
23780+
declare <256 x i64> @llvm.vp.usub.sat.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
23781+
23782+
Overview:
23783+
"""""""""
23784+
23785+
Predicated unsigned saturating subtraction of two vectors of integers.
23786+
23787+
23788+
Arguments:
23789+
""""""""""
23790+
23791+
The first two operands and the result have the same vector of integer type. The
23792+
third operand is the vector mask and has the same number of elements as the
23793+
result vector type. The fourth operand is the explicit vector length of the
23794+
operation.
23795+
23796+
Semantics:
23797+
""""""""""
23798+
23799+
The '``llvm.vp.usub.sat``' intrinsic performs usub.sat (:ref:`usub.sat <int_usub_sat>`)
23800+
of the first and second vector operands on each enabled lane. The result on
23801+
disabled lanes is a :ref:`poison value <poisonvalues>`.
23802+
23803+
23804+
Examples:
23805+
"""""""""
23806+
23807+
.. code-block:: llvm
23808+
23809+
%r = call <4 x i32> @llvm.vp.usub.sat.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl)
23810+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
23811+
23812+
%t = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
23813+
%also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
23814+
23815+
2361323816
.. _int_vp_fshl:
2361423817

2361523818
'``llvm.vp.fshl.*``' Intrinsics

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,26 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
19331933
LLVMMatchType<0>,
19341934
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
19351935
llvm_i32_ty]>;
1936+
def int_vp_sadd_sat : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
1937+
[ LLVMMatchType<0>,
1938+
LLVMMatchType<0>,
1939+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
1940+
llvm_i32_ty]>;
1941+
def int_vp_uadd_sat : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
1942+
[ LLVMMatchType<0>,
1943+
LLVMMatchType<0>,
1944+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
1945+
llvm_i32_ty]>;
1946+
def int_vp_ssub_sat : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
1947+
[ LLVMMatchType<0>,
1948+
LLVMMatchType<0>,
1949+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
1950+
llvm_i32_ty]>;
1951+
def int_vp_usub_sat : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],
1952+
[ LLVMMatchType<0>,
1953+
LLVMMatchType<0>,
1954+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
1955+
llvm_i32_ty]>;
19361956

19371957
// Floating-point arithmetic
19381958
def int_vp_fadd : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ],

llvm/include/llvm/IR/VPIntrinsics.def

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,30 @@ BEGIN_REGISTER_VP(vp_fshr, 3, 4, VP_FSHR, -1)
293293
VP_PROPERTY_FUNCTIONAL_INTRINSIC(fshr)
294294
VP_PROPERTY_FUNCTIONAL_SDOPC(FSHR)
295295
END_REGISTER_VP(vp_fshr, VP_FSHR)
296+
297+
// llvm.vp.sadd.sat(x,y,mask,vlen)
298+
BEGIN_REGISTER_VP(vp_sadd_sat, 2, 3, VP_SADDSAT, -1)
299+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(sadd_sat)
300+
VP_PROPERTY_FUNCTIONAL_SDOPC(SADDSAT)
301+
END_REGISTER_VP(vp_sadd_sat, VP_SADDSAT)
302+
303+
// llvm.vp.uadd.sat(x,y,mask,vlen)
304+
BEGIN_REGISTER_VP(vp_uadd_sat, 2, 3, VP_UADDSAT, -1)
305+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(uadd_sat)
306+
VP_PROPERTY_FUNCTIONAL_SDOPC(UADDSAT)
307+
END_REGISTER_VP(vp_uadd_sat, VP_UADDSAT)
308+
309+
// llvm.vp.ssub.sat(x,y,mask,vlen)
310+
BEGIN_REGISTER_VP(vp_ssub_sat, 2, 3, VP_SSUBSAT, -1)
311+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(ssub_sat)
312+
VP_PROPERTY_FUNCTIONAL_SDOPC(SSUBSAT)
313+
END_REGISTER_VP(vp_ssub_sat, VP_SSUBSAT)
314+
315+
// llvm.vp.usub.sat(x,y,mask,vlen)
316+
BEGIN_REGISTER_VP(vp_usub_sat, 2, 3, VP_USUBSAT, -1)
317+
VP_PROPERTY_FUNCTIONAL_INTRINSIC(usub_sat)
318+
VP_PROPERTY_FUNCTIONAL_SDOPC(USUBSAT)
319+
END_REGISTER_VP(vp_usub_sat, VP_USUBSAT)
296320
///// } Integer Arithmetic
297321

298322
///// Floating-Point Arithmetic {

0 commit comments

Comments
 (0)