xref: /llvm-project/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll (revision 42ed7757835122a63477b5783215e1100cd0b709)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4; Test and/or of fcmps that could be folded to llvm.is.fpclass
5
6; --------------------------------------------------------------------
7; Base pattern, !isfinite(x) || x == 0.0
8; --------------------------------------------------------------------
9
10; Base pattern !isfinite(x) || x == 0.0
11define i1 @not_isfinite_or_zero_f16(half %x) {
12; CHECK-LABEL: @not_isfinite_or_zero_f16(
13; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
14; CHECK-NEXT:    ret i1 [[CLASS]]
15;
16  %fabs = call half @llvm.fabs.f16(half %x)
17  %cmpinf = fcmp ueq half %fabs, 0xH7C00
18  %cmpzero = fcmp oeq half %x, 0xH0000
19  %class = or i1 %cmpzero, %cmpinf
20  ret i1 %class
21}
22
23; Base pattern x == 0.0 || !isfinite(x)
24define i1 @not_isfinite_or_zero_f16_commute_or(half %x) {
25; CHECK-LABEL: @not_isfinite_or_zero_f16_commute_or(
26; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
27; CHECK-NEXT:    ret i1 [[CLASS]]
28;
29  %fabs = call half @llvm.fabs.f16(half %x)
30  %cmpinf = fcmp ueq half %fabs, 0xH7C00
31  %cmpzero = fcmp oeq half %x, 0xH0000
32  %class = or i1 %cmpinf, %cmpzero
33  ret i1 %class
34}
35
36; Base pattern !isfinite(x) || x == -0.0
37define i1 @not_isfinite_or_zero_f16_negzero(half %x) {
38; CHECK-LABEL: @not_isfinite_or_zero_f16_negzero(
39; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
40; CHECK-NEXT:    ret i1 [[CLASS]]
41;
42  %fabs = call half @llvm.fabs.f16(half %x)
43  %cmpinf = fcmp ueq half %fabs, 0xH7C00
44  %cmpzero = fcmp oeq half %x, -0.0
45  %class = or i1 %cmpzero, %cmpinf
46  ret i1 %class
47}
48
49define i1 @not_isfinite_or_fabs_oeq_zero_f16(half %x) {
50; CHECK-LABEL: @not_isfinite_or_fabs_oeq_zero_f16(
51; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
52; CHECK-NEXT:    ret i1 [[CLASS]]
53;
54  %fabs = call half @llvm.fabs.f16(half %x)
55  %cmpinf = fcmp ueq half %fabs, 0xH7C00
56  %cmpzero = fcmp oeq half %fabs, 0xH0000
57  %class = or i1 %cmpzero, %cmpinf
58  ret i1 %class
59}
60
61; Base pattern !isfinite(x) || x == 0.0
62define <2 x i1> @not_isfinite_or_zero_v2f16(<2 x half> %x) {
63; CHECK-LABEL: @not_isfinite_or_zero_v2f16(
64; CHECK-NEXT:    [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
65; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
66;
67  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
68  %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
69  %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
70  %class = or <2 x i1> %cmpzero, %cmpinf
71  ret <2 x i1> %class
72}
73
74; Base pattern !isfinite(x) || x == <0.0, -0.0>
75define <2 x i1> @not_isfinite_or_zero_v2f16_pos0_neg0_vec(<2 x half> %x) {
76; CHECK-LABEL: @not_isfinite_or_zero_v2f16_pos0_neg0_vec(
77; CHECK-NEXT:    [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
78; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
79;
80  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
81  %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
82  %cmpzero = fcmp oeq <2 x half> %x, <half 0.0, half -0.0>
83  %class = or <2 x i1> %cmpzero, %cmpinf
84  ret <2 x i1> %class
85}
86
87; Base pattern x == 0.0 || !isfinite(x)
88define <2 x i1> @not_isfinite_or_zero_v2f16_commute_or(<2 x half> %x) {
89; CHECK-LABEL: @not_isfinite_or_zero_v2f16_commute_or(
90; CHECK-NEXT:    [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
91; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
92;
93  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
94  %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
95  %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
96  %class = or <2 x i1> %cmpinf, %cmpzero
97  ret <2 x i1> %class
98}
99
100; Positive test
101define i1 @oeq_isinf_or_oeq_zero(half %x) {
102; CHECK-LABEL: @oeq_isinf_or_oeq_zero(
103; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)
104; CHECK-NEXT:    ret i1 [[CLASS]]
105;
106  %fabs = call half @llvm.fabs.f16(half %x)
107  %cmpinf = fcmp oeq half %fabs, 0xH7C00
108  %cmpzero = fcmp oeq half %x, 0xH0000
109  %class = or i1 %cmpzero, %cmpinf
110  ret i1 %class
111}
112
113; Missing fabs for infinity check
114define i1 @ueq_inf_or_oeq_zero(half %x) {
115; CHECK-LABEL: @ueq_inf_or_oeq_zero(
116; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)
117; CHECK-NEXT:    ret i1 [[CLASS]]
118;
119  %cmpinf = fcmp ueq half %x, 0xH7C00
120  %cmpzero = fcmp oeq half %x, 0xH0000
121  %class = or i1 %cmpzero, %cmpinf
122  ret i1 %class
123}
124
125; Extra fabs.
126define i1 @oeq_isinf_or_fabs_oeq_zero(half %x) {
127; CHECK-LABEL: @oeq_isinf_or_fabs_oeq_zero(
128; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)
129; CHECK-NEXT:    ret i1 [[CLASS]]
130;
131  %fabs = call half @llvm.fabs.f16(half %x)
132  %cmpinf = fcmp oeq half %fabs, 0xH7C00
133  %cmpzero = fcmp oeq half %fabs, 0xH0000
134  %class = or i1 %cmpzero, %cmpinf
135  ret i1 %class
136}
137
138; Positive test
139define i1 @ueq_0_or_oeq_inf(half %x) {
140; CHECK-LABEL: @ueq_0_or_oeq_inf(
141; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)
142; CHECK-NEXT:    ret i1 [[CLASS]]
143;
144  %fabs = call half @llvm.fabs.f16(half %x)
145  %cmpinf = fcmp ueq half %fabs, 0xH0000
146  %cmpzero = fcmp oeq half %x, 0xH7C00
147  %class = or i1 %cmpzero, %cmpinf
148  ret i1 %class
149}
150
151; Positive test
152define i1 @not_isfinite_or_zero_f16_not_inf(half %x) {
153; CHECK-LABEL: @not_isfinite_or_zero_f16_not_inf(
154; CHECK-NEXT:    ret i1 true
155;
156  %fabs = call half @llvm.fabs.f16(half %x)
157  %cmpinf = fcmp ueq half %fabs, 0xH7C01
158  %cmpzero = fcmp oeq half %x, 0xH0000
159  %class = or i1 %cmpzero, %cmpinf
160  ret i1 %class
161}
162
163; Positive test
164define i1 @ueq_inf_or_ueq_zero(half %x) {
165; CHECK-LABEL: @ueq_inf_or_ueq_zero(
166; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
167; CHECK-NEXT:    ret i1 [[CLASS]]
168;
169  %fabs = call half @llvm.fabs.f16(half %x)
170  %cmpinf = fcmp ueq half %fabs, 0xH7C00
171  %cmpzero = fcmp ueq half %x, 0xH0000
172  %class = or i1 %cmpzero, %cmpinf
173  ret i1 %class
174}
175
176; Positive test
177define i1 @not_isfinite_and_zero_f16(half %x) {
178; CHECK-LABEL: @not_isfinite_and_zero_f16(
179; CHECK-NEXT:    ret i1 false
180;
181  %fabs = call half @llvm.fabs.f16(half %x)
182  %cmpinf = fcmp ueq half %fabs, 0xH7C00
183  %cmpzero = fcmp oeq half %x, 0xH0000
184  %class = and i1 %cmpzero, %cmpinf
185  ret i1 %class
186}
187
188; Negative test
189define i1 @not_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {
190; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp0(
191; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
192; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
193; CHECK-NEXT:    store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1
194; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
195; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
196; CHECK-NEXT:    ret i1 [[CLASS]]
197;
198  %fabs = call half @llvm.fabs.f16(half %x)
199  %cmpinf = fcmp ueq half %fabs, 0xH7C00
200  store i1 %cmpinf, ptr %ptr
201  %cmpzero = fcmp oeq half %x, 0xH0000
202  %class = or i1 %cmpzero, %cmpinf
203  ret i1 %class
204}
205
206; Negative test
207define i1 @not_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {
208; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp1(
209; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
210; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
211; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
212; CHECK-NEXT:    store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1
213; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
214; CHECK-NEXT:    ret i1 [[CLASS]]
215;
216  %fabs = call half @llvm.fabs.f16(half %x)
217  %cmpinf = fcmp ueq half %fabs, 0xH7C00
218  %cmpzero = fcmp oeq half %x, 0xH0000
219  store i1 %cmpzero, ptr %ptr
220  %class = or i1 %cmpzero, %cmpinf
221  ret i1 %class
222}
223
224; Negative test
225define i1 @not_isfinite_or_zero_f16_neg_inf(half %x) {
226; CHECK-LABEL: @not_isfinite_or_zero_f16_neg_inf(
227; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000
228; CHECK-NEXT:    ret i1 [[CLASS]]
229;
230  %fabs = call half @llvm.fabs.f16(half %x)
231  %cmpinf = fcmp ueq half %fabs, 0xHFC00
232  %cmpzero = fcmp oeq half %x, 0xH0000
233  %class = or i1 %cmpzero, %cmpinf
234  ret i1 %class
235}
236
237; Negative test
238define i1 @olt_0_or_fabs_ueq_inf(half %x) {
239; CHECK-LABEL: @olt_0_or_fabs_ueq_inf(
240; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
241; CHECK-NEXT:    ret i1 [[CLASS]]
242;
243  %fabs = call half @llvm.fabs.f16(half %x)
244  %cmpinf = fcmp ueq half %fabs, 0xH7C00
245  %cmpzero = fcmp olt half %x, 0xH0000
246  %class = or i1 %cmpzero, %cmpinf
247  ret i1 %class
248}
249
250; Negative test
251define i1 @oeq_0_or_fabs_ult_inf(half %x) {
252; CHECK-LABEL: @oeq_0_or_fabs_ult_inf(
253; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
254; CHECK-NEXT:    [[CLASS:%.*]] = fcmp une half [[TMP1]], 0xH7C00
255; CHECK-NEXT:    ret i1 [[CLASS]]
256;
257  %fabs = call half @llvm.fabs.f16(half %x)
258  %cmpinf = fcmp ult half %fabs, 0xH7C00
259  %cmpzero = fcmp oeq half %x, 0xH0000
260  %class = or i1 %cmpzero, %cmpinf
261  ret i1 %class
262}
263
264; Negative test
265define i1 @not_isfinite_or_zero_f16_multi_not_0(half %x, ptr %ptr) {
266; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_not_0(
267; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
268; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
269; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH3C00
270; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
271; CHECK-NEXT:    ret i1 [[CLASS]]
272;
273  %fabs = call half @llvm.fabs.f16(half %x)
274  %cmpinf = fcmp ueq half %fabs, 0xH7C00
275  %cmpzero = fcmp oeq half %x, 1.0
276  %class = or i1 %cmpzero, %cmpinf
277  ret i1 %class
278}
279
280; Negative test
281define i1 @not_isfinite_or_zero_f16_fabs_wrong_val(half %x, half %y) {
282; CHECK-LABEL: @not_isfinite_or_zero_f16_fabs_wrong_val(
283; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])
284; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
285; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
286; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
287; CHECK-NEXT:    ret i1 [[CLASS]]
288;
289  %fabs = call half @llvm.fabs.f16(half %y)
290  %cmpinf = fcmp ueq half %fabs, 0xH7C00
291  %cmpzero = fcmp oeq half %x, 0xH0000
292  %class = or i1 %cmpzero, %cmpinf
293  ret i1 %class
294}
295
296; Negative test
297define i1 @not_isfinite_or_zero_f16_not_fabs(half %x) {
298; CHECK-LABEL: @not_isfinite_or_zero_f16_not_fabs(
299; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.canonicalize.f16(half [[X:%.*]])
300; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
301; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
302; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
303; CHECK-NEXT:    ret i1 [[CLASS]]
304;
305  %fabs = call half @llvm.canonicalize.f16(half %x)
306  %cmpinf = fcmp ueq half %fabs, 0xH7C00
307  %cmpzero = fcmp oeq half %x, 0xH0000
308  %class = or i1 %cmpzero, %cmpinf
309  ret i1 %class
310}
311
312; --------------------------------------------------------------------
313; Negated pattern, isfinite(x) && !(x == 0.0)
314; --------------------------------------------------------------------
315
316; Negation of base pattern, isfinite(x) && !(x == 0.0)
317define i1 @negated_isfinite_or_zero_f16(half %x) {
318; CHECK-LABEL: @negated_isfinite_or_zero_f16(
319; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
320; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
321;
322  %fabs = call half @llvm.fabs.f16(half %x)
323  %cmpinf = fcmp one half %fabs, 0xH7C00
324  %cmpzero = fcmp une half %x, 0xH0000
325  %not.class = and i1 %cmpzero, %cmpinf
326  ret i1 %not.class
327}
328
329; Commuted !(x == 0.0) && isfinite(x)
330define i1 @negated_isfinite_or_zero_f16_commute_and(half %x) {
331; CHECK-LABEL: @negated_isfinite_or_zero_f16_commute_and(
332; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
333; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
334;
335  %fabs = call half @llvm.fabs.f16(half %x)
336  %cmpinf = fcmp one half %fabs, 0xH7C00
337  %cmpzero = fcmp une half %x, 0xH0000
338  %not.class = and i1 %cmpinf, %cmpzero
339  ret i1 %not.class
340}
341
342; isfinite(x) && !(x == -0.0)
343define i1 @negated_isfinite_or_zero_f16_negzero(half %x) {
344; CHECK-LABEL: @negated_isfinite_or_zero_f16_negzero(
345; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
346; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
347;
348  %fabs = call half @llvm.fabs.f16(half %x)
349  %cmpinf = fcmp one half %fabs, 0xH7C00
350  %cmpzero = fcmp une half %x, -0.0
351  %not.class = and i1 %cmpzero, %cmpinf
352  ret i1 %not.class
353}
354
355; Negated pattern
356define <2 x i1> @negated_isfinite_or_zero_v2f16(<2 x half> %x) {
357; CHECK-LABEL: @negated_isfinite_or_zero_v2f16(
358; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)
359; CHECK-NEXT:    ret <2 x i1> [[NOT_CLASS]]
360;
361  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
362  %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
363  %cmpzero = fcmp une <2 x half> %x, zeroinitializer
364  %not.class = and <2 x i1> %cmpzero, %cmpinf
365  ret <2 x i1> %not.class
366}
367
368; Negated pattern, commuted vector and
369define <2 x i1> @negated_isfinite_or_zero_v2f16_comumte(<2 x half> %x) {
370; CHECK-LABEL: @negated_isfinite_or_zero_v2f16_comumte(
371; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)
372; CHECK-NEXT:    ret <2 x i1> [[NOT_CLASS]]
373;
374  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
375  %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
376  %cmpzero = fcmp une <2 x half> %x, zeroinitializer
377  %not.class = and <2 x i1> %cmpinf, %cmpzero
378  ret <2 x i1> %not.class
379}
380
381; Positive test
382define i1 @negated_isfinite_or_zero_f16_not_une_zero(half %x) {
383; CHECK-LABEL: @negated_isfinite_or_zero_f16_not_une_zero(
384; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
385; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
386;
387  %fabs = call half @llvm.fabs.f16(half %x)
388  %cmpinf = fcmp one half %fabs, 0xH7C00
389  %cmpzero = fcmp one half %x, 0xH0000
390  %not.class = and i1 %cmpzero, %cmpinf
391  ret i1 %not.class
392}
393
394; Positive test
395define i1 @negated_isfinite_and_zero_f16(half %x) {
396; CHECK-LABEL: @negated_isfinite_and_zero_f16(
397; CHECK-NEXT:    ret i1 true
398;
399  %fabs = call half @llvm.fabs.f16(half %x)
400  %cmpinf = fcmp one half %fabs, 0xH7C00
401  %cmpzero = fcmp une half %x, 0xH0000
402  %not.class = or i1 %cmpzero, %cmpinf
403  ret i1 %not.class
404}
405
406; Negative test
407define i1 @negated_isfinite_or_zero_f16_swapped_constants(half %x) {
408; CHECK-LABEL: @negated_isfinite_or_zero_f16_swapped_constants(
409; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 412)
410; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
411;
412  %fabs = call half @llvm.fabs.f16(half %x)
413  %cmpzero = fcmp one half %fabs, 0xH0000
414  %cmpinf = fcmp une half %x, 0xH7C00
415  %not.class = and i1 %cmpzero, %cmpinf
416  ret i1 %not.class
417}
418
419; Negative test
420define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {
421; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0(
422; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
423; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
424; CHECK-NEXT:    store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1
425; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000
426; CHECK-NEXT:    [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
427; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
428;
429  %fabs = call half @llvm.fabs.f16(half %x)
430  %cmpinf = fcmp one half %fabs, 0xH7C00
431  store i1 %cmpinf, ptr %ptr
432  %cmpzero = fcmp une half %x, 0xH0000
433  %not.class = and i1 %cmpzero, %cmpinf
434  ret i1 %not.class
435}
436
437; Negative test
438define i1 @negated_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {
439; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp1(
440; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
441; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
442; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000
443; CHECK-NEXT:    store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1
444; CHECK-NEXT:    [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
445; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
446;
447  %fabs = call half @llvm.fabs.f16(half %x)
448  %cmpinf = fcmp one half %fabs, 0xH7C00
449  %cmpzero = fcmp une half %x, 0xH0000
450  store i1 %cmpzero, ptr %ptr
451  %not.class = and i1 %cmpzero, %cmpinf
452  ret i1 %not.class
453}
454
455; Negative test
456define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(half %x) {
457; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(
458; CHECK-NEXT:    [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)
459; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
460;
461  %fabs = call half @llvm.fabs.f16(half %x)
462  %cmpinf = fcmp une half %fabs, 0xH7C00
463  %cmpzero = fcmp une half %x, 0xH0000
464  %not.class = and i1 %cmpzero, %cmpinf
465  ret i1 %not.class
466}
467
468; Negative test
469define i1 @negated_isfinite_or_zero_f16_fabs_wrong_value(half %x, half %y) {
470; CHECK-LABEL: @negated_isfinite_or_zero_f16_fabs_wrong_value(
471; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])
472; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
473; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp une half [[X:%.*]], 0xH0000
474; CHECK-NEXT:    [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
475; CHECK-NEXT:    ret i1 [[NOT_CLASS]]
476;
477  %fabs = call half @llvm.fabs.f16(half %y)
478  %cmpinf = fcmp one half %fabs, 0xH7C00
479  %cmpzero = fcmp une half %x, 0xH0000
480  %not.class = and i1 %cmpzero, %cmpinf
481  ret i1 %not.class
482}
483
484; --------------------------------------------------------------------
485; Other fcmp to class recognition
486; --------------------------------------------------------------------
487
488define i1 @fcmp_une_0_or_fcmp_une_inf(half %x) {
489; CHECK-LABEL: @fcmp_une_0_or_fcmp_une_inf(
490; CHECK-NEXT:    ret i1 true
491;
492  %cmpzero = fcmp une half %x, 0.0
493  %cmpinf = fcmp une half %x, 0xH7C00
494  %or = or i1 %cmpzero, %cmpinf
495  ret i1 %or
496}
497
498define i1 @fcmp_one_0_and_fcmp_une_fabs_inf(half %x) {
499; CHECK-LABEL: @fcmp_one_0_and_fcmp_une_fabs_inf(
500; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
501; CHECK-NEXT:    ret i1 [[AND]]
502;
503  %fabs = call half @llvm.fabs.f16(half %x)
504  %cmpzero = fcmp one half %x, 0.0
505  %cmpinf = fcmp une half %fabs, 0xH7C00
506  %and = and i1 %cmpzero, %cmpinf
507  ret i1 %and
508}
509
510define i1 @fcmp_une_0_and_fcmp_une_fabs_inf(half %x) {
511; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_fabs_inf(
512; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)
513; CHECK-NEXT:    ret i1 [[AND]]
514;
515  %fabs = call half @llvm.fabs.f16(half %x)
516  %cmpzero = fcmp une half %x, 0.0
517  %cmpinf = fcmp une half %fabs, 0xH7C00
518  %and = and i1 %cmpzero, %cmpinf
519  ret i1 %and
520}
521
522define i1 @fcmp_une_0_and_fcmp_une_neginf(half %x) {
523; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_neginf(
524; CHECK-NEXT:    ret i1 true
525;
526  %cmpzero = fcmp une half %x, 0.0
527  %cmpinf = fcmp une half %x, 0xHFC00
528  %or = or i1 %cmpzero, %cmpinf
529  ret i1 %or
530}
531
532define i1 @issubnormal_or_inf(half %x) {
533; CHECK-LABEL: @issubnormal_or_inf(
534; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
535; CHECK-NEXT:    ret i1 [[CLASS]]
536;
537  %fabs = call half @llvm.fabs.f16(half %x)
538  %cmpinf = fcmp oeq half %fabs, 0xH7C00
539  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
540  %class = or i1 %cmp.smallest.normal, %cmpinf
541  ret i1 %class
542}
543
544define i1 @olt_smallest_normal_or_inf(half %x) {
545; CHECK-LABEL: @olt_smallest_normal_or_inf(
546; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 764)
547; CHECK-NEXT:    ret i1 [[CLASS]]
548;
549  %fabs = call half @llvm.fabs.f16(half %x)
550  %cmpinf = fcmp oeq half %fabs, 0xH7C00
551  %cmp.smallest.normal = fcmp olt half %x, 0xH0400 ; missing fabs
552  %class = or i1 %cmp.smallest.normal, %cmpinf
553  ret i1 %class
554}
555
556define i1 @not_issubnormal_or_inf(half %x) {
557; CHECK-LABEL: @not_issubnormal_or_inf(
558; CHECK-NEXT:    [[NOT:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 267)
559; CHECK-NEXT:    ret i1 [[NOT]]
560;
561  %fabs = call half @llvm.fabs.f16(half %x)
562  %cmpinf = fcmp une half %fabs, 0xH7C00
563  %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
564  %not = and i1 %cmp.smallest.normal, %cmpinf
565  ret i1 %not
566}
567
568define i1 @issubnormal_uge_or_inf(half %x) {
569; CHECK-LABEL: @issubnormal_uge_or_inf(
570; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
571; CHECK-NEXT:    ret i1 [[CLASS]]
572;
573  %fabs = call half @llvm.fabs.f16(half %x)
574  %cmpinf = fcmp oeq half %fabs, 0xH7C00
575  %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
576  %class = or i1 %cmp.smallest.normal, %cmpinf
577  ret i1 %class
578}
579
580; Negative test, not smallest normal
581define i1 @issubnormal_or_inf_wrong_val(half %x) {
582; CHECK-LABEL: @issubnormal_or_inf_wrong_val(
583; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
584; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
585; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0401
586; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]
587; CHECK-NEXT:    ret i1 [[CLASS]]
588;
589  %fabs = call half @llvm.fabs.f16(half %x)
590  %cmpinf = fcmp oeq half %fabs, 0xH7C00
591  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0401
592  %class = or i1 %cmp.smallest.normal, %cmpinf
593  ret i1 %class
594}
595
596define i1 @issubnormal_or_inf_neg_smallest_normal(half %x) {
597; CHECK-LABEL: @issubnormal_or_inf_neg_smallest_normal(
598; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
599; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
600; CHECK-NEXT:    ret i1 [[CMPINF]]
601;
602  %fabs = call half @llvm.fabs.f16(half %x)
603  %cmpinf = fcmp oeq half %fabs, 0xH7C00
604  %cmp.smallest.normal = fcmp olt half %fabs, 0xH8400
605  %class = or i1 %cmp.smallest.normal, %cmpinf
606  ret i1 %class
607}
608
609define i1 @fneg_fabs_olt_neg_smallest_normal_or_inf(half %x) {
610; CHECK-LABEL: @fneg_fabs_olt_neg_smallest_normal_or_inf(
611; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
612; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
613; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp ogt half [[FABS]], 0xH0400
614; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]
615; CHECK-NEXT:    ret i1 [[CLASS]]
616;
617  %fabs = call half @llvm.fabs.f16(half %x)
618  %cmpinf = fcmp oeq half %fabs, 0xH7C00
619  %fneg.fabs = fneg half %fabs
620  %cmp.smallest.normal = fcmp olt half %fneg.fabs, 0xH8400
621  %class = or i1 %cmp.smallest.normal, %cmpinf
622  ret i1 %class
623}
624
625define i1 @issubnormal_or_finite_olt(half %x) {
626; CHECK-LABEL: @issubnormal_or_finite_olt(
627; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
628; CHECK-NEXT:    [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00
629; CHECK-NEXT:    ret i1 [[OR]]
630;
631  %fabs = call half @llvm.fabs.f16(half %x)
632  %cmpinf = fcmp olt half %fabs, 0xH7C00
633  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
634  %or = or i1 %cmp.smallest.normal, %cmpinf
635  ret i1 %or
636}
637
638; inf | nan | zero | subnormal
639define i1 @issubnormal_or_finite_uge(half %x) {
640; CHECK-LABEL: @issubnormal_or_finite_uge(
641; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 759)
642; CHECK-NEXT:    ret i1 [[OR]]
643;
644  %fabs = call half @llvm.fabs.f16(half %x)
645  %cmpinf = fcmp uge half %fabs, 0xH7C00
646  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
647  %or = or i1 %cmp.smallest.normal, %cmpinf
648  ret i1 %or
649}
650
651define i1 @issubnormal_and_finite_olt(half %x) {
652; CHECK-LABEL: @issubnormal_and_finite_olt(
653; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
654; CHECK-NEXT:    ret i1 [[AND]]
655;
656  %fabs = call half @llvm.fabs.f16(half %x)
657  %cmpinf = fcmp olt half %fabs, 0xH7C00
658  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
659  %and = and i1 %cmp.smallest.normal, %cmpinf
660  ret i1 %and
661}
662
663define i1 @not_zero_and_subnormal(half %x) {
664; CHECK-LABEL: @not_zero_and_subnormal(
665; CHECK-NEXT:    [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
666; CHECK-NEXT:    ret i1 [[OR]]
667;
668  %fabs = call half @llvm.fabs.f16(half %x)
669  %cmp.zero = fcmp one half %fabs, 0.0
670  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
671  %or = or i1 %cmp.smallest.normal, %cmp.zero
672  ret i1 %or
673}
674
675define i1 @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(half %x) {
676; CHECK-LABEL: @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(
677; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
678; CHECK-NEXT:    ret i1 [[OR]]
679;
680  %fabs = call half @llvm.fabs.f16(half %x)
681  %cmpinf = fcmp uge half %fabs, 0xH7C00
682  %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
683  %or = or i1 %cmp.smallest.normal, %cmpinf
684  ret i1 %or
685}
686
687; --------------------------------------------------------------------
688; Test ord/uno
689; --------------------------------------------------------------------
690
691define i1 @is_finite_and_ord(half %x) {
692; CHECK-LABEL: @is_finite_and_ord(
693; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
694; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
695; CHECK-NEXT:    ret i1 [[AND]]
696;
697  %fabs = call half @llvm.fabs.f16(half %x)
698  %is.finite = fcmp ueq half %fabs, 0xH7C00
699  %ord = fcmp ord half %x, %x
700  %and = and i1 %ord, %is.finite
701  ret i1 %and
702}
703
704define i1 @is_finite_and_uno(half %x) {
705; CHECK-LABEL: @is_finite_and_uno(
706; CHECK-NEXT:    [[AND:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
707; CHECK-NEXT:    ret i1 [[AND]]
708;
709  %fabs = call half @llvm.fabs.f16(half %x)
710  %is.finite = fcmp ueq half %fabs, 0xH7C00
711  %uno = fcmp uno half %x, %x
712  %and = and i1 %uno, %is.finite
713  ret i1 %and
714}
715
716define i1 @is_finite_or_ord(half %x) {
717; CHECK-LABEL: @is_finite_or_ord(
718; CHECK-NEXT:    ret i1 true
719;
720  %fabs = call half @llvm.fabs.f16(half %x)
721  %is.finite = fcmp ueq half %fabs, 0xH7C00
722  %ord = fcmp ord half %x, %x
723  %or = or i1 %ord, %is.finite
724  ret i1 %or
725}
726
727define i1 @is_finite_or_uno(half %x) {
728; CHECK-LABEL: @is_finite_or_uno(
729; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
730; CHECK-NEXT:    [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
731; CHECK-NEXT:    ret i1 [[OR]]
732;
733  %fabs = call half @llvm.fabs.f16(half %x)
734  %is.finite = fcmp ueq half %fabs, 0xH7C00
735  %uno = fcmp uno half %x, %x
736  %or = or i1 %uno, %is.finite
737  ret i1 %or
738}
739
740define i1 @oeq_isinf_or_uno(half %x) {
741; CHECK-LABEL: @oeq_isinf_or_uno(
742; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
743; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
744; CHECK-NEXT:    ret i1 [[CLASS]]
745;
746  %fabs = call half @llvm.fabs.f16(half %x)
747  %cmpinf = fcmp oeq half %fabs, 0xH7C00
748  %uno = fcmp uno half %x, 0xH0000
749  %class = or i1 %cmpinf, %uno
750  ret i1 %class
751}
752
753define i1 @oeq_isinf_or_ord(half %x) {
754; CHECK-LABEL: @oeq_isinf_or_ord(
755; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
756; CHECK-NEXT:    ret i1 [[CLASS]]
757;
758  %fabs = call half @llvm.fabs.f16(half %x)
759  %cmpinf = fcmp oeq half %fabs, 0xH7C00
760  %uno = fcmp ord half %x, 0xH0000
761  %class = or i1 %cmpinf, %uno
762  ret i1 %class
763}
764
765define i1 @oeq_isinf_and_uno(half %x) {
766; CHECK-LABEL: @oeq_isinf_and_uno(
767; CHECK-NEXT:    ret i1 false
768;
769  %fabs = call half @llvm.fabs.f16(half %x)
770  %cmpinf = fcmp oeq half %fabs, 0xH7C00
771  %uno = fcmp uno half %x, 0xH0000
772  %and = and i1 %cmpinf, %uno
773  ret i1 %and
774}
775
776define i1 @oeq_isinf_and_ord(half %x) {
777; CHECK-LABEL: @oeq_isinf_and_ord(
778; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
779; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
780; CHECK-NEXT:    ret i1 [[AND]]
781;
782  %fabs = call half @llvm.fabs.f16(half %x)
783  %cmpinf = fcmp oeq half %fabs, 0xH7C00
784  %uno = fcmp ord half %x, 0xH0000
785  %and = and i1 %cmpinf, %uno
786  ret i1 %and
787}
788
789; --------------------------------------------------------------------
790; isnormal(x) || x == 0.0
791; --------------------------------------------------------------------
792
793define i1 @isnormal_or_zero(half %x) #0 {
794; CHECK-LABEL: @isnormal_or_zero(
795; CHECK-NEXT:  entry:
796; CHECK-NEXT:    [[AND1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360)
797; CHECK-NEXT:    ret i1 [[AND1]]
798;
799entry:
800  %iseq = fcmp ord half %x, 0xH0000
801  %fabs = tail call half @llvm.fabs.f16(half %x)
802  %isinf = fcmp ult half %fabs, 0xH7C00
803  %isnormal = fcmp uge half %fabs, 0xH0400
804  %and = and i1 %iseq, %isinf
805  %and1 = and i1 %isnormal, %and
806  %cmp = fcmp oeq half %x, 0xH0000
807  %spec.select = or i1 %cmp, %and1
808  ret i1 %spec.select
809}
810
811define i1 @isnormal_uge_or_zero_oeq(half %x) #0 {
812; CHECK-LABEL: @isnormal_uge_or_zero_oeq(
813; CHECK-NEXT:  entry:
814; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 879)
815; CHECK-NEXT:    ret i1 [[OR]]
816;
817entry:
818  %fabs = tail call half @llvm.fabs.f16(half %x)
819  %is.normal = fcmp uge half %fabs, 0xH0400
820  %is.zero = fcmp oeq half %x, 0xH0000
821  %or = or i1 %is.normal, %is.zero
822  ret i1 %or
823}
824
825; --------------------------------------------------------------------
826; smallest_normal check part of isnormal(x)
827; --------------------------------------------------------------------
828
829; -> ord
830define i1 @isnormalinf_or_ord(half %x) #0 {
831; CHECK-LABEL: @isnormalinf_or_ord(
832; CHECK-NEXT:    [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
833; CHECK-NEXT:    ret i1 [[OR]]
834;
835  %fabs = call half @llvm.fabs.f16(half %x)
836  %is.normal.inf = fcmp oge half %fabs, 0xH0400
837  %is.ord = fcmp ord half %x, 0xH0000
838  %or = or i1 %is.normal.inf, %is.ord
839  ret i1 %or
840}
841
842; -> ord
843define i1 @ord_or_isnormalinf(half %x) #0 {
844; CHECK-LABEL: @ord_or_isnormalinf(
845; CHECK-NEXT:    [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
846; CHECK-NEXT:    ret i1 [[OR]]
847;
848  %fabs = call half @llvm.fabs.f16(half %x)
849  %is.normal.inf = fcmp oge half %fabs, 0xH0400
850  %is.ord = fcmp ord half %x, 0xH0000
851  %or = or i1 %is.ord, %is.normal.inf
852  ret i1 %or
853}
854
855; No fabs
856; -> iszero
857define i1 @une_or_oge_smallest_normal(half %x) #0 {
858; CHECK-LABEL: @une_or_oge_smallest_normal(
859; CHECK-NEXT:    [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH0000
860; CHECK-NEXT:    ret i1 [[OR]]
861;
862  %is.normal.inf = fcmp oge half %x, 0xH0400
863  %is.une = fcmp une half %x, 0xH0000
864  %or = or i1 %is.une, %is.normal.inf
865  ret i1 %or
866}
867
868; -> normal | inf
869define i1 @isnormalinf_or_inf(half %x) #0 {
870; CHECK-LABEL: @isnormalinf_or_inf(
871; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)
872; CHECK-NEXT:    ret i1 [[OR]]
873;
874  %fabs = call half @llvm.fabs.f16(half %x)
875  %is.normal.inf = fcmp oge half %fabs, 0xH0400
876  %is.inf = fcmp oeq half %fabs, 0xH7C00
877  %or = or i1 %is.normal.inf, %is.inf
878  ret i1 %or
879}
880
881; -> pinf | pnormal
882define i1 @posisnormalinf_or_posinf(half %x) #0 {
883; CHECK-LABEL: @posisnormalinf_or_posinf(
884; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)
885; CHECK-NEXT:    ret i1 [[OR]]
886;
887  %fabs = call half @llvm.fabs.f16(half %x)
888  %is.pos.normal.inf = fcmp oge half %x, 0xH0400
889  %is.inf = fcmp oeq half %fabs, 0xH7C00
890  %or = or i1 %is.pos.normal.inf, %is.inf
891  ret i1 %or
892}
893
894; -> normal | inf
895define i1 @isnormalinf_or_posinf(half %x) #0 {
896; CHECK-LABEL: @isnormalinf_or_posinf(
897; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)
898; CHECK-NEXT:    ret i1 [[OR]]
899;
900  %fabs = call half @llvm.fabs.f16(half %x)
901  %is.normal.inf = fcmp oge half %fabs, 0xH0400
902  %is.pos.inf = fcmp oeq half %x, 0xH7C00
903  %or = or i1 %is.normal.inf, %is.pos.inf
904  ret i1 %or
905}
906
907; -> pinf|ninf
908define i1 @isnormalinf_and_inf(half %x) #0 {
909; CHECK-LABEL: @isnormalinf_and_inf(
910; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
911; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
912; CHECK-NEXT:    ret i1 [[AND]]
913;
914  %fabs = call half @llvm.fabs.f16(half %x)
915  %is.normal.inf = fcmp oge half %fabs, 0xH0400
916  %is.inf = fcmp oeq half %fabs, 0xH7C00
917  %and = and i1 %is.normal.inf, %is.inf
918  ret i1 %and
919}
920
921; -> pinf
922define i1 @posisnormalinf_and_posinf(half %x) #0 {
923; CHECK-LABEL: @posisnormalinf_and_posinf(
924; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
925; CHECK-NEXT:    ret i1 [[AND]]
926;
927  %fabs = call half @llvm.fabs.f16(half %x)
928  %is.pos.normal.inf = fcmp oge half %x, 0xH0400
929  %is.inf = fcmp oeq half %fabs, 0xH7C00
930  %and = and i1 %is.pos.normal.inf, %is.inf
931  ret i1 %and
932}
933
934; -> pinf
935define i1 @isnormalinf_and_posinf(half %x) #0 {
936; CHECK-LABEL: @isnormalinf_and_posinf(
937; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
938; CHECK-NEXT:    ret i1 [[AND]]
939;
940  %fabs = call half @llvm.fabs.f16(half %x)
941  %is.normal.inf = fcmp oge half %fabs, 0xH0400
942  %is.pos.inf = fcmp oeq half %x, 0xH7C00
943  %and = and i1 %is.normal.inf, %is.pos.inf
944  ret i1 %and
945}
946
947; --------------------------------------------------------------------
948; smallest_normal check part of isnormal(x) with inverted compare
949; --------------------------------------------------------------------
950
951; -> true
952define i1 @not_isnormalinf_or_ord(half %x) #0 {
953; CHECK-LABEL: @not_isnormalinf_or_ord(
954; CHECK-NEXT:    ret i1 true
955;
956  %fabs = call half @llvm.fabs.f16(half %x)
957  %not.is.normal.inf = fcmp ult half %fabs, 0xH0400
958  %is.ord = fcmp ord half %x, 0xH0000
959  %or = or i1 %not.is.normal.inf, %is.ord
960  ret i1 %or
961}
962
963; -> subnormal | zero
964define i1 @not_isnormalinf_and_ord(half %x) #0 {
965; CHECK-LABEL: @not_isnormalinf_and_ord(
966; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
967; CHECK-NEXT:    ret i1 [[AND]]
968;
969  %fabs = call half @llvm.fabs.f16(half %x)
970  %not.is.normal.inf = fcmp ult half %fabs, 0xH0400
971  %is.ord = fcmp ord half %x, 0xH0000
972  %and = and i1 %not.is.normal.inf, %is.ord
973  ret i1 %and
974}
975
976; -> ~ninf
977define i1 @not_isnormalinf_or_inf(half %x) #0 {
978; CHECK-LABEL: @not_isnormalinf_or_inf(
979; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
980; CHECK-NEXT:    [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
981; CHECK-NEXT:    ret i1 [[OR]]
982;
983  %fabs = call half @llvm.fabs.f16(half %x)
984  %not.is.normal.inf = fcmp ult half %fabs, 0xH0400
985  %is.inf = fcmp olt half %fabs, 0xH7C00
986  %or = or i1 %not.is.normal.inf, %is.inf
987  ret i1 %or
988}
989
990; -> subnormal | zero | nan
991define i1 @not_isnormalinf_or_uno(half %x) #0 {
992; CHECK-LABEL: @not_isnormalinf_or_uno(
993; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
994; CHECK-NEXT:    [[OR:%.*]] = fcmp ult half [[FABS]], 0xH0400
995; CHECK-NEXT:    ret i1 [[OR]]
996;
997  %fabs = call half @llvm.fabs.f16(half %x)
998  %not.is.normal.inf = fcmp ult half %fabs, 0xH0400
999  %is.uno = fcmp uno half %fabs, 0.0
1000  %or = or i1 %not.is.normal.inf, %is.uno
1001  ret i1 %or
1002}
1003
1004; -> subnormal | zero | nan
1005define i1 @not_isnormalinf_or_uno_nofabs(half %x) #0 {
1006; CHECK-LABEL: @not_isnormalinf_or_uno_nofabs(
1007; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1008; CHECK-NEXT:    [[OR:%.*]] = fcmp ult half [[FABS]], 0xH0400
1009; CHECK-NEXT:    ret i1 [[OR]]
1010;
1011  %fabs = call half @llvm.fabs.f16(half %x)
1012  %not.is.normal.inf = fcmp ult half %fabs, 0xH0400
1013  %is.uno = fcmp uno half %x, 0.0
1014  %or = or i1 %not.is.normal.inf, %is.uno
1015  ret i1 %or
1016}
1017
1018; -> ~pnormal
1019define i1 @not_negisnormalinf_or_inf(half %x) #0 {
1020; CHECK-LABEL: @not_negisnormalinf_or_inf(
1021; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
1022; CHECK-NEXT:    ret i1 [[OR]]
1023;
1024  %fabs = call half @llvm.fabs.f16(half %x)
1025  %not.is.neg.normal.inf = fcmp ult half %x, 0xH0400
1026  %is.inf = fcmp oeq half %fabs, 0xH7C00
1027  %or = or i1 %not.is.neg.normal.inf, %is.inf
1028  ret i1 %or
1029}
1030
1031; -> ~pnormal
1032define i1 @not_negisnormalinf_or_posinf(half %x) #0 {
1033; CHECK-LABEL: @not_negisnormalinf_or_posinf(
1034; CHECK-NEXT:    [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
1035; CHECK-NEXT:    ret i1 [[OR]]
1036;
1037  %not.is.pos.normal.inf = fcmp ult half %x, 0xH0400
1038  %is.inf = fcmp oeq half %x, 0xH7C00
1039  %or = or i1 %not.is.pos.normal.inf, %is.inf
1040  ret i1 %or
1041}
1042
1043; -> ninf | nnormal
1044define i1 @not_isposnormalinf_and_isnormalinf(half %x) #0 {
1045; CHECK-LABEL: @not_isposnormalinf_and_isnormalinf(
1046; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 12)
1047; CHECK-NEXT:    ret i1 [[AND]]
1048;
1049  %not.is.pos.normal.inf = fcmp ult half %x, 0xH0400
1050  %fabs = call half @llvm.fabs.f16(half %x)
1051  %is.normal.inf = fcmp oge half %fabs, 0xH0400
1052  %and = and i1 %not.is.pos.normal.inf, %is.normal.inf
1053  ret i1 %and
1054}
1055
1056; -> ord
1057define i1 @olt_smallest_normal_or_ord(half %x) #0 {
1058; CHECK-LABEL: @olt_smallest_normal_or_ord(
1059; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1060; CHECK-NEXT:    ret i1 [[CLASS]]
1061;
1062  %ord = fcmp ord half %x, 0.0
1063  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1064  %class = or i1 %cmp.smallest.normal, %ord
1065  ret i1 %class
1066}
1067
1068; -> ~pinf
1069define i1 @olt_smallest_normal_or_uno(half %x) #0 {
1070; CHECK-LABEL: @olt_smallest_normal_or_uno(
1071; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)
1072; CHECK-NEXT:    ret i1 [[CLASS]]
1073;
1074  %uno = fcmp uno half %x, 0.0
1075  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1076  %class = or i1 %cmp.smallest.normal, %uno
1077  ret i1 %class
1078}
1079
1080define i1 @olt_smallest_normal_or_finite(half %x) #0 {
1081; CHECK-LABEL: @olt_smallest_normal_or_finite(
1082; CHECK-NEXT:    [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
1083; CHECK-NEXT:    ret i1 [[CLASS]]
1084;
1085  %fabs = call half @llvm.fabs.f16(half %x)
1086  %is.finite = fcmp olt half %fabs, 0xH7C00
1087  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1088  %class = or i1 %cmp.smallest.normal, %is.finite
1089  ret i1 %class
1090}
1091
1092define i1 @uge_smallest_normal_or_ord(half %x) #0 {
1093; CHECK-LABEL: @uge_smallest_normal_or_ord(
1094; CHECK-NEXT:    ret i1 true
1095;
1096  %ord = fcmp ord half %x, 0.0
1097  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1098  %class = or i1 %cmp.smallest.normal, %ord
1099  ret i1 %class
1100}
1101
1102; -> nan | pnormal | pinf
1103define i1 @uge_smallest_normal_or_uno(half %x) #0 {
1104; CHECK-LABEL: @uge_smallest_normal_or_uno(
1105; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp uge half [[X:%.*]], 0xH0400
1106; CHECK-NEXT:    ret i1 [[CMP_SMALLEST_NORMAL]]
1107;
1108  %uno = fcmp uno half %x, 0.0
1109  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1110  %class = or i1 %cmp.smallest.normal, %uno
1111  ret i1 %class
1112}
1113
1114; -> uno
1115define i1 @uge_smallest_normal_and_uno(half %x) #0 {
1116; CHECK-LABEL: @uge_smallest_normal_and_uno(
1117; CHECK-NEXT:    [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
1118; CHECK-NEXT:    ret i1 [[CLASS]]
1119;
1120  %uno = fcmp uno half %x, 0.0
1121  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1122  %class = and i1 %cmp.smallest.normal, %uno
1123  ret i1 %class
1124}
1125
1126; -> true
1127define i1 @olt_infinity_or_finite(half %x) #0 {
1128; CHECK-LABEL: @olt_infinity_or_finite(
1129; CHECK-NEXT:    [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
1130; CHECK-NEXT:    ret i1 [[CLASS]]
1131;
1132  %lt.infinity = fcmp olt half %x, 0xH7C00
1133  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1134  %class = or i1 %cmp.smallest.normal, %lt.infinity
1135  ret i1 %class
1136}
1137
1138; -> zero|subnormal|normal
1139define i1 @olt_infinity_and_finite(half %x) #0 { ; bustttedddd
1140; CHECK-LABEL: @olt_infinity_and_finite(
1141; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
1142; CHECK-NEXT:    ret i1 [[CLASS]]
1143;
1144  %lt.infinity = fcmp olt half %x, 0xH7C00
1145  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1146  %class = and i1 %cmp.smallest.normal, %lt.infinity
1147  ret i1 %class
1148}
1149
1150; -> ord
1151define i1 @olt_infinity_or_ord(half %x) #0 {
1152; CHECK-LABEL: @olt_infinity_or_ord(
1153; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1154; CHECK-NEXT:    ret i1 [[CLASS]]
1155;
1156  %lt.infinity = fcmp olt half %x, 0xH7C00
1157  %ord = fcmp ord half %x, 0xH0400
1158  %class = or i1 %lt.infinity, %ord
1159  ret i1 %class
1160}
1161
1162; -> ~posinf
1163define i1 @olt_infinity_or_uno(half %x) #0 {
1164; CHECK-LABEL: @olt_infinity_or_uno(
1165; CHECK-NEXT:    [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
1166; CHECK-NEXT:    ret i1 [[CLASS]]
1167;
1168  %lt.infinity = fcmp olt half %x, 0xH7C00
1169  %uno = fcmp uno half %x, 0xH0400
1170  %class = or i1 %lt.infinity, %uno
1171  ret i1 %class
1172}
1173
1174define i1 @olt_infinity_or_subnormal(half %x) #0 {
1175; CHECK-LABEL: @olt_infinity_or_subnormal(
1176; CHECK-NEXT:    [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
1177; CHECK-NEXT:    ret i1 [[CLASS]]
1178;
1179  %lt.infinity = fcmp olt half %x, 0xH7C00
1180  %fabs = call half @llvm.fabs.f16(half %x)
1181  %is.subnormal = fcmp olt half %fabs, 0xH0400
1182  %class = or i1 %lt.infinity, %is.subnormal
1183  ret i1 %class
1184}
1185
1186define i1 @olt_infinity_and_subnormal(half %x) #0 {
1187; CHECK-LABEL: @olt_infinity_and_subnormal(
1188; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
1189; CHECK-NEXT:    ret i1 [[CLASS]]
1190;
1191  %lt.infinity = fcmp olt half %x, 0xH7C00
1192  %fabs = call half @llvm.fabs.f16(half %x)
1193  %is.subnormal = fcmp olt half %fabs, 0xH0400
1194  %class = and i1 %lt.infinity, %is.subnormal
1195  ret i1 %class
1196}
1197
1198define i1 @olt_infinity_and_not_subnormal(half %x) #0 {
1199; CHECK-LABEL: @olt_infinity_and_not_subnormal(
1200; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 268)
1201; CHECK-NEXT:    ret i1 [[CLASS]]
1202;
1203  %lt.infinity = fcmp olt half %x, 0xH7C00
1204  %fabs = call half @llvm.fabs.f16(half %x)
1205  %is.subnormal = fcmp olt half %fabs, 0xH0400
1206  %not.subnormal = xor i1 %is.subnormal, true
1207  %class = and i1 %lt.infinity, %not.subnormal
1208  ret i1 %class
1209}
1210
1211; -> ninf
1212define i1 @olt_infinity_and_ueq_inf(half %x) #0 {
1213; CHECK-LABEL: @olt_infinity_and_ueq_inf(
1214; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1215; CHECK-NEXT:    ret i1 [[CLASS]]
1216;
1217  %lt.infinity = fcmp olt half %x, 0xH7C00
1218  %fabs = call half @llvm.fabs.f16(half %x)
1219  %eq.inf = fcmp ueq half %fabs, 0xH7C00
1220  %class = and i1 %lt.infinity, %eq.inf
1221  ret i1 %class
1222}
1223
1224; -> true
1225define i1 @olt_infinity_or_ueq_inf(half %x) #0 {
1226; CHECK-LABEL: @olt_infinity_or_ueq_inf(
1227; CHECK-NEXT:    ret i1 true
1228;
1229  %lt.infinity = fcmp olt half %x, 0xH7C00
1230  %eq.inf = fcmp ueq half %x, 0xH7C00
1231  %class = or i1 %lt.infinity, %eq.inf
1232  ret i1 %class
1233}
1234
1235; -> pnormal
1236define i1 @olt_smallest_normal_or_ueq_inf(half %x) #0 {
1237; CHECK-LABEL: @olt_smallest_normal_or_ueq_inf(
1238; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
1239; CHECK-NEXT:    ret i1 [[CLASS]]
1240;
1241  %lt.normal = fcmp olt half %x, 0xH0400
1242  %eq.inf = fcmp ueq half %x, 0xH7C00
1243  %class = or i1 %lt.normal, %eq.inf
1244  ret i1 %class
1245}
1246
1247; -> ~pinf
1248define i1 @olt_smallest_normal_or_une_inf(half %x) #0 {
1249; CHECK-LABEL: @olt_smallest_normal_or_une_inf(
1250; CHECK-NEXT:    [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
1251; CHECK-NEXT:    ret i1 [[CLASS]]
1252;
1253  %lt.normal = fcmp olt half %x, 0xH0400
1254  %eq.inf = fcmp une half %x, 0xH7C00
1255  %class = or i1 %lt.normal, %eq.inf
1256  ret i1 %class
1257}
1258
1259; -> ninf | nnormal | subnormal | zero
1260define i1 @olt_smallest_normal_and_une_inf(half %x) #0 {
1261; CHECK-LABEL: @olt_smallest_normal_and_une_inf(
1262; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
1263; CHECK-NEXT:    ret i1 [[CLASS]]
1264;
1265  %lt.normal = fcmp olt half %x, 0xH0400
1266  %eq.inf = fcmp une half %x, 0xH7C00
1267  %class = and i1 %lt.normal, %eq.inf
1268  ret i1 %class
1269}
1270
1271define i1 @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(half %x) #0 {
1272; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(
1273; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
1274; CHECK-NEXT:    ret i1 [[CLASS]]
1275;
1276  %lt.normal = fcmp olt half %x, 0xH0400
1277  %eq.inf = fcmp une half %x, 0xH7C00
1278  %class = and i1 %lt.normal, %eq.inf
1279  %eq.normal = fcmp oeq half %x, 0xH0400
1280  %eq.largest.normal = or i1 %eq.normal, %class
1281  ret i1 %class
1282}
1283
1284define i1 @olt_smallest_normal_and_une_inf_or_one_smallest_normal(half %x) #0 {
1285; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_one_smallest_normal(
1286; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
1287; CHECK-NEXT:    ret i1 [[CLASS]]
1288;
1289  %lt.normal = fcmp olt half %x, 0xH0400
1290  %eq.inf = fcmp une half %x, 0xH7C00
1291  %class = and i1 %lt.normal, %eq.inf
1292  %ne.normal = fcmp one half %x, 0xH0400
1293  %eq.largest.normal = or i1 %ne.normal, %class
1294  ret i1 %class
1295}
1296
1297define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 {
1298; CHECK-LABEL: @oge_fabs_eq_inf_and_ord(
1299; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1300; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
1301; CHECK-NEXT:    ret i1 [[AND]]
1302;
1303  %fabs = call half @llvm.fabs.f16(half %x)
1304  %oge.fabs.inf = fcmp oge half %fabs, 0xH7C00
1305  %ord = fcmp ord half %x, 0xH0000
1306  %and = and i1 %oge.fabs.inf, %ord
1307  ret i1 %and
1308}
1309
1310define i1 @oge_eq_inf_and_ord(half %x) #0 {
1311; CHECK-LABEL: @oge_eq_inf_and_ord(
1312; CHECK-NEXT:    [[OGE_FABS_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
1313; CHECK-NEXT:    ret i1 [[OGE_FABS_INF]]
1314;
1315  %oge.fabs.inf = fcmp oge half %x, 0xH7C00
1316  %ord = fcmp ord half %x, 0xH0000
1317  %and = and i1 %oge.fabs.inf, %ord
1318  ret i1 %and
1319}
1320
1321define i1 @oge_fabs_eq_inf_or_uno(half %x) #0 {
1322; CHECK-LABEL: @oge_fabs_eq_inf_or_uno(
1323; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1324; CHECK-NEXT:    [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
1325; CHECK-NEXT:    ret i1 [[OR]]
1326;
1327  %fabs = call half @llvm.fabs.f16(half %x)
1328  %oge.fabs.inf = fcmp oge half %fabs, 0xH7C00
1329  %uno = fcmp uno half %x, 0xH0000
1330  %or = or i1 %oge.fabs.inf, %uno
1331  ret i1 %or
1332}
1333
1334define i1 @oge_eq_inf_or_uno(half %x) #0 {
1335; CHECK-LABEL: @oge_eq_inf_or_uno(
1336; CHECK-NEXT:    [[OR:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
1337; CHECK-NEXT:    ret i1 [[OR]]
1338;
1339  %oge.fabs.inf = fcmp oge half %x, 0xH7C00
1340  %uno = fcmp uno half %x, 0xH0000
1341  %or = or i1 %oge.fabs.inf, %uno
1342  ret i1 %or
1343}
1344
1345define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 {
1346; CHECK-LABEL: @ult_fabs_eq_inf_and_ord(
1347; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1348; CHECK-NEXT:    [[AND:%.*]] = fcmp one half [[FABS]], 0xH7C00
1349; CHECK-NEXT:    ret i1 [[AND]]
1350;
1351  %fabs = call half @llvm.fabs.f16(half %x)
1352  %ult.fabs.inf = fcmp ult half %fabs, 0xH7C00
1353  %ord = fcmp ord half %x, 0xH0000
1354  %and = and i1 %ult.fabs.inf, %ord
1355  ret i1 %and
1356}
1357
1358define i1 @ult_eq_inf_and_ord(half %x) #0 {
1359; CHECK-LABEL: @ult_eq_inf_and_ord(
1360; CHECK-NEXT:    [[AND:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
1361; CHECK-NEXT:    ret i1 [[AND]]
1362;
1363  %ult.fabs.inf = fcmp ult half %x, 0xH7C00
1364  %ord = fcmp ord half %x, 0xH0000
1365  %and = and i1 %ult.fabs.inf, %ord
1366  ret i1 %and
1367}
1368
1369define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 {
1370; CHECK-LABEL: @ult_fabs_eq_inf_or_uno(
1371; CHECK-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1372; CHECK-NEXT:    [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
1373; CHECK-NEXT:    ret i1 [[OR]]
1374;
1375  %fabs = call half @llvm.fabs.f16(half %x)
1376  %ult.fabs.inf = fcmp ult half %fabs, 0xH7C00
1377  %uno = fcmp uno half %x, 0xH0000
1378  %or = or i1 %ult.fabs.inf, %uno
1379  ret i1 %or
1380}
1381
1382define i1 @ult_eq_inf_or_uno(half %x) #0 {
1383; CHECK-LABEL: @ult_eq_inf_or_uno(
1384; CHECK-NEXT:    [[ULT_FABS_INF:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
1385; CHECK-NEXT:    ret i1 [[ULT_FABS_INF]]
1386;
1387  %ult.fabs.inf = fcmp ult half %x, 0xH7C00
1388  %uno = fcmp uno half %x, 0xH0000
1389  %or = or i1 %ult.fabs.inf, %uno
1390  ret i1 %or
1391}
1392
1393
1394; Can't do anything with this
1395define i1 @oeq_neginfinity_or_oeq_smallest_normal(half %x) #0 {
1396; CHECK-LABEL: @oeq_neginfinity_or_oeq_smallest_normal(
1397; CHECK-NEXT:    [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1398; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400
1399; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[OEQ_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]
1400; CHECK-NEXT:    ret i1 [[CLASS]]
1401;
1402  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1403  %cmp.smallest.normal = fcmp oeq half %x, 0xH0400
1404  %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
1405  ret i1 %class
1406}
1407
1408; -> ninf | fcZero | fcSubnormal
1409define i1 @oeq_neginfinity_or_olt_smallest_normal(half %x) #0 {
1410; CHECK-LABEL: @oeq_neginfinity_or_olt_smallest_normal(
1411; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
1412; CHECK-NEXT:    ret i1 [[CLASS]]
1413;
1414  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1415  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1416  %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
1417  ret i1 %class
1418}
1419
1420; -> ninf
1421define i1 @oeq_neginfinity_and_olt_smallest_normal(half %x) #0 {
1422; CHECK-LABEL: @oeq_neginfinity_and_olt_smallest_normal(
1423; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1424; CHECK-NEXT:    ret i1 [[CLASS]]
1425;
1426  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1427  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1428  %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal
1429  ret i1 %class
1430}
1431
1432; -> ninf | pnormal | pinf
1433define i1 @oeq_neginfinity_or_oge_smallest_normal(half %x) #0 {
1434; CHECK-LABEL: @oeq_neginfinity_or_oge_smallest_normal(
1435; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)
1436; CHECK-NEXT:    ret i1 [[CLASS]]
1437;
1438  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1439  %cmp.smallest.normal = fcmp oge half %x, 0xH0400
1440  %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
1441  ret i1 %class
1442}
1443
1444; -> false
1445define i1 @oeq_neginfinity_and_oge_smallest_normal(half %x) #0 {
1446; CHECK-LABEL: @oeq_neginfinity_and_oge_smallest_normal(
1447; CHECK-NEXT:    ret i1 false
1448;
1449  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1450  %cmp.smallest.normal = fcmp oge half %x, 0xH0400
1451  %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal
1452  ret i1 %class
1453}
1454
1455; -> ord
1456define i1 @oeq_neginfinity_or_ord(half %x) #0 {
1457; CHECK-LABEL: @oeq_neginfinity_or_ord(
1458; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1459; CHECK-NEXT:    ret i1 [[CLASS]]
1460;
1461  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1462  %ord = fcmp ord half %x, 0.0
1463  %class = or i1 %oeq.neg.infinity, %ord
1464  ret i1 %class
1465}
1466
1467; -> ninf
1468define i1 @oeq_neginfinity_and_ord(half %x) #0 {
1469; CHECK-LABEL: @oeq_neginfinity_and_ord(
1470; CHECK-NEXT:    [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1471; CHECK-NEXT:    ret i1 [[OEQ_NEG_INFINITY]]
1472;
1473  %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
1474  %ord = fcmp ord half %x, 0.0
1475  %class = and i1 %oeq.neg.infinity, %ord
1476  ret i1 %class
1477}
1478
1479; can't do anything with this
1480define i1 @une_neginfinity_or_oeq_smallest_normal(half %x) #0 {
1481; CHECK-LABEL: @une_neginfinity_or_oeq_smallest_normal(
1482; CHECK-NEXT:    [[UNE_NEG_INFINITY:%.*]] = fcmp une half [[X:%.*]], 0xHFC00
1483; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400
1484; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[UNE_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]
1485; CHECK-NEXT:    ret i1 [[CLASS]]
1486;
1487  %une.neg.infinity = fcmp une half %x, 0xHFC00
1488  %cmp.smallest.normal = fcmp oeq half %x, 0xH0400
1489  %class = or i1 %une.neg.infinity, %cmp.smallest.normal
1490  ret i1 %class
1491}
1492
1493; -> true
1494define i1 @une_neginfinity_or_ord(half %x) #0 {
1495; CHECK-LABEL: @une_neginfinity_or_ord(
1496; CHECK-NEXT:    ret i1 true
1497;
1498  %une.neg.infinity = fcmp une half %x, 0xHFC00
1499  %ord = fcmp ord half %x, 0.0
1500  %class = or i1 %une.neg.infinity, %ord
1501  ret i1 %class
1502}
1503
1504; -> ~(nan | ninf)
1505define i1 @une_neginfinity_and_ord(half %x) #0 {
1506; CHECK-LABEL: @une_neginfinity_and_ord(
1507; CHECK-NEXT:    [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xHFC00
1508; CHECK-NEXT:    ret i1 [[CLASS]]
1509;
1510  %une.neg.infinity = fcmp une half %x, 0xHFC00
1511  %ord = fcmp ord half %x, 0.0
1512  %class = and i1 %une.neg.infinity, %ord
1513  ret i1 %class
1514}
1515
1516; -> ord
1517define i1 @one_neginfinity_or_olt_smallest_normal(half %x) #0 {
1518; CHECK-LABEL: @one_neginfinity_or_olt_smallest_normal(
1519; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1520; CHECK-NEXT:    ret i1 [[CLASS]]
1521;
1522  %one.neg.infinity = fcmp one half %x, 0xHFC00
1523  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1524  %class = or i1 %one.neg.infinity, %cmp.smallest.normal
1525  ret i1 %class
1526}
1527
1528; -> ~(nan|ninf)
1529define i1 @one_neginfinity_and_olt_smallest_normal(half %x) #0 {
1530; CHECK-LABEL: @one_neginfinity_and_olt_smallest_normal(
1531; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 248)
1532; CHECK-NEXT:    ret i1 [[CLASS]]
1533;
1534  %one.neg.infinity = fcmp one half %x, 0xHFC00
1535  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1536  %class = and i1 %one.neg.infinity, %cmp.smallest.normal
1537  ret i1 %class
1538}
1539
1540; -> ~ninf
1541define i1 @one_neginfinity_or_uno(half %x) #0 {
1542; CHECK-LABEL: @one_neginfinity_or_uno(
1543; CHECK-NEXT:    [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xHFC00
1544; CHECK-NEXT:    ret i1 [[CLASS]]
1545;
1546  %one.neg.infinity = fcmp one half %x, 0xHFC00
1547  %uno = fcmp uno half %x, 0.0
1548  %class = or i1 %one.neg.infinity, %uno
1549  ret i1 %class
1550}
1551
1552; -> ~ninf
1553define i1 @one_neginfinity_and_ord(half %x) #0 {
1554; CHECK-LABEL: @one_neginfinity_and_ord(
1555; CHECK-NEXT:    ret i1 false
1556;
1557  %one.neg.infinity = fcmp one half %x, 0xHFC00
1558  %ord = fcmp uno half %x, 0.0
1559  %class = and i1 %one.neg.infinity, %ord
1560  ret i1 %class
1561}
1562
1563; -> pnormal|pinf
1564define i1 @one_neginfinity_and_uge_smallest_normal(half %x) #0 {
1565; CHECK-LABEL: @one_neginfinity_and_uge_smallest_normal(
1566; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)
1567; CHECK-NEXT:    ret i1 [[CLASS]]
1568;
1569  %one.neg.infinity = fcmp one half %x, 0xHFC00
1570  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1571  %class = and i1 %one.neg.infinity, %cmp.smallest.normal
1572  ret i1 %class
1573}
1574
1575; -> ~(pnormal|pinf)
1576define i1 @ueq_neginfinity_or_olt_smallest_normal(half %x) #0 {
1577; CHECK-LABEL: @ueq_neginfinity_or_olt_smallest_normal(
1578; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)
1579; CHECK-NEXT:    ret i1 [[CLASS]]
1580;
1581  %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
1582  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1583  %class = or i1 %ueq.neg.infinity, %cmp.smallest.normal
1584  ret i1 %class
1585}
1586
1587; -> ninf
1588define i1 @ueq_neginfinity_and_olt_smallest_normal(half %x) #0 {
1589; CHECK-LABEL: @ueq_neginfinity_and_olt_smallest_normal(
1590; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1591; CHECK-NEXT:    ret i1 [[CLASS]]
1592;
1593  %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
1594  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1595  %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal
1596  ret i1 %class
1597}
1598
1599; -> nan|ninf
1600define i1 @ueq_neginfinity_or_uno(half %x) #0 {
1601; CHECK-LABEL: @ueq_neginfinity_or_uno(
1602; CHECK-NEXT:    [[UEQ_NEG_INFINITY:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
1603; CHECK-NEXT:    ret i1 [[UEQ_NEG_INFINITY]]
1604;
1605  %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
1606  %uno = fcmp uno half %x, 0.0
1607  %class = or i1 %ueq.neg.infinity, %uno
1608  ret i1 %class
1609}
1610
1611; -> nan|ninf
1612define i1 @ueq_neginfinity_and_ord(half %x) #0 {
1613; CHECK-LABEL: @ueq_neginfinity_and_ord(
1614; CHECK-NEXT:    [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
1615; CHECK-NEXT:    ret i1 [[CLASS]]
1616;
1617  %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
1618  %ord = fcmp uno half %x, 0.0
1619  %class = and i1 %ueq.neg.infinity, %ord
1620  ret i1 %class
1621}
1622
1623; -> uno
1624define i1 @ueq_neginfinity_and_uge_smallest_normal(half %x) #0 {
1625; CHECK-LABEL: @ueq_neginfinity_and_uge_smallest_normal(
1626; CHECK-NEXT:    [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
1627; CHECK-NEXT:    ret i1 [[CLASS]]
1628;
1629  %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
1630  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1631  %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal
1632  ret i1 %class
1633}
1634
1635; -> ord
1636define i1 @fabs_oeq_neginfinity_or_ord(half %x) #0 {
1637; CHECK-LABEL: @fabs_oeq_neginfinity_or_ord(
1638; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1639; CHECK-NEXT:    ret i1 [[ORD]]
1640;
1641  %fabs = call half @llvm.fabs.f16(half %x)
1642  %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
1643  %ord = fcmp ord half %x, 0.0
1644  %class = or i1 %fabs.oeq.neg.infinity, %ord
1645  ret i1 %class
1646}
1647
1648; -> true
1649define i1 @fabs_une_neginfinity_or_ord(half %x) #0 {
1650; CHECK-LABEL: @fabs_une_neginfinity_or_ord(
1651; CHECK-NEXT:    ret i1 true
1652;
1653  %fabs = call half @llvm.fabs.f16(half %x)
1654  %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00
1655  %ord = fcmp une half %x, 0.0
1656  %class = or i1 %fabs.une.neg.infinity, %ord
1657  ret i1 %class
1658}
1659
1660; -> une
1661define i1 @fabs_une_neginfinity_and_ord(half %x) #0 {
1662; CHECK-LABEL: @fabs_une_neginfinity_and_ord(
1663; CHECK-NEXT:    [[ORD:%.*]] = fcmp une half [[X:%.*]], 0xH0000
1664; CHECK-NEXT:    ret i1 [[ORD]]
1665;
1666  %fabs = call half @llvm.fabs.f16(half %x)
1667  %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00
1668  %ord = fcmp une half %x, 0.0
1669  %class = and i1 %fabs.une.neg.infinity, %ord
1670  ret i1 %class
1671}
1672
1673; -> false
1674define i1 @fabs_oeq_neginfinity_and_uge_smallest_normal(half %x) #0 {
1675; CHECK-LABEL: @fabs_oeq_neginfinity_and_uge_smallest_normal(
1676; CHECK-NEXT:    ret i1 false
1677;
1678  %fabs = call half @llvm.fabs.f16(half %x)
1679  %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
1680  %cmp.smallest.normal = fcmp oeq half %x, 0xH0400
1681  %class = and i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
1682  ret i1 %class
1683}
1684
1685; -> false
1686define i1 @fabs_oeq_neginfinity_or_uge_smallest_normal(half %x) #0 {
1687; CHECK-LABEL: @fabs_oeq_neginfinity_or_uge_smallest_normal(
1688; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X:%.*]], 0xH0400
1689; CHECK-NEXT:    ret i1 [[CMP_SMALLEST_NORMAL]]
1690;
1691  %fabs = call half @llvm.fabs.f16(half %x)
1692  %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
1693  %cmp.smallest.normal = fcmp oeq half %x, 0xH0400
1694  %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
1695  ret i1 %class
1696}
1697
1698;- > ord
1699define i1 @fabs_oeq_neginfinity_and_ord(half %x) #0 {
1700; CHECK-LABEL: @fabs_oeq_neginfinity_and_ord(
1701; CHECK-NEXT:    ret i1 false
1702;
1703  %fabs = call half @llvm.fabs.f16(half %x)
1704  %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
1705  %ord = fcmp ord half %x, 0.0
1706  %class = and i1 %fabs.oeq.neg.infinity, %ord
1707  ret i1 %class
1708}
1709
1710; -> false
1711define i1 @fabs_ueq_neginfinity_and_olt_smallest_normal(half %x) #0 { ; WRONG
1712; CHECK-LABEL: @fabs_ueq_neginfinity_and_olt_smallest_normal(
1713; CHECK-NEXT:    ret i1 false
1714;
1715  %fabs = call half @llvm.fabs.f16(half %x)
1716  %fabs.ueq.neg.infinity = fcmp ueq half %fabs, 0xHFC00
1717  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1718  %class = and i1 %fabs.ueq.neg.infinity, %cmp.smallest.normal
1719  ret i1 %class
1720}
1721
1722; -> pinf|pnormal
1723define i1 @fabs_one_neginfinity_and_uge_smallest_normal(half %x) #0 {
1724; CHECK-LABEL: @fabs_one_neginfinity_and_uge_smallest_normal(
1725; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)
1726; CHECK-NEXT:    ret i1 [[CLASS]]
1727;
1728  %fabs = call half @llvm.fabs.f16(half %x)
1729  %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00
1730  %cmp.smallest.normal = fcmp uge half %x, 0xH0400
1731  %class = and i1 %fabs.one.neg.infinity, %cmp.smallest.normal
1732  ret i1 %class
1733}
1734
1735; -> ord
1736define i1 @fabs_one_neginfinity_or_olt_smallest_normal(half %x) #0 {
1737; CHECK-LABEL: @fabs_one_neginfinity_or_olt_smallest_normal(
1738; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1739; CHECK-NEXT:    ret i1 [[CLASS]]
1740;
1741  %fabs = call half @llvm.fabs.f16(half %x)
1742  %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00
1743  %cmp.smallest.normal = fcmp olt half %x, 0xH0400
1744  %class = or i1 %fabs.one.neg.infinity, %cmp.smallest.normal
1745  ret i1 %class
1746}
1747
1748; -> ~(zero|subnormal)
1749define i1 @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(half %x) #0 {
1750; CHECK-LABEL: @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(
1751; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
1752; CHECK-NEXT:    ret i1 [[CLASS]]
1753;
1754  %fabs = call half @llvm.fabs.f16(half %x)
1755  %fabs.oeq.neg.infinity = fcmp ueq half %fabs, 0xHFC00
1756  %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
1757  %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
1758  ret i1 %class
1759}
1760
1761; --------------------------------------------------------------------
1762; Test denormal mode handling with x == 0
1763; --------------------------------------------------------------------
1764
1765; Base pattern !isfinite(x) || x == 0.0, with input denormals flushed to 0
1766define i1 @not_isfinite_or_zero_f16_daz(half %x) #1 {
1767; CHECK-LABEL: @not_isfinite_or_zero_f16_daz(
1768; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1769; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
1770; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
1771; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
1772; CHECK-NEXT:    ret i1 [[CLASS]]
1773;
1774  %fabs = call half @llvm.fabs.f16(half %x)
1775  %cmpinf = fcmp ueq half %fabs, 0xH7C00
1776  %cmpzero = fcmp oeq half %x, 0xH0000
1777  %class = or i1 %cmpzero, %cmpinf
1778  ret i1 %class
1779}
1780
1781define <2 x i1> @not_isfinite_or_zero_v2f16_daz(<2 x half> %x) #1 {
1782; CHECK-LABEL: @not_isfinite_or_zero_v2f16_daz(
1783; CHECK-NEXT:    [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
1784; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00)
1785; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
1786; CHECK-NEXT:    [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
1787; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
1788;
1789  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
1790  %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
1791  %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
1792  %class = or <2 x i1> %cmpzero, %cmpinf
1793  ret <2 x i1> %class
1794}
1795
1796; Base pattern !isfinite(x) || x == 0.0, with unknown input denormal treatment
1797define i1 @not_isfinite_or_zero_f16_dynamic(half %x) #2 {
1798; CHECK-LABEL: @not_isfinite_or_zero_f16_dynamic(
1799; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1800; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
1801; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
1802; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
1803; CHECK-NEXT:    ret i1 [[CLASS]]
1804;
1805  %fabs = call half @llvm.fabs.f16(half %x)
1806  %cmpinf = fcmp ueq half %fabs, 0xH7C00
1807  %cmpzero = fcmp oeq half %x, 0xH0000
1808  %class = or i1 %cmpzero, %cmpinf
1809  ret i1 %class
1810}
1811
1812define <2 x i1> @not_isfinite_or_zero_v2f16_dynamic(<2 x half> %x) #2 {
1813; CHECK-LABEL: @not_isfinite_or_zero_v2f16_dynamic(
1814; CHECK-NEXT:    [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
1815; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00)
1816; CHECK-NEXT:    [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
1817; CHECK-NEXT:    [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
1818; CHECK-NEXT:    ret <2 x i1> [[CLASS]]
1819;
1820  %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
1821  %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
1822  %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
1823  %class = or <2 x i1> %cmpzero, %cmpinf
1824  ret <2 x i1> %class
1825}
1826
1827define i1 @not_zero_and_subnormal_daz(half %x) #1 {
1828; CHECK-LABEL: @not_zero_and_subnormal_daz(
1829; CHECK-NEXT:    [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
1830; CHECK-NEXT:    ret i1 [[OR]]
1831;
1832  %fabs = call half @llvm.fabs.f16(half %x)
1833  %cmp.zero = fcmp one half %fabs, 0.0
1834  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
1835  %or = or i1 %cmp.smallest.normal, %cmp.zero
1836  ret i1 %or
1837}
1838
1839define i1 @not_zero_and_subnormal_dynamic(half %x) #2 {
1840; CHECK-LABEL: @not_zero_and_subnormal_dynamic(
1841; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1842; CHECK-NEXT:    [[CMP_ZERO:%.*]] = fcmp one half [[X]], 0xH0000
1843; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
1844; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMP_ZERO]]
1845; CHECK-NEXT:    ret i1 [[OR]]
1846;
1847  %fabs = call half @llvm.fabs.f16(half %x)
1848  %cmp.zero = fcmp one half %fabs, 0.0
1849  %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
1850  %or = or i1 %cmp.smallest.normal, %cmp.zero
1851  ret i1 %or
1852}
1853
1854; TODO: This could fold to just fcmp olt half %fabs, 0xH0400
1855define i1 @subnormal_or_zero_ieee(half %x) #0 {
1856; CHECK-LABEL: @subnormal_or_zero_ieee(
1857; CHECK-NEXT:    [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
1858; CHECK-NEXT:    ret i1 [[AND]]
1859;
1860  %fabs = call half @llvm.fabs.f16(half %x)
1861  %is.subnormal = fcmp olt half %fabs, 0xH0400
1862  %is.zero = fcmp oeq half %x, 0xH0000
1863  %and = or i1 %is.subnormal, %is.zero
1864  ret i1 %and
1865}
1866
1867define i1 @subnormal_or_zero_daz(half %x) #1 {
1868; CHECK-LABEL: @subnormal_or_zero_daz(
1869; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
1870; CHECK-NEXT:    ret i1 [[AND]]
1871;
1872  %fabs = call half @llvm.fabs.f16(half %x)
1873  %is.subnormal = fcmp olt half %fabs, 0xH0400
1874  %is.zero = fcmp oeq half %x, 0xH0000
1875  %and = or i1 %is.subnormal, %is.zero
1876  ret i1 %and
1877}
1878
1879define i1 @subnormal_or_zero_dynamic(half %x) #2 {
1880; CHECK-LABEL: @subnormal_or_zero_dynamic(
1881; CHECK-NEXT:    [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
1882; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
1883; CHECK-NEXT:    [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
1884; CHECK-NEXT:    [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]]
1885; CHECK-NEXT:    ret i1 [[AND]]
1886;
1887  %fabs = call half @llvm.fabs.f16(half %x)
1888  %is.subnormal = fcmp olt half %fabs, 0xH0400
1889  %is.zero = fcmp oeq half %x, 0xH0000
1890  %and = or i1 %is.subnormal, %is.zero
1891  ret i1 %and
1892}
1893
1894define i1 @issubnormal_or_inf_nnan_logical_select(half %x) {
1895; CHECK-LABEL: @issubnormal_or_inf_nnan_logical_select(
1896; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
1897; CHECK-NEXT:    ret i1 [[CLASS]]
1898;
1899  %fabs = call nnan half @llvm.fabs.f16(half %x)
1900  %cmpinf = fcmp nnan oeq half %fabs, 0xH7C00
1901  %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400
1902  %class = select i1 %cmpinf, i1 true, i1 %cmp.smallest.normal
1903  ret i1 %class
1904}
1905
1906define i1 @issubnormal_and_ninf_nnan_logical_select(half %x) {
1907; CHECK-LABEL: @issubnormal_and_ninf_nnan_logical_select(
1908; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
1909; CHECK-NEXT:    ret i1 [[CLASS]]
1910;
1911  %fabs = call nnan half @llvm.fabs.f16(half %x)
1912  %cmpinf = fcmp nnan one half %fabs, 0xH7C00
1913  %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400
1914  %class = select i1 %cmpinf, i1 %cmp.smallest.normal, i1 false
1915  ret i1 %class
1916}
1917
1918define i1 @fcmp_ueq_neginf_or_oge_zero_f16(half %x) {
1919; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16(
1920; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 999)
1921; CHECK-NEXT:    ret i1 [[CLASS]]
1922;
1923  %cmpinf = fcmp ueq half %x, 0xHFC00
1924  %cmp.oge.zero = fcmp oge half %x, 0xH0000
1925  %class = or i1 %cmp.oge.zero, %cmpinf
1926  ret i1 %class
1927}
1928
1929define i1 @fcmp_oeq_neginf_or_oge_zero_f16(half %x) {
1930; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16(
1931; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 996)
1932; CHECK-NEXT:    ret i1 [[CLASS]]
1933;
1934  %cmpinf = fcmp oeq half %x, 0xHFC00
1935  %cmp.oge.zero = fcmp oge half %x, 0xH0000
1936  %class = or i1 %cmp.oge.zero, %cmpinf
1937  ret i1 %class
1938}
1939
1940define i1 @fcmp_ueq_neginf_or_oge_zero_f16_daz(half %x) #1 {
1941; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16_daz(
1942; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
1943; CHECK-NEXT:    [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000
1944; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]
1945; CHECK-NEXT:    ret i1 [[CLASS]]
1946;
1947  %cmpinf = fcmp ueq half %x, 0xHFC00
1948  %cmp.oge.zero = fcmp oge half %x, 0xH0000
1949  %class = or i1 %cmp.oge.zero, %cmpinf
1950  ret i1 %class
1951}
1952
1953define i1 @fcmp_oeq_neginf_or_oge_zero_f16_daz(half %x) #1 {
1954; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16_daz(
1955; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
1956; CHECK-NEXT:    [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000
1957; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]
1958; CHECK-NEXT:    ret i1 [[CLASS]]
1959;
1960  %cmpinf = fcmp oeq half %x, 0xHFC00
1961  %cmp.oge.zero = fcmp oge half %x, 0xH0000
1962  %class = or i1 %cmp.oge.zero, %cmpinf
1963  ret i1 %class
1964}
1965
1966define i1 @fcmp_oeq_neginf_or_ogt_zero_f16(half %x) {
1967; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16(
1968; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 900)
1969; CHECK-NEXT:    ret i1 [[CLASS]]
1970;
1971  %cmpinf = fcmp oeq half %x, 0xHFC00
1972  %cmp.ogt.zero = fcmp ogt half %x, 0xH0000
1973  %class = or i1 %cmp.ogt.zero, %cmpinf
1974  ret i1 %class
1975}
1976
1977define i1 @fcmp_ueq_neginf_or_ogt_zero_f16(half %x) {
1978; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16(
1979; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)
1980; CHECK-NEXT:    ret i1 [[CLASS]]
1981;
1982  %cmpinf = fcmp ueq half %x, 0xHFC00
1983  %cmp.ogt.zero = fcmp ogt half %x, 0xH0000
1984  %class = or i1 %cmp.ogt.zero, %cmpinf
1985  ret i1 %class
1986}
1987
1988define i1 @fcmp_ueq_neginf_or_ogt_zero_f16_daz(half %x) #1 {
1989; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16_daz(
1990; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
1991; CHECK-NEXT:    [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000
1992; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]
1993; CHECK-NEXT:    ret i1 [[CLASS]]
1994;
1995  %cmpinf = fcmp ueq half %x, 0xHFC00
1996  %cmp.ogt.zero = fcmp ogt half %x, 0xH0000
1997  %class = or i1 %cmp.ogt.zero, %cmpinf
1998  ret i1 %class
1999}
2000
2001define i1 @fcmp_oeq_neginf_or_ogt_zero_f16_daz(half %x) #1 {
2002; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16_daz(
2003; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
2004; CHECK-NEXT:    [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000
2005; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]
2006; CHECK-NEXT:    ret i1 [[CLASS]]
2007;
2008  %cmpinf = fcmp oeq half %x, 0xHFC00
2009  %cmp.ogt.zero = fcmp ogt half %x, 0xH0000
2010  %class = or i1 %cmp.ogt.zero, %cmpinf
2011  ret i1 %class
2012}
2013
2014define i1 @fcmp_oeq_neginf_or_ugt_zero_f16(half %x) {
2015; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16(
2016; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)
2017; CHECK-NEXT:    ret i1 [[CLASS]]
2018;
2019  %cmpinf = fcmp oeq half %x, 0xHFC00
2020  %cmp.ugt.zero = fcmp ugt half %x, 0xH0000
2021  %class = or i1 %cmp.ugt.zero, %cmpinf
2022  ret i1 %class
2023}
2024
2025define i1 @fcmp_ueq_neginf_or_ugt_zero_f16_daz(half %x) #1 {
2026; CHECK-LABEL: @fcmp_ueq_neginf_or_ugt_zero_f16_daz(
2027; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
2028; CHECK-NEXT:    [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000
2029; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]
2030; CHECK-NEXT:    ret i1 [[CLASS]]
2031;
2032  %cmpinf = fcmp ueq half %x, 0xHFC00
2033  %cmp.ugt.zero = fcmp ugt half %x, 0xH0000
2034  %class = or i1 %cmp.ugt.zero, %cmpinf
2035  ret i1 %class
2036}
2037
2038define i1 @fcmp_oeq_neginf_or_ugt_zero_f16_daz(half %x) #1 {
2039; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16_daz(
2040; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
2041; CHECK-NEXT:    [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000
2042; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]
2043; CHECK-NEXT:    ret i1 [[CLASS]]
2044;
2045  %cmpinf = fcmp oeq half %x, 0xHFC00
2046  %cmp.ugt.zero = fcmp ugt half %x, 0xH0000
2047  %class = or i1 %cmp.ugt.zero, %cmpinf
2048  ret i1 %class
2049}
2050
2051define i1 @fcmp_ueq_posinf_or_ole_zero_f16(half %x) {
2052; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16(
2053; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)
2054; CHECK-NEXT:    ret i1 [[CLASS]]
2055;
2056  %cmpinf = fcmp ueq half %x, 0xH7C00
2057  %cmp.ole.zero = fcmp ole half %x, 0xH0000
2058  %class = or i1 %cmp.ole.zero, %cmpinf
2059  ret i1 %class
2060}
2061
2062define i1 @fcmp_oeq_posinf_or_ole_zero_f16(half %x) {
2063; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16(
2064; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 636)
2065; CHECK-NEXT:    ret i1 [[CLASS]]
2066;
2067  %cmpinf = fcmp oeq half %x, 0xH7C00
2068  %cmp.ole.zero = fcmp ole half %x, 0xH0000
2069  %class = or i1 %cmp.ole.zero, %cmpinf
2070  ret i1 %class
2071}
2072
2073define i1 @fcmp_ueq_posinf_or_ole_zero_f16_daz(half %x) #1 {
2074; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16_daz(
2075; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
2076; CHECK-NEXT:    [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000
2077; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]
2078; CHECK-NEXT:    ret i1 [[CLASS]]
2079;
2080  %cmpinf = fcmp ueq half %x, 0xH7C00
2081  %cmp.ole.zero = fcmp ole half %x, 0xH0000
2082  %class = or i1 %cmp.ole.zero, %cmpinf
2083  ret i1 %class
2084}
2085
2086define i1 @fcmp_oeq_posinf_or_ole_zero_f16_daz(half %x) #1 {
2087; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16_daz(
2088; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
2089; CHECK-NEXT:    [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000
2090; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]
2091; CHECK-NEXT:    ret i1 [[CLASS]]
2092;
2093  %cmpinf = fcmp oeq half %x, 0xH7C00
2094  %cmp.ole.zero = fcmp ole half %x, 0xH0000
2095  %class = or i1 %cmp.ole.zero, %cmpinf
2096  ret i1 %class
2097}
2098
2099define i1 @fcmp_oeq_posinf_or_olt_zero_f16(half %x) {
2100; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16(
2101; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 540)
2102; CHECK-NEXT:    ret i1 [[CLASS]]
2103;
2104  %cmpinf = fcmp oeq half %x, 0xH7C00
2105  %cmp.olt.zero = fcmp olt half %x, 0xH0000
2106  %class = or i1 %cmp.olt.zero, %cmpinf
2107  ret i1 %class
2108}
2109
2110define i1 @fcmp_oeq_posinf_or_olt_zero_f16_daz(half %x) #1 {
2111; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16_daz(
2112; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
2113; CHECK-NEXT:    [[CMP_OLT_ZERO:%.*]] = fcmp olt half [[X]], 0xH0000
2114; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_OLT_ZERO]], [[CMPINF]]
2115; CHECK-NEXT:    ret i1 [[CLASS]]
2116;
2117  %cmpinf = fcmp oeq half %x, 0xH7C00
2118  %cmp.olt.zero = fcmp olt half %x, 0xH0000
2119  %class = or i1 %cmp.olt.zero, %cmpinf
2120  ret i1 %class
2121}
2122
2123define i1 @fcmp_ueq_posinf_or_ult_zero_f16(half %x) {
2124; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16(
2125; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
2126; CHECK-NEXT:    ret i1 [[CLASS]]
2127;
2128  %cmpinf = fcmp ueq half %x, 0xH7C00
2129  %cmp.ult.zero = fcmp ult half %x, 0xH0000
2130  %class = or i1 %cmp.ult.zero, %cmpinf
2131  ret i1 %class
2132}
2133
2134define i1 @fcmp_oeq_posinf_or_ult_zero_f16(half %x) {
2135; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16(
2136; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
2137; CHECK-NEXT:    ret i1 [[CLASS]]
2138;
2139  %cmpinf = fcmp oeq half %x, 0xH7C00
2140  %cmp.ult.zero = fcmp ult half %x, 0xH0000
2141  %class = or i1 %cmp.ult.zero, %cmpinf
2142  ret i1 %class
2143}
2144
2145define i1 @fcmp_ueq_posinf_or_ult_zero_f16_daz(half %x) #1 {
2146; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16_daz(
2147; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
2148; CHECK-NEXT:    [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000
2149; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]
2150; CHECK-NEXT:    ret i1 [[CLASS]]
2151;
2152  %cmpinf = fcmp ueq half %x, 0xH7C00
2153  %cmp.ult.zero = fcmp ult half %x, 0xH0000
2154  %class = or i1 %cmp.ult.zero, %cmpinf
2155  ret i1 %class
2156}
2157
2158define i1 @fcmp_oeq_posinf_or_ult_zero_f16_daz(half %x) #1 {
2159; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16_daz(
2160; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
2161; CHECK-NEXT:    [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000
2162; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]
2163; CHECK-NEXT:    ret i1 [[CLASS]]
2164;
2165  %cmpinf = fcmp oeq half %x, 0xH7C00
2166  %cmp.ult.zero = fcmp ult half %x, 0xH0000
2167  %class = or i1 %cmp.ult.zero, %cmpinf
2168  ret i1 %class
2169}
2170
2171define i1 @fcmp_ueq_posinf_or_ule_zero_f16(half %x) {
2172; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16(
2173; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)
2174; CHECK-NEXT:    ret i1 [[CLASS]]
2175;
2176  %cmpinf = fcmp ueq half %x, 0xH7C00
2177  %cmp.ule.zero = fcmp ule half %x, 0xH0000
2178  %class = or i1 %cmp.ule.zero, %cmpinf
2179  ret i1 %class
2180}
2181
2182define i1 @fcmp_ueq_posinf_or_ule_zero_f16_daz(half %x) #1 {
2183; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16_daz(
2184; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
2185; CHECK-NEXT:    [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000
2186; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]
2187; CHECK-NEXT:    ret i1 [[CLASS]]
2188;
2189  %cmpinf = fcmp ueq half %x, 0xH7C00
2190  %cmp.ule.zero = fcmp ule half %x, 0xH0000
2191  %class = or i1 %cmp.ule.zero, %cmpinf
2192  ret i1 %class
2193}
2194
2195define i1 @fcmp_oeq_posinf_or_ule_zero_f16_daz(half %x) #1 {
2196; CHECK-LABEL: @fcmp_oeq_posinf_or_ule_zero_f16_daz(
2197; CHECK-NEXT:    [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
2198; CHECK-NEXT:    [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000
2199; CHECK-NEXT:    [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]
2200; CHECK-NEXT:    ret i1 [[CLASS]]
2201;
2202  %cmpinf = fcmp oeq half %x, 0xH7C00
2203  %cmp.ule.zero = fcmp ule half %x, 0xH0000
2204  %class = or i1 %cmp.ule.zero, %cmpinf
2205  ret i1 %class
2206}
2207
2208define i1 @fcmp_ueq_posinf_or_olt_zero_f16(half %x) {
2209; CHECK-LABEL: @fcmp_ueq_posinf_or_olt_zero_f16(
2210; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
2211; CHECK-NEXT:    ret i1 [[CLASS]]
2212;
2213  %cmpinf = fcmp ueq half %x, 0xH7C00
2214  %cmp.olt.zero = fcmp olt half %x, 0xH0000
2215  %class = or i1 %cmp.olt.zero, %cmpinf
2216  ret i1 %class
2217}
2218
2219declare half @llvm.fabs.f16(half) #0
2220declare half @llvm.canonicalize.f16(half) #0
2221declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0
2222
2223attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
2224attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }
2225attributes #2 = { "denormal-fp-math"="ieee,dynamic" }
2226