[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