Skip to content

Commit f532b02

Browse files
committed
InstCombine: Add baseline tests for is.fpclass with fcmp
1 parent af1f1b0 commit f532b02

File tree

1 file changed

+388
-0
lines changed

1 file changed

+388
-0
lines changed
Lines changed: 388 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,388 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3+
4+
define i1 @fcmp_oeq_inf_or_class_normal(half %x) {
5+
; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal(
6+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
7+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
8+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
9+
; CHECK-NEXT: ret i1 [[OR]]
10+
;
11+
%oeq.inf = fcmp oeq half %x, 0xH7C00
12+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
13+
%or = or i1 %oeq.inf, %class
14+
ret i1 %or
15+
}
16+
17+
define i1 @class_normal_or_fcmp_oeq_inf(half %x) {
18+
; CHECK-LABEL: @class_normal_or_fcmp_oeq_inf(
19+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
20+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
21+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CLASS]], [[OEQ_INF]]
22+
; CHECK-NEXT: ret i1 [[OR]]
23+
;
24+
%oeq.inf = fcmp oeq half %x, 0xH7C00
25+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
26+
%or = or i1 %class, %oeq.inf
27+
ret i1 %or
28+
}
29+
30+
define <2 x i1> @fcmp_oeq_inf_or_class_normal_vector(<2 x half> %x) {
31+
; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_vector(
32+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], <half 0xH7C00, half 0xH7C00>
33+
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264)
34+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]]
35+
; CHECK-NEXT: ret <2 x i1> [[OR]]
36+
;
37+
%oeq.inf = fcmp oeq <2 x half> %x, <half 0xH7C00, half 0xH7C00>
38+
%class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)
39+
%or = or <2 x i1> %oeq.inf, %class
40+
ret <2 x i1> %or
41+
}
42+
43+
define i1 @fcmp_oeq_inf_multi_use_or_class_normal(half %x, ptr %ptr) {
44+
; CHECK-LABEL: @fcmp_oeq_inf_multi_use_or_class_normal(
45+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
46+
; CHECK-NEXT: store i1 [[OEQ_INF]], ptr [[PTR:%.*]], align 1
47+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
48+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
49+
; CHECK-NEXT: ret i1 [[OR]]
50+
;
51+
%oeq.inf = fcmp oeq half %x, 0xH7C00
52+
store i1 %oeq.inf, ptr %ptr
53+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
54+
%or = or i1 %oeq.inf, %class
55+
ret i1 %or
56+
}
57+
58+
define i1 @fcmp_oeq_inf_or_class_normal_multi_use(half %x, ptr %ptr) {
59+
; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_multi_use(
60+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
61+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
62+
; CHECK-NEXT: store i1 [[CLASS]], ptr [[PTR:%.*]], align 1
63+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
64+
; CHECK-NEXT: ret i1 [[OR]]
65+
;
66+
%oeq.inf = fcmp oeq half %x, 0xH7C00
67+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
68+
store i1 %class, ptr %ptr
69+
%or = or i1 %oeq.inf, %class
70+
ret i1 %or
71+
}
72+
73+
; -> true
74+
define i1 @fcmp_ord_or_class_isnan(half %x) {
75+
; CHECK-LABEL: @fcmp_ord_or_class_isnan(
76+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
77+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 3)
78+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[ORD]], [[CLASS]]
79+
; CHECK-NEXT: ret i1 [[OR]]
80+
;
81+
%ord = fcmp ord half %x, 0.0
82+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)
83+
%or = or i1 %ord, %class
84+
ret i1 %or
85+
}
86+
87+
define i1 @fcmp_ord_or_class_isnan_wrong_operand(half %x, half %y) {
88+
; CHECK-LABEL: @fcmp_ord_or_class_isnan_wrong_operand(
89+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
90+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[Y:%.*]], i32 3)
91+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[ORD]], [[CLASS]]
92+
; CHECK-NEXT: ret i1 [[OR]]
93+
;
94+
%ord = fcmp ord half %x, 0.0
95+
%class = call i1 @llvm.is.fpclass.f16(half %y, i32 3)
96+
%or = or i1 %ord, %class
97+
ret i1 %or
98+
}
99+
100+
; -> false
101+
define i1 @fcmp_ord_and_class_isnan(half %x) {
102+
; CHECK-LABEL: @fcmp_ord_and_class_isnan(
103+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
104+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 3)
105+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CLASS]]
106+
; CHECK-NEXT: ret i1 [[AND]]
107+
;
108+
%ord = fcmp ord half %x, 0.0
109+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)
110+
%and = and i1 %ord, %class
111+
ret i1 %and
112+
}
113+
114+
; -> true
115+
define i1 @fcmp_ord_or_class_isnan_commute(half %x) {
116+
; CHECK-LABEL: @fcmp_ord_or_class_isnan_commute(
117+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 3)
118+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
119+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CLASS]], [[ORD]]
120+
; CHECK-NEXT: ret i1 [[OR]]
121+
;
122+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)
123+
%ord = fcmp ord half %x, 0.0
124+
%or = or i1 %class, %ord
125+
ret i1 %or
126+
}
127+
128+
; -> false
129+
define i1 @fcmp_ord_and_class_isnan_commute(half %x) {
130+
; CHECK-LABEL: @fcmp_ord_and_class_isnan_commute(
131+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 3)
132+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
133+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[CLASS]], [[ORD]]
134+
; CHECK-NEXT: ret i1 [[AND]]
135+
;
136+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)
137+
%ord = fcmp ord half %x, 0.0
138+
%and = and i1 %class, %ord
139+
ret i1 %and
140+
}
141+
142+
define i1 @fcmp_isfinite_and_class_subnormal(half %x) {
143+
; CHECK-LABEL: @fcmp_isfinite_and_class_subnormal(
144+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
145+
; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt half [[FABS]], 0xH7C00
146+
; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 144)
147+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[IS_FINITE]], [[SUBNORMAL_CLASS]]
148+
; CHECK-NEXT: ret i1 [[AND]]
149+
;
150+
%fabs = call half @llvm.fabs.f16(half %x)
151+
%is.finite = fcmp olt half %fabs, 0xH7C00
152+
%subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144)
153+
%and = and i1 %is.finite, %subnormal.class
154+
ret i1 %and
155+
}
156+
157+
define i1 @fcmp_isfinite_or_class_subnormal(half %x) {
158+
; CHECK-LABEL: @fcmp_isfinite_or_class_subnormal(
159+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
160+
; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt half [[FABS]], 0xH7C00
161+
; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 144)
162+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_FINITE]], [[SUBNORMAL_CLASS]]
163+
; CHECK-NEXT: ret i1 [[OR]]
164+
;
165+
%fabs = call half @llvm.fabs.f16(half %x)
166+
%is.finite = fcmp olt half %fabs, 0xH7C00
167+
%subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144)
168+
%or = or i1 %is.finite, %subnormal.class
169+
ret i1 %or
170+
}
171+
172+
; -> isfinite
173+
define i1 @fcmp_issubnormal_or_class_finite(half %x) {
174+
; CHECK-LABEL: @fcmp_issubnormal_or_class_finite(
175+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
176+
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
177+
; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504)
178+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_FINITE_CLASS]]
179+
; CHECK-NEXT: ret i1 [[OR]]
180+
;
181+
%fabs = call half @llvm.fabs.f16(half %x)
182+
%is.subnormal = fcmp olt half %fabs, 0xH0400
183+
%is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)
184+
%or = or i1 %is.subnormal, %is.finite.class
185+
ret i1 %or
186+
}
187+
188+
; -> isfinite
189+
define i1 @class_finite_or_fcmp_issubnormal(half %x) {
190+
; CHECK-LABEL: @class_finite_or_fcmp_issubnormal(
191+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
192+
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
193+
; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504)
194+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_FINITE_CLASS]], [[IS_SUBNORMAL]]
195+
; CHECK-NEXT: ret i1 [[OR]]
196+
;
197+
%fabs = call half @llvm.fabs.f16(half %x)
198+
%is.subnormal = fcmp olt half %fabs, 0xH0400
199+
%is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)
200+
%or = or i1 %is.finite.class, %is.subnormal
201+
ret i1 %or
202+
}
203+
204+
; -> issubnormal
205+
define i1 @fcmp_issubnormal_and_class_finite(half %x) {
206+
; CHECK-LABEL: @fcmp_issubnormal_and_class_finite(
207+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
208+
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
209+
; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504)
210+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[IS_SUBNORMAL]], [[IS_FINITE_CLASS]]
211+
; CHECK-NEXT: ret i1 [[AND]]
212+
;
213+
%fabs = call half @llvm.fabs.f16(half %x)
214+
%is.subnormal = fcmp olt half %fabs, 0xH0400
215+
%is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)
216+
%and = and i1 %is.subnormal, %is.finite.class
217+
ret i1 %and
218+
}
219+
220+
define i1 @class_inf_or_fcmp_issubnormal(half %x) {
221+
; CHECK-LABEL: @class_inf_or_fcmp_issubnormal(
222+
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
223+
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
224+
; CHECK-NEXT: [[IS_INF_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 516)
225+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_INF_CLASS]], [[IS_SUBNORMAL]]
226+
; CHECK-NEXT: ret i1 [[OR]]
227+
;
228+
%fabs = call half @llvm.fabs.f16(half %x)
229+
%is.subnormal = fcmp olt half %fabs, 0xH0400
230+
%is.inf.class = call i1 @llvm.is.fpclass.f16(half %x, i32 516)
231+
%or = or i1 %is.inf.class, %is.subnormal
232+
ret i1 %or
233+
}
234+
235+
; -> isfinite
236+
define <2 x i1> @class_finite_or_fcmp_issubnormal_vector(<2 x half> %x) {
237+
; CHECK-LABEL: @class_finite_or_fcmp_issubnormal_vector(
238+
; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
239+
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt <2 x half> [[FABS]], <half 0xH0400, half 0xH0400>
240+
; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 504)
241+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[IS_FINITE_CLASS]], [[IS_SUBNORMAL]]
242+
; CHECK-NEXT: ret <2 x i1> [[OR]]
243+
;
244+
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
245+
%is.subnormal = fcmp olt <2 x half> %fabs, <half 0xH0400, half 0xH0400>
246+
%is.finite.class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 504)
247+
%or = or <2 x i1> %is.finite.class, %is.subnormal
248+
ret <2 x i1> %or
249+
}
250+
251+
define i1 @fcmp_oeq_zero_or_class_normal(half %x) {
252+
; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal(
253+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
254+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
255+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
256+
; CHECK-NEXT: ret i1 [[OR]]
257+
;
258+
%oeq.inf = fcmp oeq half %x, 0.0
259+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
260+
%or = or i1 %oeq.inf, %class
261+
ret i1 %or
262+
}
263+
264+
define i1 @class_normal_or_fcmp_oeq_zero(half %x) {
265+
; CHECK-LABEL: @class_normal_or_fcmp_oeq_zero(
266+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
267+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
268+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]
269+
; CHECK-NEXT: ret i1 [[OR]]
270+
;
271+
%oeq.inf = fcmp oeq half %x, 0.0
272+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
273+
%or = or i1 %oeq.inf, %class
274+
ret i1 %or
275+
}
276+
277+
define i1 @fcmp_ueq_zero_or_class_normal(half %x) {
278+
; CHECK-LABEL: @fcmp_ueq_zero_or_class_normal(
279+
; CHECK-NEXT: [[UEQ_INF:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000
280+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
281+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[UEQ_INF]], [[CLASS]]
282+
; CHECK-NEXT: ret i1 [[OR]]
283+
;
284+
%ueq.inf = fcmp ueq half %x, 0.0
285+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
286+
%or = or i1 %ueq.inf, %class
287+
ret i1 %or
288+
}
289+
290+
define i1 @class_normal_or_fcmp_ueq_zero(half %x) {
291+
; CHECK-LABEL: @class_normal_or_fcmp_ueq_zero(
292+
; CHECK-NEXT: [[UEQ_INF:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000
293+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
294+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[UEQ_INF]], [[CLASS]]
295+
; CHECK-NEXT: ret i1 [[OR]]
296+
;
297+
%ueq.inf = fcmp ueq half %x, 0.0
298+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
299+
%or = or i1 %ueq.inf, %class
300+
ret i1 %or
301+
}
302+
303+
define i1 @fcmp_one_zero_or_class_normal(half %x) {
304+
; CHECK-LABEL: @fcmp_one_zero_or_class_normal(
305+
; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000
306+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
307+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]
308+
; CHECK-NEXT: ret i1 [[OR]]
309+
;
310+
%one.inf = fcmp one half %x, 0.0
311+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
312+
%or = or i1 %one.inf, %class
313+
ret i1 %or
314+
}
315+
316+
define i1 @class_normal_or_fcmp_one_zero(half %x) {
317+
; CHECK-LABEL: @class_normal_or_fcmp_one_zero(
318+
; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000
319+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
320+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]
321+
; CHECK-NEXT: ret i1 [[OR]]
322+
;
323+
%one.inf = fcmp one half %x, 0.0
324+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
325+
%or = or i1 %one.inf, %class
326+
ret i1 %or
327+
}
328+
329+
define i1 @fcmp_une_zero_or_class_normal(half %x) {
330+
; CHECK-LABEL: @fcmp_une_zero_or_class_normal(
331+
; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000
332+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
333+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]
334+
; CHECK-NEXT: ret i1 [[OR]]
335+
;
336+
%une.inf = fcmp une half %x, 0.0
337+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
338+
%or = or i1 %une.inf, %class
339+
ret i1 %or
340+
}
341+
342+
define i1 @class_normal_or_fcmp_une_zero(half %x) {
343+
; CHECK-LABEL: @class_normal_or_fcmp_une_zero(
344+
; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000
345+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
346+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]
347+
; CHECK-NEXT: ret i1 [[OR]]
348+
;
349+
%une.inf = fcmp une half %x, 0.0
350+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
351+
%or = or i1 %une.inf, %class
352+
ret i1 %or
353+
}
354+
355+
define i1 @fcmp_oeq_inf_xor_class_normal(half %x) {
356+
; CHECK-LABEL: @fcmp_oeq_inf_xor_class_normal(
357+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
358+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
359+
; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OEQ_INF]], [[CLASS]]
360+
; CHECK-NEXT: ret i1 [[XOR]]
361+
;
362+
%oeq.inf = fcmp oeq half %x, 0xH7C00
363+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
364+
%xor = xor i1 %oeq.inf, %class
365+
ret i1 %xor
366+
}
367+
368+
define i1 @class_normal_xor_fcmp_oeq_inf(half %x) {
369+
; CHECK-LABEL: @class_normal_xor_fcmp_oeq_inf(
370+
; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
371+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)
372+
; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CLASS]], [[OEQ_INF]]
373+
; CHECK-NEXT: ret i1 [[XOR]]
374+
;
375+
%oeq.inf = fcmp oeq half %x, 0xH7C00
376+
%class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)
377+
%xor = xor i1 %class, %oeq.inf
378+
ret i1 %xor
379+
}
380+
381+
382+
declare half @llvm.fabs.f16(half) #0
383+
declare half @llvm.canonicalize.f16(half) #0
384+
declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0
385+
declare i1 @llvm.is.fpclass.f16(half, i32 immarg) #0
386+
declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32 immarg) #0
387+
388+
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

0 commit comments

Comments
 (0)