Skip to content

Commit 73244e8

Browse files
committed
[VP] Add vp.icmp comparison intrinsic and docs
This patch mostly follows up on D121292 which introduced the vp.fcmp intrinsic. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D122729
1 parent a0e5d9e commit 73244e8

File tree

8 files changed

+118
-4
lines changed

8 files changed

+118
-4
lines changed

llvm/docs/LangRef.rst

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11126,6 +11126,8 @@ The '``icmp``' instruction takes three operands. The first operand is
1112611126
the condition code indicating the kind of comparison to perform. It is
1112711127
not a value, just a keyword. The possible condition codes are:
1112811128

11129+
.. _icmp_md_cc:
11130+
1112911131
#. ``eq``: equal
1113011132
#. ``ne``: not equal
1113111133
#. ``ugt``: unsigned greater than
@@ -11148,6 +11150,8 @@ The '``icmp``' compares ``op1`` and ``op2`` according to the condition
1114811150
code given as ``cond``. The comparison performed always yields either an
1114911151
:ref:`i1 <t_integer>` or vector of ``i1`` result, as follows:
1115011152

11153+
.. _icmp_md_cc_sem:
11154+
1115111155
#. ``eq``: yields ``true`` if the operands are equal, ``false``
1115211156
otherwise. No sign interpretation is necessary or performed.
1115311157
#. ``ne``: yields ``true`` if the operands are unequal, ``false``
@@ -20341,6 +20345,64 @@ Examples:
2034120345
%also.r = select <4 x i1> %mask, <4 x i1> %t, <4 x i1> undef
2034220346

2034320347

20348+
.. _int_vp_icmp:
20349+
20350+
'``llvm.vp.icmp.*``' Intrinsics
20351+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20352+
20353+
Syntax:
20354+
"""""""
20355+
This is an overloaded intrinsic.
20356+
20357+
::
20358+
20359+
declare <32 x i1> @llvm.vp.icmp.v32i32(<32 x i32> <left_op>, <32 x i32> <right_op>, metadata <condition code>, <32 x i1> <mask>, i32 <vector_length>)
20360+
declare <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> <left_op>, <vscale x 2 x i32> <right_op>, metadata <condition code>, <vscale x 2 x i1> <mask>, i32 <vector_length>)
20361+
declare <128 x i1> @llvm.vp.icmp.v128i8(<128 x i8> <left_op>, <128 x i8> <right_op>, metadata <condition code>, <128 x i1> <mask>, i32 <vector_length>)
20362+
20363+
Overview:
20364+
"""""""""
20365+
20366+
The '``llvm.vp.icmp``' intrinsic returns a vector of boolean values based on
20367+
the comparison of its operands. The operation has a mask and an explicit vector
20368+
length parameter.
20369+
20370+
20371+
Arguments:
20372+
""""""""""
20373+
20374+
The '``llvm.vp.icmp``' intrinsic takes the two values to compare as its first
20375+
and second operands. These two values must be vectors of :ref:`integer
20376+
<t_integer>` types.
20377+
The return type is the result of the comparison. The return type must be a
20378+
vector of :ref:`i1 <t_integer>` type. The fourth operand is the vector mask.
20379+
The return type, the values to compare, and the vector mask have the same
20380+
number of elements. The third operand is the condition code indicating the kind
20381+
of comparison to perform. It must be a metadata string with :ref:`one of the
20382+
supported integer condition code values <icmp_md_cc>`. The fifth operand is the
20383+
explicit vector length of the operation.
20384+
20385+
Semantics:
20386+
""""""""""
20387+
20388+
The '``llvm.vp.icmp``' compares its first two operands according to the
20389+
condition code given as the third operand. The operands are compared element by
20390+
element on each enabled lane, where the the semantics of the comparison are
20391+
defined :ref:`according to the condition code <icmp_md_cc_sem>`. Masked-off
20392+
lanes are undefined.
20393+
20394+
Examples:
20395+
"""""""""
20396+
20397+
.. code-block:: llvm
20398+
20399+
%r = call <4 x i1> @llvm.vp.icmp.v4i32(<4 x i32> %a, <4 x i32> %b, metadata !"ne", <4 x i1> %mask, i32 %evl)
20400+
;; For all lanes below %evl, %r is lane-wise equivalent to %also.r
20401+
20402+
%t = icmp ne <4 x i32> %a, %b
20403+
%also.r = select <4 x i1> %mask, <4 x i1> %t, <4 x i1> undef
20404+
20405+
2034420406
.. _int_mload_mstore:
2034520407

2034620408
Masked Vector Load and Store Intrinsics

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,13 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
15751575
llvm_metadata_ty,
15761576
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
15771577
llvm_i32_ty]>;
1578+
1579+
def int_vp_icmp : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ],
1580+
[ llvm_anyvector_ty,
1581+
LLVMMatchType<0>,
1582+
llvm_metadata_ty,
1583+
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
1584+
llvm_i32_ty]>;
15781585
}
15791586

15801587
// Reductions

llvm/include/llvm/IR/VPIntrinsics.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ VP_PROPERTY_CMP(2, true)
267267
VP_PROPERTY_CONSTRAINEDFP(0, 1, experimental_constrained_fcmp)
268268
END_REGISTER_VP(vp_fcmp, VP_FCMP)
269269

270+
// llvm.vp.icmp(x,y,cc,mask,vlen)
271+
BEGIN_REGISTER_VP(vp_icmp, 3, 4, VP_ICMP, -1)
272+
VP_PROPERTY_FUNCTIONAL_OPC(ICmp)
273+
VP_PROPERTY_CMP(2, false)
274+
END_REGISTER_VP(vp_icmp, VP_ICMP)
275+
270276
///// } Comparisons
271277

272278
///// Memory Operations {

llvm/lib/IR/IntrinsicInst.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,24 @@ bool VPCmpIntrinsic::isVPCmp(Intrinsic::ID ID) {
576576
return false;
577577
}
578578

579+
static ICmpInst::Predicate getIntPredicateFromMD(const Value *Op) {
580+
Metadata *MD = cast<MetadataAsValue>(Op)->getMetadata();
581+
if (!MD || !isa<MDString>(MD))
582+
return ICmpInst::BAD_ICMP_PREDICATE;
583+
return StringSwitch<ICmpInst::Predicate>(cast<MDString>(MD)->getString())
584+
.Case("eq", ICmpInst::ICMP_EQ)
585+
.Case("ne", ICmpInst::ICMP_NE)
586+
.Case("ugt", ICmpInst::ICMP_UGT)
587+
.Case("uge", ICmpInst::ICMP_UGE)
588+
.Case("ult", ICmpInst::ICMP_ULT)
589+
.Case("ule", ICmpInst::ICMP_ULE)
590+
.Case("sgt", ICmpInst::ICMP_SGT)
591+
.Case("sge", ICmpInst::ICMP_SGE)
592+
.Case("slt", ICmpInst::ICMP_SLT)
593+
.Case("sle", ICmpInst::ICMP_SLE)
594+
.Default(ICmpInst::BAD_ICMP_PREDICATE);
595+
}
596+
579597
CmpInst::Predicate VPCmpIntrinsic::getPredicate() const {
580598
bool IsFP = true;
581599
Optional<unsigned> CCArgIdx;
@@ -590,9 +608,9 @@ CmpInst::Predicate VPCmpIntrinsic::getPredicate() const {
590608
#define END_REGISTER_VP_INTRINSIC(VPID) break;
591609
#include "llvm/IR/VPIntrinsics.def"
592610
}
593-
assert(CCArgIdx.hasValue() && IsFP &&
594-
"Unexpected vector-predicated comparison");
595-
return getFPPredicateFromMD(getArgOperand(*CCArgIdx));
611+
assert(CCArgIdx.hasValue() && "Unexpected vector-predicated comparison");
612+
return IsFP ? getFPPredicateFromMD(getArgOperand(*CCArgIdx))
613+
: getIntPredicateFromMD(getArgOperand(*CCArgIdx));
596614
}
597615

598616
unsigned VPReductionIntrinsic::getVectorParamPos() const {

llvm/lib/IR/Verifier.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5606,6 +5606,11 @@ void Verifier::visitVPIntrinsic(VPIntrinsic &VPI) {
56065606
Assert(CmpInst::isFPPredicate(Pred),
56075607
"invalid predicate for VP FP comparison intrinsic", &VPI);
56085608
}
5609+
if (VPI.getIntrinsicID() == Intrinsic::vp_icmp) {
5610+
auto Pred = cast<VPCmpIntrinsic>(&VPI)->getPredicate();
5611+
Assert(CmpInst::isIntPredicate(Pred),
5612+
"invalid predicate for VP integer comparison intrinsic", &VPI);
5613+
}
56095614
}
56105615

56115616
void Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {

llvm/test/Verifier/invalid-vp-intrinsics.ll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare <4 x i32> @llvm.vp.fptosi.v4i32.v8f32(<8 x float>, <4 x i1>, i32)
44
declare <4 x i1> @llvm.vp.fcmp.v4f32(<4 x float>, <4 x float>, metadata, <4 x i1>, i32)
5+
declare <4 x i1> @llvm.vp.icmp.v4i32(<4 x i32>, <4 x i32>, metadata, <4 x i1>, i32)
56

67
; CHECK: VP cast intrinsic first argument and result vector lengths must be equal
78
; CHECK-NEXT: %r0 = call <4 x i32>
@@ -21,3 +22,14 @@ define void @test_vp_fcmp(<4 x float> %a, <4 x float> %b, <4 x i1> %m, i32 %n) {
2122
%r1 = call <4 x i1> @llvm.vp.fcmp.v4f32(<4 x float> %a, <4 x float> %b, metadata !"eq", <4 x i1> %m, i32 %n)
2223
ret void
2324
}
25+
26+
; CHECK: invalid predicate for VP integer comparison intrinsic
27+
; CHECK-NEXT: %r0 = call <4 x i1> @llvm.vp.icmp.v4i32
28+
; CHECK: invalid predicate for VP integer comparison intrinsic
29+
; CHECK-NEXT: %r1 = call <4 x i1> @llvm.vp.icmp.v4i32
30+
31+
define void @test_vp_icmp(<4 x i32> %a, <4 x i32> %b, <4 x i1> %m, i32 %n) {
32+
%r0 = call <4 x i1> @llvm.vp.icmp.v4i32(<4 x i32> %a, <4 x i32> %b, metadata !"bad", <4 x i1> %m, i32 %n)
33+
%r1 = call <4 x i1> @llvm.vp.icmp.v4i32(<4 x i32> %a, <4 x i32> %b, metadata !"oeq", <4 x i1> %m, i32 %n)
34+
ret void
35+
}

llvm/test/Verifier/vp-intrinsics.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ define void @test_vp_int_fp_conversions(<8 x i32> %i0, <8 x float> %f0, <8 x i1>
6363
ret void
6464
}
6565

66-
define void @test_vp_comparisons(<8 x float> %f0, <8 x float> %f1, <8 x i1> %mask, i32 %evl) {
66+
define void @test_vp_comparisons(<8 x float> %f0, <8 x float> %f1, <8 x i32> %i0, <8 x i32> %i1, <8 x i1> %mask, i32 %evl) {
6767
%r0 = call <8 x i1> @llvm.vp.fcmp.v8f32(<8 x float> %f0, <8 x float> %f1, metadata !"oeq", <8 x i1> %mask, i32 %evl)
68+
%r1 = call <8 x i1> @llvm.vp.icmp.v8i32(<8 x i32> %i0, <8 x i32> %i1, metadata !"eq", <8 x i1> %mask, i32 %evl)
6869
ret void
6970
}
7071

@@ -108,6 +109,7 @@ declare <8 x float> @llvm.vp.sitofp.v8f32.v8i32(<8 x i32>, <8 x i1>, i32)
108109
declare <8 x i32> @llvm.vp.fptosi.v8i32.v8f32(<8 x float>, <8 x i1>, i32)
109110
; compares
110111
declare <8 x i1> @llvm.vp.fcmp.v8f32(<8 x float>, <8 x float>, metadata, <8 x i1>, i32)
112+
declare <8 x i1> @llvm.vp.icmp.v8i32(<8 x i32>, <8 x i32>, metadata, <8 x i1>, i32)
111113
; shuffles
112114
declare <8 x i32> @llvm.experimental.vp.splice.v8i32(<8 x i32>, <8 x i32>, i32, <8 x i1>, i32, i32)
113115
declare <vscale x 8 x i32> @llvm.experimental.vp.splice.nxv8i32(<vscale x 8 x i32>, <vscale x 8 x i32>, i32, <vscale x 8 x i1>, i32, i32)

llvm/unittests/IR/VPIntrinsicTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ class VPIntrinsicTest : public testing::Test {
9999

100100
Str << " declare <8 x i1> @llvm.vp.fcmp.v8f32"
101101
<< "(<8 x float>, <8 x float>, metadata, <8 x i1>, i32) ";
102+
Str << " declare <8 x i1> @llvm.vp.icmp.v8i16"
103+
<< "(<8 x i16>, <8 x i16>, metadata, <8 x i1>, i32) ";
102104

103105
return parseAssemblyString(Str.str(), Err, C);
104106
}

0 commit comments

Comments
 (0)