Index: llvm/include/llvm/Support/TargetOpcodes.def =================================================================== --- llvm/include/llvm/Support/TargetOpcodes.def +++ llvm/include/llvm/Support/TargetOpcodes.def @@ -769,10 +769,12 @@ 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. Index: llvm/include/llvm/Target/GenericOpcodes.td =================================================================== --- llvm/include/llvm/Target/GenericOpcodes.td +++ llvm/include/llvm/Target/GenericOpcodes.td @@ -225,6 +225,13 @@ 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. //------------------------------------------------------------------------------ Index: llvm/lib/CodeGen/MachineVerifier.cpp =================================================================== --- llvm/lib/CodeGen/MachineVerifier.cpp +++ llvm/lib/CodeGen/MachineVerifier.cpp @@ -947,6 +947,25 @@ // 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; + } + // Not sure if pointers are valid; disallow them since it doesn't make too + // much sense to check if a pointer is NaN. + 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 = Index: llvm/test/MachineVerifier/test_g_isnan.mir =================================================================== --- /dev/null +++ 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