[llvm] Add 3 way compare <=> integer intrinsics to Langref (PR #83227)

Miguel Raz Guzmán Macedo via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 10 08:46:30 PDT 2024


https://github.com/miguelraz updated https://github.com/llvm/llvm-project/pull/83227

>From 9d7134fbc570d8ce3218a69c56562aabda7a6be1 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Thu, 29 Feb 2024 20:01:20 -0600
Subject: [PATCH 1/8] add sthreecmp and uthreecmp intrinsics to LangRef

---
 llvm/docs/LangRef.rst | 92 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index f56d4ed28f2855..ceffd33cdc54f5 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -11976,6 +11976,98 @@ Example:
       <result> = icmp ule i16 -4, 5        ; yields: result=false
       <result> = icmp sge i16  4, 5        ; yields: result=false
 
+.. _i_sthreecmp:
+
+'``sthreecmp``' Instruction
+^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+      <result> = sthreecmp <op1>, <op2>  ; yields i2 or <N x i2>:result
+
+Overview:
+"""""""""
+
+The '``sthreecmp``' instruction returns an integer value or a vector of
+integer values based on comparison of its two integer, integer vector,
+pointer, or pointer vector operands.
+
+Arguments:
+""""""""""
+
+The '``sthreecmp``' instruction takes two signed integer operands.
+
+Semantics:
+""""""""""
+If the operands are equal, it returns 0. If ``op1`` is less than ``op2``,
+it returns -1, and if ``op1`` is greater than ``op2``, it returns 1.
+It is also known as the '``<=>``' spaceship operator.
+
+If the operands are :ref:`pointer <t_pointer>` typed, the pointer values
+are compared as if they were integers.
+
+If the operands are integer vectors, then they are compared element by
+element. The result is an ``i2`` vector with the same number of elements
+as the values being compared. Otherwise, the result is an ``i2``.
+
+Example:
+""""""""
+
+.. code-block:: text
+
+      <result> = sthreecmp 4, 5          ; yields: result=-1
+      <result> = sthreecmp 2, 2          ; yields: result=0
+      <result> = sthreecmp -2, -1        ; yields: result=1
+
+.. _i_uthreecmp:
+
+'``uthreecmp``' Instruction
+^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+      <result> = uthreecmp <op1>, <op2>  ; yields i2 or <N x i2>:result
+
+Overview:
+"""""""""
+
+The '``uthreecmp``' instruction returns an integer value or a vector of
+integer values based on comparison of its two integer, integer vector,
+pointer, or pointer vector operands.
+
+Arguments:
+""""""""""
+
+The '``uthreecmp``' instruction takes two signed integer operands.
+
+Semantics:
+""""""""""
+If the operands are equal, it returns 0. If ``op1`` is less than ``op2``,
+it returns -1, and if ``op1`` is greater than ``op2``, it returns 1.
+It is also known as the '``<=>``' spaceship operator.
+
+If the operands are :ref:`pointer <t_pointer>` typed, the pointer values
+are compared as if they were integers.
+
+If the operands are integer vectors, then they are compared element by
+element. The result is an ``i2`` vector with the same number of elements
+as the values being compared. Otherwise, the result is an ``i2``.
+
+Example:
+""""""""
+
+.. code-block:: text
+
+      <result> = uthreecmp 4, 5          ; yields: result=-1
+      <result> = uthreecmp 2, 2          ; yields: result=0
+      <result> = uthreecmp 9, 0          ; yields: result=1
+
 .. _i_fcmp:
 
 '``fcmp``' Instruction

>From 57ec729bd308d43adaedb7e095541991f4377111 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Thu, 29 Feb 2024 20:49:59 -0600
Subject: [PATCH 2/8] add tablegen for sthreecmp and usthreecmp intrinsics

---
 llvm/include/llvm/IR/Intrinsics.td | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 0f13d25eb30ebf..15df2e7b76577e 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -2136,7 +2136,14 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
                                llvm_metadata_ty,
                                LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                                llvm_i32_ty]>;
-
+  def int_vp_sthreecmp : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i8_ty> ],
+                             [LLVMMatchType<0>,
+                              LLVMMatchType<0>],
+                              [IntrSpeculatable]>;
+  def int_vp_uthreecmp : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i8_ty>],
+                             [LLVMMatchType<0>,
+                              LLVMMatchType<0>],
+                              [IntrSpeculatable]>;
   // Reductions
   def int_vp_reduce_fadd : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
                              [ LLVMVectorElementType<0>,

>From 34c0531ef62460e17c9e96e964f51d5017581680 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Thu, 29 Feb 2024 20:50:37 -0600
Subject: [PATCH 3/8] typo fix unsigned integer for uthreecmp

---
 llvm/docs/LangRef.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index ceffd33cdc54f5..5eae1015bffb18 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12044,7 +12044,7 @@ pointer, or pointer vector operands.
 Arguments:
 """"""""""
 
-The '``uthreecmp``' instruction takes two signed integer operands.
+The '``uthreecmp``' instruction takes two unsigned integer operands.
 
 Semantics:
 """"""""""

>From fc62757c2e096a7daa95c49371b067af5fe70f91 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Fri, 1 Mar 2024 23:24:56 -0600
Subject: [PATCH 4/8] add sthreecmp and uthreecmp intrinsics modeled after
 llvm.smax

---
 llvm/docs/LangRef.rst | 149 ++++++++++++++++--------------------------
 1 file changed, 57 insertions(+), 92 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5eae1015bffb18..62bcf825da5df2 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -11976,98 +11976,6 @@ Example:
       <result> = icmp ule i16 -4, 5        ; yields: result=false
       <result> = icmp sge i16  4, 5        ; yields: result=false
 
-.. _i_sthreecmp:
-
-'``sthreecmp``' Instruction
-^^^^^^^^^^^^^^^^^^^^^^
-
-Syntax:
-"""""""
-
-::
-
-      <result> = sthreecmp <op1>, <op2>  ; yields i2 or <N x i2>:result
-
-Overview:
-"""""""""
-
-The '``sthreecmp``' instruction returns an integer value or a vector of
-integer values based on comparison of its two integer, integer vector,
-pointer, or pointer vector operands.
-
-Arguments:
-""""""""""
-
-The '``sthreecmp``' instruction takes two signed integer operands.
-
-Semantics:
-""""""""""
-If the operands are equal, it returns 0. If ``op1`` is less than ``op2``,
-it returns -1, and if ``op1`` is greater than ``op2``, it returns 1.
-It is also known as the '``<=>``' spaceship operator.
-
-If the operands are :ref:`pointer <t_pointer>` typed, the pointer values
-are compared as if they were integers.
-
-If the operands are integer vectors, then they are compared element by
-element. The result is an ``i2`` vector with the same number of elements
-as the values being compared. Otherwise, the result is an ``i2``.
-
-Example:
-""""""""
-
-.. code-block:: text
-
-      <result> = sthreecmp 4, 5          ; yields: result=-1
-      <result> = sthreecmp 2, 2          ; yields: result=0
-      <result> = sthreecmp -2, -1        ; yields: result=1
-
-.. _i_uthreecmp:
-
-'``uthreecmp``' Instruction
-^^^^^^^^^^^^^^^^^^^^^^
-
-Syntax:
-"""""""
-
-::
-
-      <result> = uthreecmp <op1>, <op2>  ; yields i2 or <N x i2>:result
-
-Overview:
-"""""""""
-
-The '``uthreecmp``' instruction returns an integer value or a vector of
-integer values based on comparison of its two integer, integer vector,
-pointer, or pointer vector operands.
-
-Arguments:
-""""""""""
-
-The '``uthreecmp``' instruction takes two unsigned integer operands.
-
-Semantics:
-""""""""""
-If the operands are equal, it returns 0. If ``op1`` is less than ``op2``,
-it returns -1, and if ``op1`` is greater than ``op2``, it returns 1.
-It is also known as the '``<=>``' spaceship operator.
-
-If the operands are :ref:`pointer <t_pointer>` typed, the pointer values
-are compared as if they were integers.
-
-If the operands are integer vectors, then they are compared element by
-element. The result is an ``i2`` vector with the same number of elements
-as the values being compared. Otherwise, the result is an ``i2``.
-
-Example:
-""""""""
-
-.. code-block:: text
-
-      <result> = uthreecmp 4, 5          ; yields: result=-1
-      <result> = uthreecmp 2, 2          ; yields: result=0
-      <result> = uthreecmp 9, 0          ; yields: result=1
-
 .. _i_fcmp:
 
 '``fcmp``' Instruction
@@ -14623,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_sthreecmp:
+
+'``llvm.sthreecmp.*``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+This is an overloaded intrinsic. You can use ``@llvm.sthreecmp`` on any
+integer bit width or any vector of integer elements.
+
+::
+
+      declare i32 @llvm.sthreecmp.i32(i32 %a, i32 %b)
+      declare <4 x i32> @llvm.sthreecmp.v4i32(<4 x i32> %a, <4 x i32> %b)
+
+Overview:
+"""""""""
+
+Return ``-1`` if ``%a`` is less than ``%b``, ``0`` if they are equal, and 
+``1`` if ``%a`` is greater than ``%b``. Vector intrinsics operate on a per-element basis. 
+
+Arguments:
+""""""""""
+
+The arguments (``%a`` and ``%b``) may be of any signed 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 uphold the ``-1`` return value.
+
+.. _int_uthreecmp:
+
+'``llvm.uthreecmp.*``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+This is an overloaded intrinsic. You can use ``@llvm.sthreecmp`` on any
+integer bit width or any vector of integer elements.
+
+::
+
+      declare i2 @llvm.uthreecmp.i32(i32 %a, i32 %b)
+      declare <4 x i32> @llvm.uthreecmp.v4i32(<4 x i32> %a, <4 x i32> %b)
+
+Overview:
+"""""""""
+
+Return ``-1`` if ``%a`` is less than ``%b``, ``0`` if they are equal, and 
+``1`` if ``%a`` is greater than ``%b``. Vector intrinsics operate on a per-element basis. 
+
+Arguments:
+""""""""""
+
+The arguments (``%a`` and ``%b``) may be of any unsigned 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 uphold the ``-1`` return value.
 
 .. _int_memcpy:
 

>From a8ee07885770f8a23c898944dff6e26f189ea341 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Fri, 1 Mar 2024 23:26:53 -0600
Subject: [PATCH 5/8] add int_sthreecmp and int_uthreecmp based on int_smin

---
 llvm/include/llvm/IR/Intrinsics.td | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 15df2e7b76577e..856f5545be0165 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1526,6 +1526,12 @@ def int_umax : DefaultAttrsIntrinsic<
 def int_umin : DefaultAttrsIntrinsic<
     [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
     [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_sthreecmp : DefaultAttrsIntrinsic<
+    [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+    [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+def int_uthreecmp : DefaultAttrsIntrinsic<
+    [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+    [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
 
 //===------------------------- Memory Use Markers -------------------------===//
 //
@@ -2136,14 +2142,7 @@ let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
                                llvm_metadata_ty,
                                LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                                llvm_i32_ty]>;
-  def int_vp_sthreecmp : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i8_ty> ],
-                             [LLVMMatchType<0>,
-                              LLVMMatchType<0>],
-                              [IntrSpeculatable]>;
-  def int_vp_uthreecmp : DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i8_ty>],
-                             [LLVMMatchType<0>,
-                              LLVMMatchType<0>],
-                              [IntrSpeculatable]>;
+
   // Reductions
   def int_vp_reduce_fadd : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
                              [ LLVMVectorElementType<0>,

>From ef5bd69d570699af2b376ba4c7b0b6fe171cea6a Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Sat, 2 Mar 2024 07:20:30 -0600
Subject: [PATCH 6/8] add [u]sthreecmp to ValueTrackingTest.cpp

---
 llvm/unittests/Analysis/ValueTrackingTest.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 9e0abe7a16df98..05f5e16a498e89 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -891,6 +891,8 @@ TEST(ValueTracking, propagatesPoison) {
       {true, "call i32 @llvm.smin.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.umax.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.umin.i32(i32 %x, i32 %y)", 0},
+      {true, "call i32 @llvm.sthreecmp.i32(i32 %x, i32 %y)", 0},
+      {true, "call i32 @llvm.uthreecmp.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.bitreverse.i32(i32 %x)", 0},
       {true, "call i32 @llvm.bswap.i32(i32 %x)", 0},
       {false, "call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt)", 0},

>From 2ba679d624e1929ca3c0368f364816ea9275ba31 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Sat, 9 Mar 2024 20:47:07 -0600
Subject: [PATCH 7/8] call three way cmp intrinsic [u]scmp in LangRef

---
 llvm/docs/LangRef.rst | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 62bcf825da5df2..ff600c0dfe35b3 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -14531,21 +14531,21 @@ 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_sthreecmp:
+.. _int_scmp:
 
-'``llvm.sthreecmp.*``' Intrinsic
+'``llvm.scmp.*``' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Syntax:
 """""""
 
-This is an overloaded intrinsic. You can use ``@llvm.sthreecmp`` on any
+This is an overloaded intrinsic. You can use ``@llvm.scmp`` on any
 integer bit width or any vector of integer elements.
 
 ::
 
-      declare i32 @llvm.sthreecmp.i32(i32 %a, i32 %b)
-      declare <4 x i32> @llvm.sthreecmp.v4i32(<4 x i32> %a, <4 x i32> %b)
+      declare i32 @llvm.scmp.i32(i32 %a, i32 %b)
+      declare <4 x i32> @llvm.scmp.v4i32(<4 x i32> %a, <4 x i32> %b)
 
 Overview:
 """""""""
@@ -14560,21 +14560,21 @@ The arguments (``%a`` and ``%b``) may be of any signed integer type or a vector
 integer element type. The argument types must match each other, and the return
 type must be at least as wide as ``i2``, to uphold the ``-1`` return value.
 
-.. _int_uthreecmp:
+.. _int_ucmp:
 
-'``llvm.uthreecmp.*``' Intrinsic
+'``llvm.ucmp.*``' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Syntax:
 """""""
 
-This is an overloaded intrinsic. You can use ``@llvm.sthreecmp`` on any
+This is an overloaded intrinsic. You can use ``@llvm.ucmp`` on any
 integer bit width or any vector of integer elements.
 
 ::
 
-      declare i2 @llvm.uthreecmp.i32(i32 %a, i32 %b)
-      declare <4 x i32> @llvm.uthreecmp.v4i32(<4 x i32> %a, <4 x i32> %b)
+      declare i2 @llvm.ucmp.i32(i32 %a, i32 %b)
+      declare <4 x i32> @llvm.ucmp.v4i32(<4 x i32> %a, <4 x i32> %b)
 
 Overview:
 """""""""

>From c605cdf4f48921b8b8a3b3611e5cb62f3e2c3e01 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Sun, 10 Mar 2024 09:46:05 -0600
Subject: [PATCH 8/8] only add minimum stuff to LangRef and Intrinsics.td for
 s/ucmp

---
 llvm/include/llvm/IR/Intrinsics.td            | 4 ++--
 llvm/unittests/Analysis/ValueTrackingTest.cpp | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 856f5545be0165..9f437375e64bd4 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1526,10 +1526,10 @@ def int_umax : DefaultAttrsIntrinsic<
 def int_umin : DefaultAttrsIntrinsic<
     [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
     [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_sthreecmp : DefaultAttrsIntrinsic<
+def int_scmp : DefaultAttrsIntrinsic<
     [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
     [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
-def int_uthreecmp : DefaultAttrsIntrinsic<
+def int_ucmp : DefaultAttrsIntrinsic<
     [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
     [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
 
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 05f5e16a498e89..9e0abe7a16df98 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -891,8 +891,6 @@ TEST(ValueTracking, propagatesPoison) {
       {true, "call i32 @llvm.smin.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.umax.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.umin.i32(i32 %x, i32 %y)", 0},
-      {true, "call i32 @llvm.sthreecmp.i32(i32 %x, i32 %y)", 0},
-      {true, "call i32 @llvm.uthreecmp.i32(i32 %x, i32 %y)", 0},
       {true, "call i32 @llvm.bitreverse.i32(i32 %x)", 0},
       {true, "call i32 @llvm.bswap.i32(i32 %x)", 0},
       {false, "call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt)", 0},



More information about the llvm-commits mailing list