forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e8c8407aca
commit
0a2b1ba33a
|
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue