[llvm] 0a2b1ba - [GlobalISel] Add G_ISNAN

Jessica Paquette via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 18 10:42:25 PDT 2021


Author: Jessica Paquette
Date: 2021-08-18T10:42:05-07:00
New Revision: 0a2b1ba33ae6dcaedb81417f7c4cc714f72a5968

URL: https://github.com/llvm/llvm-project/commit/0a2b1ba33ae6dcaedb81417f7c4cc714f72a5968
DIFF: https://github.com/llvm/llvm-project/commit/0a2b1ba33ae6dcaedb81417f7c4cc714f72a5968.diff

LOG: [GlobalISel] Add G_ISNAN

Add a generic opcode equivalent to the `llvm.isnan` intrinsic +
MachineVerifier support for it.

We need an opcode here because we may want target-specific lowering later on.

Differential Revision: https://reviews.llvm.org/D108222

Added: 
    llvm/test/MachineVerifier/test_g_isnan.mir

Modified: 
    llvm/docs/GlobalISel/GenericOpcode.rst
    llvm/include/llvm/Support/TargetOpcodes.def
    llvm/include/llvm/Target/GenericOpcodes.td
    llvm/lib/CodeGen/MachineVerifier.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index 5f1ac067d9f90..4abe069b10e7a 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -629,6 +629,17 @@ G_VECREDUCE_FMAX, G_VECREDUCE_FMIN
 
 FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
 
+G_ISNAN
+^^^^^^^
+
+GlobalISel-equivalent of the '``llvm.isnan``' intrinsic.
+
+Returns a 1-bit scalar or vector of 1-bit scalar values. The result's contents
+represent whether or not the source value is NaN.
+
+.. code-block:: none
+
+  %is_nan:_(s1) = G_ISNAN %check_me_for_nan
 
 Integer/bitwise reductions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index fbe0d1a55bfca..6ba679b3d2a77 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -769,10 +769,12 @@ HANDLE_TARGET_OPCODE(G_VECREDUCE_UMIN)
 HANDLE_TARGET_OPCODE(G_SBFX)
 HANDLE_TARGET_OPCODE(G_UBFX)
 
+HANDLE_TARGET_OPCODE(G_ISNAN)
+
 /// Marker for the end of the generic opcode.
 /// This is used to check if an opcode is in the range of the
 /// generic opcodes.
-HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_UBFX)
+HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_ISNAN)
 
 /// BUILTIN_OP_END - This must be the last enum value in this list.
 /// The target-specific post-isel opcode values start here.

diff  --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index e3e1d5fc3c655..4d0b91e3b6be2 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -225,6 +225,13 @@ def G_FREEZE : GenericInstruction {
   let hasSideEffects = false;
 }
 
+// Generic opcode equivalent to the llvm.isnan intrinsic.
+def G_ISNAN: GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src);
+  let hasSideEffects = false;
+}
+
 //------------------------------------------------------------------------------
 // Binary ops.
 //------------------------------------------------------------------------------

diff  --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 2b980ecb0236a..0c495043c2cd7 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -947,6 +947,25 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
   // Verify properties of various specific instruction types
   unsigned Opc = MI->getOpcode();
   switch (Opc) {
+  case TargetOpcode::G_ISNAN: {
+    LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+    LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
+    LLT S1 = DstTy.isVector() ? DstTy.getElementType() : DstTy;
+    if (S1 != LLT::scalar(1)) {
+      report("Destination must be a 1-bit scalar or vector of 1-bit elements",
+             MI);
+      break;
+    }
+
+    // Disallow pointers.
+    LLT SrcOrElt = SrcTy.isVector() ? SrcTy.getElementType() : SrcTy;
+    if (!SrcOrElt.isScalar()) {
+      report("Source must be a scalar or vector of scalars", MI);
+      break;
+    }
+    verifyVectorElementMatch(DstTy, SrcTy, MI);
+    break;
+  }
   case TargetOpcode::G_ASSERT_SEXT:
   case TargetOpcode::G_ASSERT_ZEXT: {
     std::string OpcName =

diff  --git a/llvm/test/MachineVerifier/test_g_isnan.mir b/llvm/test/MachineVerifier/test_g_isnan.mir
new file mode 100644
index 0000000000000..94bc93b671905
--- /dev/null
+++ b/llvm/test/MachineVerifier/test_g_isnan.mir
@@ -0,0 +1,33 @@
+# REQUIRES: aarch64-registered-target
+# RUN: not --crash llc -verify-machineinstrs -mtriple aarch64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+
+name:            test
+body: |
+  bb.0:
+   liveins: $x0
+   %s64:_(s64) = COPY $x0
+   %v4s16:_(<4 x s16>) = COPY $x0
+
+   ; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
+   ; CHECK: instruction: %isnan1:_(s64) = G_ISNAN %s64:_(s64)
+   %isnan1:_(s64) = G_ISNAN %s64
+
+   ; CHECK: *** Bad machine code: operand types must be all-vector or all-scalar ***
+   ; CHECK: instruction: %isnan2:_(<2 x s1>) = G_ISNAN %s64:_(s64)
+   %isnan2:_(<2 x s1>) = G_ISNAN %s64
+
+   ; CHECK: *** Bad machine code: operand types must preserve number of vector elements ***
+   ; CHECK: instruction: %isnan3:_(<2 x s1>) = G_ISNAN %v4s16:_(<4 x s16>)
+   %isnan3:_(<2 x s1>) = G_ISNAN %v4s16
+
+   ; CHECK: *** Bad machine code: operand types must be all-vector or all-scalar ***
+   ; CHECK: instruction: %isnan4:_(s1) = G_ISNAN %v4s16:_(<4 x s16>)
+   %isnan4:_(s1) = G_ISNAN %v4s16
+
+   ; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
+   ; CHECK: instruction: %isnan5:_(p0) = G_ISNAN %s64:_(s64)
+   %isnan5:_(p0) = G_ISNAN %s64
+
+   ; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
+   ; CHECK: instruction: %isnan6:_(<4 x p0>) = G_ISNAN %v4s16:_(<4 x s16>)
+   %isnan6:_(<4 x p0>) = G_ISNAN %v4s16


        


More information about the llvm-commits mailing list