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
^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
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.
//------------------------------------------------------------------------------
// 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 =
--- /dev/null
+# 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