Skip to content

Commit d987371

Browse files
author
Jessica Paquette
committed
[GlobalISel] Add IRTranslator support for G_ISNAN
Translate the `@llvm.isnan` intrinsic to G_ISNAN when we see it. This is pretty much the same as the associated SelectionDAGBuilder code. Main difference is that we don't expand it here. It makes more sense to do that during legalization in GlobalISel. GlobalISel will just legalize the generated illegal types. Differential Revision: https://reviews.llvm.org/D108226
1 parent 66e2772 commit d987371

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

+6
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,12 @@ class MachineIRBuilder {
18651865
return buildInstr(TargetOpcode::G_BITREVERSE, {Dst}, {Src});
18661866
}
18671867

1868+
/// Build and insert \p Dst = G_ISNAN \p Src
1869+
MachineInstrBuilder buildIsNaN(const DstOp &Dst, const SrcOp &Src,
1870+
Optional<unsigned> Flags = None) {
1871+
return buildInstr(TargetOpcode::G_ISNAN, {Dst}, {Src}, Flags);
1872+
}
1873+
18681874
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
18691875
ArrayRef<SrcOp> SrcOps,
18701876
Optional<unsigned> Flags = None);

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,14 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
22282228

22292229
return true;
22302230
}
2231+
case Intrinsic::isnan: {
2232+
Register Src = getOrCreateVReg(*CI.getArgOperand(0));
2233+
unsigned Flags = MachineInstr::copyFlagsFromInstruction(CI);
2234+
if (!CI.getFunction()->getAttributes().hasFnAttr(llvm::Attribute::StrictFP))
2235+
Flags |= MachineInstr::NoFPExcept;
2236+
MIRBuilder.buildIsNaN(getOrCreateVReg(CI), Src, Flags);
2237+
return true;
2238+
}
22312239
#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
22322240
case Intrinsic::INTRINSIC:
22332241
#include "llvm/IR/ConstrainedOps.def"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -global-isel -mtriple=aarch64-unknown-unknown -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
3+
declare i1 @llvm.isnan.f16(half)
4+
declare <4 x i1> @llvm.isnan.v4f16(<4 x half>)
5+
6+
define i1 @s16(half %x) {
7+
; CHECK-LABEL: name: s16
8+
; CHECK: bb.1 (%ir-block.0):
9+
; CHECK: liveins: $h0
10+
; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
11+
; CHECK: %1:_(s1) = nofpexcept G_ISNAN [[COPY]](s16)
12+
; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT %1(s1)
13+
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
14+
; CHECK: $w0 = COPY [[ANYEXT]](s32)
15+
; CHECK: RET_ReallyLR implicit $w0
16+
%isnan = tail call i1 @llvm.isnan.f16(half %x)
17+
ret i1 %isnan
18+
}
19+
20+
define <4 x i1> @v4s16(<4 x half> %x) {
21+
; CHECK-LABEL: name: v4s16
22+
; CHECK: bb.1 (%ir-block.0):
23+
; CHECK: liveins: $d0
24+
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
25+
; CHECK: %1:_(<4 x s1>) = nofpexcept G_ISNAN [[COPY]](<4 x s16>)
26+
; CHECK: [[ANYEXT:%[0-9]+]]:_(<4 x s16>) = G_ANYEXT %1(<4 x s1>)
27+
; CHECK: $d0 = COPY [[ANYEXT]](<4 x s16>)
28+
; CHECK: RET_ReallyLR implicit $d0
29+
%isnan = tail call <4 x i1> @llvm.isnan.v4f16(<4 x half> %x)
30+
ret <4 x i1> %isnan
31+
}
32+
33+
define i1 @strictfp(half %x) strictfp {
34+
; CHECK-LABEL: name: strictfp
35+
; CHECK: bb.1 (%ir-block.0):
36+
; CHECK: liveins: $h0
37+
; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
38+
; CHECK: [[ISNAN:%[0-9]+]]:_(s1) = G_ISNAN [[COPY]](s16)
39+
; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[ISNAN]](s1)
40+
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
41+
; CHECK: $w0 = COPY [[ANYEXT]](s32)
42+
; CHECK: RET_ReallyLR implicit $w0
43+
%isnan = tail call i1 @llvm.isnan.f16(half %x)
44+
ret i1 %isnan
45+
}

0 commit comments

Comments
 (0)