Skip to content

Commit 0a2b1ba

Browse files
author
Jessica Paquette
committed
[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
1 parent e8c8407 commit 0a2b1ba

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

+11
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,17 @@ G_VECREDUCE_FMAX, G_VECREDUCE_FMIN
629629

630630
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
631631

632+
G_ISNAN
633+
^^^^^^^
634+
635+
GlobalISel-equivalent of the '``llvm.isnan``' intrinsic.
636+
637+
Returns a 1-bit scalar or vector of 1-bit scalar values. The result's contents
638+
represent whether or not the source value is NaN.
639+
640+
.. code-block:: none
641+
642+
%is_nan:_(s1) = G_ISNAN %check_me_for_nan
632643
633644
Integer/bitwise reductions
634645
^^^^^^^^^^^^^^^^^^^^^^^^^^

llvm/include/llvm/Support/TargetOpcodes.def

+3-1
Original file line numberDiff line numberDiff line change
@@ -769,10 +769,12 @@ HANDLE_TARGET_OPCODE(G_VECREDUCE_UMIN)
769769
HANDLE_TARGET_OPCODE(G_SBFX)
770770
HANDLE_TARGET_OPCODE(G_UBFX)
771771

772+
HANDLE_TARGET_OPCODE(G_ISNAN)
773+
772774
/// Marker for the end of the generic opcode.
773775
/// This is used to check if an opcode is in the range of the
774776
/// generic opcodes.
775-
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_UBFX)
777+
HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_ISNAN)
776778

777779
/// BUILTIN_OP_END - This must be the last enum value in this list.
778780
/// The target-specific post-isel opcode values start here.

llvm/include/llvm/Target/GenericOpcodes.td

+7
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ def G_FREEZE : GenericInstruction {
225225
let hasSideEffects = false;
226226
}
227227

228+
// Generic opcode equivalent to the llvm.isnan intrinsic.
229+
def G_ISNAN: GenericInstruction {
230+
let OutOperandList = (outs type0:$dst);
231+
let InOperandList = (ins type1:$src);
232+
let hasSideEffects = false;
233+
}
234+
228235
//------------------------------------------------------------------------------
229236
// Binary ops.
230237
//------------------------------------------------------------------------------

llvm/lib/CodeGen/MachineVerifier.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,25 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
947947
// Verify properties of various specific instruction types
948948
unsigned Opc = MI->getOpcode();
949949
switch (Opc) {
950+
case TargetOpcode::G_ISNAN: {
951+
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
952+
LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
953+
LLT S1 = DstTy.isVector() ? DstTy.getElementType() : DstTy;
954+
if (S1 != LLT::scalar(1)) {
955+
report("Destination must be a 1-bit scalar or vector of 1-bit elements",
956+
MI);
957+
break;
958+
}
959+
960+
// Disallow pointers.
961+
LLT SrcOrElt = SrcTy.isVector() ? SrcTy.getElementType() : SrcTy;
962+
if (!SrcOrElt.isScalar()) {
963+
report("Source must be a scalar or vector of scalars", MI);
964+
break;
965+
}
966+
verifyVectorElementMatch(DstTy, SrcTy, MI);
967+
break;
968+
}
950969
case TargetOpcode::G_ASSERT_SEXT:
951970
case TargetOpcode::G_ASSERT_ZEXT: {
952971
std::string OpcName =
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# REQUIRES: aarch64-registered-target
2+
# RUN: not --crash llc -verify-machineinstrs -mtriple aarch64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
3+
4+
name: test
5+
body: |
6+
bb.0:
7+
liveins: $x0
8+
%s64:_(s64) = COPY $x0
9+
%v4s16:_(<4 x s16>) = COPY $x0
10+
11+
; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
12+
; CHECK: instruction: %isnan1:_(s64) = G_ISNAN %s64:_(s64)
13+
%isnan1:_(s64) = G_ISNAN %s64
14+
15+
; CHECK: *** Bad machine code: operand types must be all-vector or all-scalar ***
16+
; CHECK: instruction: %isnan2:_(<2 x s1>) = G_ISNAN %s64:_(s64)
17+
%isnan2:_(<2 x s1>) = G_ISNAN %s64
18+
19+
; CHECK: *** Bad machine code: operand types must preserve number of vector elements ***
20+
; CHECK: instruction: %isnan3:_(<2 x s1>) = G_ISNAN %v4s16:_(<4 x s16>)
21+
%isnan3:_(<2 x s1>) = G_ISNAN %v4s16
22+
23+
; CHECK: *** Bad machine code: operand types must be all-vector or all-scalar ***
24+
; CHECK: instruction: %isnan4:_(s1) = G_ISNAN %v4s16:_(<4 x s16>)
25+
%isnan4:_(s1) = G_ISNAN %v4s16
26+
27+
; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
28+
; CHECK: instruction: %isnan5:_(p0) = G_ISNAN %s64:_(s64)
29+
%isnan5:_(p0) = G_ISNAN %s64
30+
31+
; CHECK: *** Bad machine code: Destination must be a 1-bit scalar or vector of 1-bit elements ***
32+
; CHECK: instruction: %isnan6:_(<4 x p0>) = G_ISNAN %v4s16:_(<4 x s16>)
33+
%isnan6:_(<4 x p0>) = G_ISNAN %v4s16

0 commit comments

Comments
 (0)