Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LangRef][IR] Add 3-way compare intrinsics llvm.scmp/llvm.ucmp #83227

Merged
merged 43 commits into from Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9d7134f
add sthreecmp and uthreecmp intrinsics to LangRef
miguelraz Mar 1, 2024
57ec729
add tablegen for sthreecmp and usthreecmp intrinsics
miguelraz Mar 1, 2024
34c0531
typo fix unsigned integer for uthreecmp
miguelraz Mar 1, 2024
fc62757
add sthreecmp and uthreecmp intrinsics modeled after llvm.smax
miguelraz Mar 2, 2024
a8ee078
add int_sthreecmp and int_uthreecmp based on int_smin
miguelraz Mar 2, 2024
ef5bd69
add [u]sthreecmp to ValueTrackingTest.cpp
miguelraz Mar 2, 2024
2ba679d
call three way cmp intrinsic [u]scmp in LangRef
miguelraz Mar 10, 2024
c605cdf
only add minimum stuff to LangRef and Intrinsics.td for s/ucmp
miguelraz Mar 10, 2024
294822f
add u/scmp result type overload over a fixed type in Intrinsics.td
miguelraz Mar 10, 2024
7651b2e
add VisitIntrinsicCall cases for Intrinsic::ucmp/scmp
miguelraz Mar 11, 2024
a4fe31d
Update llvm/lib/IR/Verifier.cpp
miguelraz Mar 11, 2024
cdf4abf
add proper type overloads for llvm.ucmp.i2.i32 and llvm.scmp.i2.i32 i…
miguelraz Mar 11, 2024
e50721f
Merge branch 'spaceship-intrinsic' of github.com:miguelraz/llvm-proje…
miguelraz Mar 11, 2024
ae6910f
move isVector check above else to catch dest as scalar but src as vector
miguelraz Mar 11, 2024
d68cf0d
omit checks done by Intrinsics.td on u/scmp operating on int-likes
miguelraz Mar 11, 2024
7b3cfee
Update llvm/docs/LangRef.rst
miguelraz Mar 11, 2024
3a0ee32
Update llvm/docs/LangRef.rst
miguelraz Mar 11, 2024
343daf4
Update llvm/docs/LangRef.rst
miguelraz Mar 11, 2024
4cd70d6
Update llvm/lib/IR/Verifier.cpp
miguelraz Mar 11, 2024
c8b5e02
Update llvm/lib/IR/Verifier.cpp
miguelraz Mar 11, 2024
a86c4a0
delete stray newline
miguelraz Mar 12, 2024
f887988
cast to vectors (not arrays!) in scmp Check
miguelraz Mar 12, 2024
d6d0a27
add Filecheck tests for Verifier.cpp u/scmp intrinsics
miguelraz Mar 12, 2024
4f91e51
delete last unneded CHECK
miguelraz Mar 12, 2024
38e94c5
make return value length more simple on scmp and ucmp
miguelraz Mar 12, 2024
915ead2
make return value length more simple on scmp and ucmp
miguelraz Mar 12, 2024
266894c
Update llvm/docs/LangRef.rst
miguelraz Mar 12, 2024
0d988d5
Update llvm/docs/LangRef.rst
miguelraz Mar 12, 2024
045d385
Update llvm/docs/LangRef.rst
miguelraz Mar 14, 2024
45ccd00
Update llvm/docs/LangRef.rst
miguelraz Mar 14, 2024
2666817
Update llvm/lib/IR/Verifier.cpp
miguelraz Mar 14, 2024
fbfdea3
fix CodingStandards for var casenames and 4 spaces not tabs in FileCh…
miguelraz Mar 14, 2024
04c220b
Update llvm/test/Verifier/intrinsic-cmp.ll
miguelraz Mar 14, 2024
0f5d306
align to 2 spaces
miguelraz Mar 14, 2024
d5e7146
fixup unit tests for scmp intrinsic
miguelraz Mar 14, 2024
94c853d
appease the formatting gods
miguelraz Mar 14, 2024
f09c3e4
appease the formatting gods, again
miguelraz Mar 14, 2024
a85ae26
appease the formatting gods, again, again
miguelraz Mar 14, 2024
9aaab2c
appease the formatting gods, again, again, again
miguelraz Mar 14, 2024
8005996
appease the FileCheck gods \o/
miguelraz Mar 15, 2024
4caa63e
phrasing nits for error messages
miguelraz Mar 15, 2024
b0918f6
update FileCheck unit tests with most recent errors
miguelraz Mar 15, 2024
74c9bb3
freakin' formatting gods
miguelraz Mar 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 57 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -14531,6 +14531,63 @@ The arguments (``%a`` and ``%b``) may be of any integer type or a vector with
integer element type. The argument types must match each other, and the return
type must match the argument type.

.. _int_scmp:

'``llvm.scmp.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

This is an overloaded intrinsic. You can use ``@llvm.scmp`` on any
integer bit width or any vector of integer elements.

::

declare i2 @llvm.scmp.i2.i32(i32 %a, i32 %b)
declare <4 x i32> @llvm.scmp.v4i32.v4i32(<4 x i32> %a, <4 x i32> %b)

Overview:
"""""""""

Return ``-1`` if ``%a`` is signed less than ``%b``, ``0`` if they are equal, and
``1`` if ``%a`` is signed greater than ``%b``. Vector intrinsics operate on a per-element basis.

Arguments:
""""""""""

The arguments (``%a`` and ``%b``) may be of any integer type or a vector with
integer element type. The argument types must match each other, and the return
type must be at least as wide as ``i2``, to hold the three possible return values.

.. _int_ucmp:

'``llvm.ucmp.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

This is an overloaded intrinsic. You can use ``@llvm.ucmp`` on any
integer bit width or any vector of integer elements.

::

declare i2 @llvm.ucmp.i2.i32(i32 %a, i32 %b)
declare <4 x i32> @llvm.ucmp.v4i32.v4i32(<4 x i32> %a, <4 x i32> %b)

Overview:
"""""""""

Return ``-1`` if ``%a`` is unsigned less than ``%b``, ``0`` if they are equal, and
``1`` if ``%a`` is unsigned greater than ``%b``. Vector intrinsics operate on a per-element basis.

Arguments:
""""""""""

The arguments (``%a`` and ``%b``) may be of any integer type or a vector with
integer element type. The argument types must match each other, and the return
type must be at least as wide as ``i2``, to hold the three possible return values.

.. _int_memcpy:

Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/IR/Intrinsics.td
Expand Up @@ -1526,6 +1526,12 @@ def int_umax : DefaultAttrsIntrinsic<
def int_umin : DefaultAttrsIntrinsic<
[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_scmp : DefaultAttrsIntrinsic<
[llvm_anyint_ty], [llvm_anyint_ty, LLVMMatchType<1>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_ucmp : DefaultAttrsIntrinsic<
[llvm_anyint_ty], [llvm_anyint_ty, LLVMMatchType<1>],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;

//===------------------------- Memory Use Markers -------------------------===//
//
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/IR/Verifier.cpp
Expand Up @@ -5235,6 +5235,29 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
}
break;
}
case Intrinsic::ucmp:
case Intrinsic::scmp: {
Type *SrcTy = Call.getOperand(0)->getType();
Type *DestTy = Call.getType();

Check(DestTy->getScalarSizeInBits() >= 2,
"result type must be at least 2 bits wide", Call);

bool IsDestTypeVector = DestTy->isVectorTy();
Check(SrcTy->isVectorTy() == IsDestTypeVector,
"ucmp/scmp argument and result types must both be either vector or "
"scalar types",
Call);
if (IsDestTypeVector) {
auto SrcVecLen = cast<VectorType>(SrcTy)->getElementCount();
auto DestVecLen = cast<VectorType>(DestTy)->getElementCount();
Check(SrcVecLen == DestVecLen,
"return type and arguments must have the same number of "
"elements",
miguelraz marked this conversation as resolved.
Show resolved Hide resolved
Call);
}
break;
}
case Intrinsic::coro_id: {
auto *InfoArg = Call.getArgOperand(3)->stripPointerCasts();
if (isa<ConstantPointerNull>(InfoArg))
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/Verifier/intrinsic-cmp.ll
@@ -0,0 +1,22 @@
; RUN: not opt -S -passes=verify 2>&1 < %s | FileCheck %s

define void @matching_vector_lens(<4 x i32> %arg1, <4 x i32> %arg2) {
; CHECK: return type and arguments must have the same number of elements
%res = call <8 x i32> @llvm.scmp.v8i32.v4i32(<4 x i32> %arg1, <4 x i32> %arg2)
ret void
}

define void @result_len_is_at_least_2bits_wide(i32 %arg1, i32 %arg2) {
; CHECK: result type must be at least 2 bits wide
%res2 = call i1 @llvm.scmp.i1.i32(i32 %arg1, i32 %arg2)
ret void
}

define void @both_args_are_vecs_or_neither(<4 x i32> %arg1, i32 %arg2) {
; CHECK: ucmp/scmp argument and result types must both be either vector or scalar types
%res3 = call i2 @llvm.scmp.i2.v4i32(<4 x i32> %arg1, <4 x i32> %arg1)
; CHECK: ucmp/scmp argument and result types must both be either vector or scalar types
%res4 = call <4 x i32> @llvm.scmp.v4i32.i32(i32 %arg2, i32 %arg2)
ret void
}