1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4; Infinity
5
6define i1 @inf0(double %arg) {
7; CHECK-LABEL: @inf0(
8; CHECK-NEXT:    ret i1 false
9;
10  %tmp = fcmp ogt double %arg, 0x7FF0000000000000
11  ret i1 %tmp
12}
13
14define i1 @inf1(double %arg) {
15; CHECK-LABEL: @inf1(
16; CHECK-NEXT:    ret i1 true
17;
18  %tmp = fcmp ule double %arg, 0x7FF0000000000000
19  ret i1 %tmp
20}
21
22; Negative infinity
23
24define i1 @ninf0(double %arg) {
25; CHECK-LABEL: @ninf0(
26; CHECK-NEXT:    ret i1 false
27;
28  %tmp = fcmp olt double %arg, 0xFFF0000000000000
29  ret i1 %tmp
30}
31
32define i1 @ninf1(double %arg) {
33; CHECK-LABEL: @ninf1(
34; CHECK-NEXT:    ret i1 true
35;
36  %tmp = fcmp uge double %arg, 0xFFF0000000000000
37  ret i1 %tmp
38}
39
40; NaNs
41
42define i1 @nan0(double %arg) {
43; CHECK-LABEL: @nan0(
44; CHECK-NEXT:    ret i1 false
45;
46  %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF
47  ret i1 %tmp
48}
49
50define i1 @nan1(double %arg) {
51; CHECK-LABEL: @nan1(
52; CHECK-NEXT:    ret i1 false
53;
54  %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF
55  ret i1 %tmp
56}
57
58define i1 @nan2(double %arg) {
59; CHECK-LABEL: @nan2(
60; CHECK-NEXT:    ret i1 false
61;
62  %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF
63  ret i1 %tmp
64}
65
66define i1 @nan3(double %arg) {
67; CHECK-LABEL: @nan3(
68; CHECK-NEXT:    ret i1 true
69;
70  %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF
71  ret i1 %tmp
72}
73
74define i1 @nan4(double %arg) {
75; CHECK-LABEL: @nan4(
76; CHECK-NEXT:    ret i1 true
77;
78  %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF
79  ret i1 %tmp
80}
81
82define i1 @nan5(double %arg) {
83; CHECK-LABEL: @nan5(
84; CHECK-NEXT:    ret i1 true
85;
86  %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF
87  ret i1 %tmp
88}
89
90; Negative NaN.
91
92define i1 @nnan0(double %arg) {
93; CHECK-LABEL: @nnan0(
94; CHECK-NEXT:    ret i1 false
95;
96  %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF
97  ret i1 %tmp
98}
99
100define i1 @nnan1(double %arg) {
101; CHECK-LABEL: @nnan1(
102; CHECK-NEXT:    ret i1 false
103;
104  %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF
105  ret i1 %tmp
106}
107
108define i1 @nnan2(double %arg) {
109; CHECK-LABEL: @nnan2(
110; CHECK-NEXT:    ret i1 false
111;
112  %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF
113  ret i1 %tmp
114}
115
116define i1 @nnan3(double %arg) {
117; CHECK-LABEL: @nnan3(
118; CHECK-NEXT:    ret i1 true
119;
120  %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF
121  ret i1 %tmp
122}
123
124define i1 @nnan4(double %arg) {
125; CHECK-LABEL: @nnan4(
126; CHECK-NEXT:    ret i1 true
127;
128  %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF
129  ret i1 %tmp
130}
131
132define i1 @nnan5(double %arg) {
133; CHECK-LABEL: @nnan5(
134; CHECK-NEXT:    ret i1 true
135;
136  %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF
137  ret i1 %tmp
138}
139
140; Negative zero.
141
142define i1 @nzero0() {
143; CHECK-LABEL: @nzero0(
144; CHECK-NEXT:    ret i1 true
145;
146  %tmp = fcmp oeq double 0.0, -0.0
147  ret i1 %tmp
148}
149
150define i1 @nzero1() {
151; CHECK-LABEL: @nzero1(
152; CHECK-NEXT:    ret i1 false
153;
154  %tmp = fcmp ogt double 0.0, -0.0
155  ret i1 %tmp
156}
157
158; No enlightenment here.
159
160define i1 @one_with_self(double %arg) {
161; CHECK-LABEL: @one_with_self(
162; CHECK-NEXT:    ret i1 false
163;
164  %tmp = fcmp one double %arg, %arg
165  ret i1 %tmp
166}
167
168; These tests choose arbitrarily between float and double,
169; and between uge and olt, to give reasonble coverage
170; without combinatorial explosion.
171
172declare half @llvm.fabs.f16(half)
173declare float @llvm.fabs.f32(float)
174declare double @llvm.fabs.f64(double)
175declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
176declare <3 x float> @llvm.fabs.v3f32(<3 x float>)
177declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
178declare float @llvm.sqrt.f32(float)
179declare double @llvm.powi.f64(double,i32)
180declare float @llvm.exp.f32(float)
181declare float @llvm.minnum.f32(float, float)
182declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>)
183declare float @llvm.maxnum.f32(float, float)
184declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)
185declare float @llvm.maximum.f32(float, float)
186declare double @llvm.exp2.f64(double)
187declare float @llvm.fma.f32(float,float,float)
188
189declare void @expect_equal(i1,i1)
190
191define i1 @orderedLessZeroTree(float,float,float,float) {
192; CHECK-LABEL: @orderedLessZeroTree(
193; CHECK-NEXT:    ret i1 true
194;
195  %square = fmul float %0, %0
196  %abs = call float @llvm.fabs.f32(float %1)
197  %sqrt = call float @llvm.sqrt.f32(float %2)
198  %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt)
199  %div = fdiv float %square, %abs
200  %rem = frem float %sqrt, %fma
201  %add = fadd float %div, %rem
202  %uge = fcmp uge float %add, 0.000000e+00
203  ret i1 %uge
204}
205
206define i1 @orderedLessZero_fdiv(float %x) {
207; CHECK-LABEL: @orderedLessZero_fdiv(
208; CHECK-NEXT:    ret i1 true
209;
210  %d = fdiv float %x, %x
211  %uge = fcmp uge float %d, 0.0
212  ret i1 %uge
213}
214
215; If x == -0.0, maxnum can return -0.0, but that still compares equal to 0.0.
216
217define i1 @orderedLessZero_maxnum(float %x) {
218; CHECK-LABEL: @orderedLessZero_maxnum(
219; CHECK-NEXT:    ret i1 true
220;
221  %d = call float @llvm.maxnum.f32(float %x, float 0.0)
222  %uge = fcmp uge float %d, 0.0
223  ret i1 %uge
224}
225
226define i1 @orderedLessZeroExpExt(float) {
227; CHECK-LABEL: @orderedLessZeroExpExt(
228; CHECK-NEXT:    ret i1 true
229;
230  %a = call float @llvm.exp.f32(float %0)
231  %b = fpext float %a to double
232  %uge = fcmp uge double %b, 0.000000e+00
233  ret i1 %uge
234}
235
236define i1 @orderedLessZeroExp2Trunc(double) {
237; CHECK-LABEL: @orderedLessZeroExp2Trunc(
238; CHECK-NEXT:    ret i1 false
239;
240  %a = call double @llvm.exp2.f64(double %0)
241  %b = fptrunc double %a to float
242  %olt = fcmp olt float %b, 0.000000e+00
243  ret i1 %olt
244}
245
246define i1 @orderedLessZeroPowi(double,double) {
247; CHECK-LABEL: @orderedLessZeroPowi(
248; CHECK-NEXT:    ret i1 false
249;
250  ; Even constant exponent
251  %a = call double @llvm.powi.f64(double %0, i32 2)
252  %square = fmul double %1, %1
253  ; Odd constant exponent with provably non-negative base
254  %b = call double @llvm.powi.f64(double %square, i32 3)
255  %c = fadd double %a, %b
256  %olt = fcmp olt double %b, 0.000000e+00
257  ret i1 %olt
258}
259
260define i1 @UIToFP_is_nan_or_positive_or_zero(i32 %x) {
261; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero(
262; CHECK-NEXT:    ret i1 true
263;
264  %a = uitofp i32 %x to float
265  %r = fcmp uge float %a, 0.000000e+00
266  ret i1 %r
267}
268
269define <2 x i1> @UIToFP_is_nan_or_positive_or_zero_vec(<2 x i32> %x) {
270; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero_vec(
271; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
272;
273  %a = uitofp <2 x i32> %x to <2 x float>
274  %r = fcmp uge <2 x float> %a, zeroinitializer
275  ret <2 x i1> %r
276}
277
278define i1 @UIToFP_is_positive_or_zero(i32 %x) {
279; CHECK-LABEL: @UIToFP_is_positive_or_zero(
280; CHECK-NEXT:    ret i1 true
281;
282  %a = uitofp i32 %x to float
283  %r = fcmp oge float %a, 0.000000e+00
284  ret i1 %r
285}
286
287define <2 x i1> @UIToFP_is_positive_or_zero_vec(<2 x i32> %x) {
288; CHECK-LABEL: @UIToFP_is_positive_or_zero_vec(
289; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
290;
291  %a = uitofp <2 x i32> %x to <2 x float>
292  %r = fcmp oge <2 x float> %a, zeroinitializer
293  ret <2 x i1> %r
294}
295
296define i1 @UIToFP_nnan_is_positive_or_zero(i32 %x) {
297; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero(
298; CHECK-NEXT:    ret i1 true
299;
300  %a = uitofp i32 %x to float
301  %r = fcmp nnan oge float %a, 0.000000e+00
302  ret i1 %r
303}
304
305define <2 x i1> @UIToFP_nnan_is_positive_or_zero_vec(<2 x i32> %x) {
306; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero_vec(
307; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
308;
309  %a = uitofp <2 x i32> %x to <2 x float>
310  %r = fcmp nnan oge <2 x float> %a, zeroinitializer
311  ret <2 x i1> %r
312}
313
314define i1 @UIToFP_is_not_negative(i32 %x) {
315; CHECK-LABEL: @UIToFP_is_not_negative(
316; CHECK-NEXT:    ret i1 false
317;
318  %a = uitofp i32 %x to float
319  %r = fcmp olt float %a, 0.000000e+00
320  ret i1 %r
321}
322
323define <2 x i1> @UIToFP_is_not_negative_vec(<2 x i32> %x) {
324; CHECK-LABEL: @UIToFP_is_not_negative_vec(
325; CHECK-NEXT:    ret <2 x i1> zeroinitializer
326;
327  %a = uitofp <2 x i32> %x to <2 x float>
328  %r = fcmp olt <2 x float> %a, zeroinitializer
329  ret <2 x i1> %r
330}
331
332; No FMF are required for this transform.
333
334define i1 @UIToFP_is_not_negative_or_nan(i32 %x) {
335; CHECK-LABEL: @UIToFP_is_not_negative_or_nan(
336; CHECK-NEXT:    ret i1 false
337;
338  %a = uitofp i32 %x to float
339  %r = fcmp ult float %a, 0.000000e+00
340  ret i1 %r
341}
342
343define <2 x i1> @UIToFP_is_not_negative_or_nan_vec(<2 x i32> %x) {
344; CHECK-LABEL: @UIToFP_is_not_negative_or_nan_vec(
345; CHECK-NEXT:    ret <2 x i1> zeroinitializer
346;
347  %a = uitofp <2 x i32> %x to <2 x float>
348  %r = fcmp ult <2 x float> %a, zeroinitializer
349  ret <2 x i1> %r
350}
351
352define i1 @UIToFP_nnan_is_not_negative(i32 %x) {
353; CHECK-LABEL: @UIToFP_nnan_is_not_negative(
354; CHECK-NEXT:    ret i1 false
355;
356  %a = uitofp i32 %x to float
357  %r = fcmp nnan ult float %a, 0.000000e+00
358  ret i1 %r
359}
360
361define <2 x i1> @UIToFP_nnan_is_not_negative_vec(<2 x i32> %x) {
362; CHECK-LABEL: @UIToFP_nnan_is_not_negative_vec(
363; CHECK-NEXT:    ret <2 x i1> zeroinitializer
364;
365  %a = uitofp <2 x i32> %x to <2 x float>
366  %r = fcmp nnan ult <2 x float> %a, zeroinitializer
367  ret <2 x i1> %r
368}
369
370define i1 @fabs_is_nan_or_positive_or_zero(double %x) {
371; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero(
372; CHECK-NEXT:    ret i1 true
373;
374  %fabs = tail call double @llvm.fabs.f64(double %x)
375  %cmp = fcmp uge double %fabs, 0.0
376  ret i1 %cmp
377}
378
379define <2 x i1> @fabs_is_nan_or_positive_or_zero_vec(<2 x double> %x) {
380; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero_vec(
381; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
382;
383  %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
384  %cmp = fcmp uge <2 x double> %fabs, zeroinitializer
385  ret <2 x i1> %cmp
386}
387
388define i1 @fabs_nnan_is_positive_or_zero(double %x) {
389; CHECK-LABEL: @fabs_nnan_is_positive_or_zero(
390; CHECK-NEXT:    ret i1 true
391;
392  %fabs = tail call nnan double @llvm.fabs.f64(double %x)
393  %cmp = fcmp oge double %fabs, 0.0
394  ret i1 %cmp
395}
396
397define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) {
398; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec(
399; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
400;
401  %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
402  %cmp = fcmp oge <2 x double> %fabs, zeroinitializer
403  ret <2 x i1> %cmp
404}
405
406define i1 @fabs_fcmp-nnan_is_positive_or_zero(double %x) {
407; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero(
408; CHECK-NEXT:    ret i1 true
409;
410  %fabs = tail call double @llvm.fabs.f64(double %x)
411  %cmp = fcmp nnan oge double %fabs, 0.0
412  ret i1 %cmp
413}
414
415define <2 x i1> @fabs_fcmp-nnan_is_positive_or_zero_vec(<2 x double> %x) {
416; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero_vec(
417; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
418;
419  %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
420  %cmp = fcmp nnan oge <2 x double> %fabs, zeroinitializer
421  ret <2 x i1> %cmp
422}
423
424define i1 @fabs_is_not_negative(double %x) {
425; CHECK-LABEL: @fabs_is_not_negative(
426; CHECK-NEXT:    ret i1 false
427;
428  %fabs = tail call double @llvm.fabs.f64(double %x)
429  %cmp = fcmp olt double %fabs, 0.0
430  ret i1 %cmp
431}
432
433define <2 x i1> @fabs_is_not_negative_vec(<2 x double> %x) {
434; CHECK-LABEL: @fabs_is_not_negative_vec(
435; CHECK-NEXT:    ret <2 x i1> zeroinitializer
436;
437  %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
438  %cmp = fcmp olt <2 x double> %fabs, zeroinitializer
439  ret <2 x i1> %cmp
440}
441
442define i1 @fabs_nnan_is_not_negative(double %x) {
443; CHECK-LABEL: @fabs_nnan_is_not_negative(
444; CHECK-NEXT:    ret i1 false
445;
446  %fabs = tail call nnan double @llvm.fabs.f64(double %x)
447  %cmp = fcmp ult double %fabs, 0.0
448  ret i1 %cmp
449}
450
451define <2 x i1> @fabs_nnan_is_not_negative_vec(<2 x double> %x) {
452; CHECK-LABEL: @fabs_nnan_is_not_negative_vec(
453; CHECK-NEXT:    ret <2 x i1> zeroinitializer
454;
455  %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
456  %cmp = fcmp ult <2 x double> %fabs, zeroinitializer
457  ret <2 x i1> %cmp
458}
459
460define i1 @fabs_fcmp-nnan_is_not_negative(double %x) {
461; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative(
462; CHECK-NEXT:    ret i1 false
463;
464  %fabs = tail call double @llvm.fabs.f64(double %x)
465  %cmp = fcmp nnan ult double %fabs, 0.0
466  ret i1 %cmp
467}
468
469define <2 x i1> @fabs_fcmp-nnan_is_not_negative_vec(<2 x double> %x) {
470; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative_vec(
471; CHECK-NEXT:    ret <2 x i1> zeroinitializer
472;
473  %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
474  %cmp = fcmp nnan ult <2 x double> %fabs, zeroinitializer
475  ret <2 x i1> %cmp
476}
477
478define <2 x i1> @fabs_is_not_negative_negzero(<2 x float> %V) {
479; CHECK-LABEL: @fabs_is_not_negative_negzero(
480; CHECK-NEXT:    ret <2 x i1> zeroinitializer
481;
482  %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
483  %cmp = fcmp olt <2 x float> %abs, <float -0.0, float -0.0>
484  ret <2 x i1> %cmp
485}
486
487define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) {
488; CHECK-LABEL: @fabs_is_not_negative_poszero(
489; CHECK-NEXT:    ret <2 x i1> zeroinitializer
490;
491  %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
492  %cmp = fcmp olt <2 x float> %abs, <float 0.0, float 0.0>
493  ret <2 x i1> %cmp
494}
495
496define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) {
497; CHECK-LABEL: @fabs_is_not_negative_anyzero(
498; CHECK-NEXT:    ret <2 x i1> zeroinitializer
499;
500  %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
501  %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0>
502  ret <2 x i1> %cmp
503}
504
505define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) {
506; CHECK-LABEL: @fabs_is_not_negative_negzero_undef(
507; CHECK-NEXT:    ret <3 x i1> zeroinitializer
508;
509  %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
510  %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float undef>
511  ret <3 x i1> %cmp
512}
513
514define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) {
515; CHECK-LABEL: @fabs_is_not_negative_poszero_undef(
516; CHECK-NEXT:    ret <3 x i1> zeroinitializer
517;
518  %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
519  %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float undef>
520  ret <3 x i1> %cmp
521}
522
523define <3 x i1> @fabs_is_not_negative_anyzero_undef(<3 x float> %V) {
524; CHECK-LABEL: @fabs_is_not_negative_anyzero_undef(
525; CHECK-NEXT:    ret <3 x i1> zeroinitializer
526;
527  %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
528  %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float undef>
529  ret <3 x i1> %cmp
530}
531
532define i1 @orderedLessZeroSelect(float, float) {
533; CHECK-LABEL: @orderedLessZeroSelect(
534; CHECK-NEXT:    ret i1 true
535;
536  %a = call float @llvm.exp.f32(float %0)
537  %b = call float @llvm.fabs.f32(float %1)
538  %c = fcmp olt float %0, %1
539  %d = select i1 %c, float %a, float %b
540  %e = fadd float %d, 1.0
541  %uge = fcmp uge float %e, 0.000000e+00
542  ret i1 %uge
543}
544
545define i1 @orderedLessZeroMinNum(float, float) {
546; CHECK-LABEL: @orderedLessZeroMinNum(
547; CHECK-NEXT:    ret i1 true
548;
549  %a = call float @llvm.exp.f32(float %0)
550  %b = call float @llvm.fabs.f32(float %1)
551  %c = call float @llvm.minnum.f32(float %a, float %b)
552  %uge = fcmp uge float %c, 0.000000e+00
553  ret i1 %uge
554}
555
556; PR37776: https://bugs.llvm.org/show_bug.cgi?id=37776
557; exp() may return nan, leaving %1 as the unknown result, so we can't simplify.
558
559define i1 @orderedLessZeroMaxNum(float, float) {
560; CHECK-LABEL: @orderedLessZeroMaxNum(
561; CHECK-NEXT:    [[A:%.*]] = call float @llvm.exp.f32(float [[TMP0:%.*]])
562; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[TMP1:%.*]])
563; CHECK-NEXT:    [[UGE:%.*]] = fcmp uge float [[B]], 0.000000e+00
564; CHECK-NEXT:    ret i1 [[UGE]]
565;
566  %a = call float @llvm.exp.f32(float %0)
567  %b = call float @llvm.maxnum.f32(float %a, float %1)
568  %uge = fcmp uge float %b, 0.000000e+00
569  ret i1 %uge
570}
571
572; But using maximum, we can simplify, since the NaN would be propagated
573
574define i1 @orderedLessZeroMaximum(float, float) {
575; CHECK-LABEL: @orderedLessZeroMaximum(
576; CHECK-NEXT:    ret i1 true
577;
578  %a = call float @llvm.exp.f32(float %0)
579  %b = call float @llvm.maximum.f32(float %a, float %1)
580  %uge = fcmp uge float %b, 0.000000e+00
581  ret i1 %uge
582}
583
584define i1 @minnum_non_nan(float %x) {
585; CHECK-LABEL: @minnum_non_nan(
586; CHECK-NEXT:    ret i1 true
587;
588  %min = call float @llvm.minnum.f32(float 0.5, float %x)
589  %cmp = fcmp ord float %min, 1.0
590  ret i1 %cmp
591}
592
593define i1 @maxnum_non_nan(float %x) {
594; CHECK-LABEL: @maxnum_non_nan(
595; CHECK-NEXT:    ret i1 false
596;
597  %min = call float @llvm.maxnum.f32(float %x, float 42.0)
598  %cmp = fcmp uno float %min, 12.0
599  ret i1 %cmp
600}
601
602; min(x, 0.5) == 1.0 --> false
603
604define i1 @minnum_oeq_small_min_constant(float %x) {
605; CHECK-LABEL: @minnum_oeq_small_min_constant(
606; CHECK-NEXT:    ret i1 false
607;
608  %min = call float @llvm.minnum.f32(float %x, float 0.5)
609  %cmp = fcmp oeq float %min, 1.0
610  ret i1 %cmp
611}
612
613; min(x, 0.5) > 1.0 --> false
614
615define i1 @minnum_ogt_small_min_constant(float %x) {
616; CHECK-LABEL: @minnum_ogt_small_min_constant(
617; CHECK-NEXT:    ret i1 false
618;
619  %min = call float @llvm.minnum.f32(float %x, float 0.5)
620  %cmp = fcmp ogt float %min, 1.0
621  ret i1 %cmp
622}
623
624; min(x, 0.5) >= 1.0 --> false
625
626define i1 @minnum_oge_small_min_constant(float %x) {
627; CHECK-LABEL: @minnum_oge_small_min_constant(
628; CHECK-NEXT:    ret i1 false
629;
630  %min = call float @llvm.minnum.f32(float %x, float 0.5)
631  %cmp = fcmp oge float %min, 1.0
632  ret i1 %cmp
633}
634
635; min(x, 0.5) == 1.0 --> false
636
637define i1 @minnum_ueq_small_min_constant(float %x) {
638; CHECK-LABEL: @minnum_ueq_small_min_constant(
639; CHECK-NEXT:    ret i1 false
640;
641  %min = call float @llvm.minnum.f32(float %x, float 0.5)
642  %cmp = fcmp ueq float %min, 1.0
643  ret i1 %cmp
644}
645
646; min(x, 0.5) > 1.0 --> false
647
648define i1 @minnum_ugt_small_min_constant(float %x) {
649; CHECK-LABEL: @minnum_ugt_small_min_constant(
650; CHECK-NEXT:    ret i1 false
651;
652  %min = call float @llvm.minnum.f32(float %x, float 0.5)
653  %cmp = fcmp ugt float %min, 1.0
654  ret i1 %cmp
655}
656
657; min(x, 0.5) >= 1.0 --> false
658
659define <2 x i1> @minnum_uge_small_min_constant(<2 x float> %x) {
660; CHECK-LABEL: @minnum_uge_small_min_constant(
661; CHECK-NEXT:    ret <2 x i1> zeroinitializer
662;
663  %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
664  %cmp = fcmp uge <2 x float> %min, <float 1.0, float 1.0>
665  ret <2 x i1> %cmp
666}
667
668; min(x, 0.5) < 1.0 --> true
669
670define <2 x i1> @minnum_olt_small_min_constant(<2 x float> %x) {
671; CHECK-LABEL: @minnum_olt_small_min_constant(
672; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
673;
674  %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
675  %cmp = fcmp olt <2 x float> %min, <float 1.0, float 1.0>
676  ret <2 x i1> %cmp
677}
678
679; min(x, 0.5) <= 1.0 --> true
680
681define i1 @minnum_ole_small_min_constant(float %x) {
682; CHECK-LABEL: @minnum_ole_small_min_constant(
683; CHECK-NEXT:    ret i1 true
684;
685  %min = call float @llvm.minnum.f32(float %x, float 0.5)
686  %cmp = fcmp ole float %min, 1.0
687  ret i1 %cmp
688}
689
690; min(x, 0.5) != 1.0 --> true
691
692define i1 @minnum_one_small_min_constant(float %x) {
693; CHECK-LABEL: @minnum_one_small_min_constant(
694; CHECK-NEXT:    ret i1 true
695;
696  %min = call float @llvm.minnum.f32(float %x, float 0.5)
697  %cmp = fcmp one float %min, 1.0
698  ret i1 %cmp
699}
700
701; min(x, 0.5) < 1.0 --> true
702
703define i1 @minnum_ult_small_min_constant(float %x) {
704; CHECK-LABEL: @minnum_ult_small_min_constant(
705; CHECK-NEXT:    ret i1 true
706;
707  %min = call float @llvm.minnum.f32(float %x, float 0.5)
708  %cmp = fcmp ult float %min, 1.0
709  ret i1 %cmp
710}
711
712; min(x, 0.5) <= 1.0 --> true
713
714define i1 @minnum_ule_small_min_constant(float %x) {
715; CHECK-LABEL: @minnum_ule_small_min_constant(
716; CHECK-NEXT:    ret i1 true
717;
718  %min = call float @llvm.minnum.f32(float %x, float 0.5)
719  %cmp = fcmp ule float %min, 1.0
720  ret i1 %cmp
721}
722
723; min(x, 0.5) != 1.0 --> true
724
725define i1 @minnum_une_small_min_constant(float %x) {
726; CHECK-LABEL: @minnum_une_small_min_constant(
727; CHECK-NEXT:    ret i1 true
728;
729  %min = call float @llvm.minnum.f32(float %x, float 0.5)
730  %cmp = fcmp une float %min, 1.0
731  ret i1 %cmp
732}
733
734; Negative test:
735; min(x, 1.0) != 1.0 --> ?
736
737define i1 @minnum_une_equal_min_constant(float %x) {
738; CHECK-LABEL: @minnum_une_equal_min_constant(
739; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00)
740; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
741; CHECK-NEXT:    ret i1 [[CMP]]
742;
743  %min = call float @llvm.minnum.f32(float %x, float 1.0)
744  %cmp = fcmp une float %min, 1.0
745  ret i1 %cmp
746}
747
748; Negative test:
749; min(x, 2.0) != 1.0 --> ?
750
751define i1 @minnum_une_large_min_constant(float %x) {
752; CHECK-LABEL: @minnum_une_large_min_constant(
753; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.000000e+00)
754; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
755; CHECK-NEXT:    ret i1 [[CMP]]
756;
757  %min = call float @llvm.minnum.f32(float %x, float 2.0)
758  %cmp = fcmp une float %min, 1.0
759  ret i1 %cmp
760}
761
762; Partial negative test (the minnum simplifies):
763; min(x, NaN) != 1.0 --> x != 1.0
764
765define i1 @minnum_une_nan_min_constant(float %x) {
766; CHECK-LABEL: @minnum_une_nan_min_constant(
767; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
768; CHECK-NEXT:    ret i1 [[CMP]]
769;
770  %min = call float @llvm.minnum.f32(float %x, float 0x7FF8000000000000)
771  %cmp = fcmp une float %min, 1.0
772  ret i1 %cmp
773}
774
775; max(x, 1.5) == 1.0 --> false
776
777define i1 @maxnum_oeq_large_max_constant(float %x) {
778; CHECK-LABEL: @maxnum_oeq_large_max_constant(
779; CHECK-NEXT:    ret i1 false
780;
781  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
782  %cmp = fcmp oeq float %max, 1.0
783  ret i1 %cmp
784}
785
786; max(x, 1.5) < 1.0 --> false
787
788define i1 @maxnum_olt_large_max_constant(float %x) {
789; CHECK-LABEL: @maxnum_olt_large_max_constant(
790; CHECK-NEXT:    ret i1 false
791;
792  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
793  %cmp = fcmp olt float %max, 1.0
794  ret i1 %cmp
795}
796
797; max(x, 1.5) <= 1.0 --> false
798
799define i1 @maxnum_ole_large_max_constant(float %x) {
800; CHECK-LABEL: @maxnum_ole_large_max_constant(
801; CHECK-NEXT:    ret i1 false
802;
803  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
804  %cmp = fcmp ole float %max, 1.0
805  ret i1 %cmp
806}
807
808; max(x, 1.5) == 1.0 --> false
809
810define i1 @maxnum_ueq_large_max_constant(float %x) {
811; CHECK-LABEL: @maxnum_ueq_large_max_constant(
812; CHECK-NEXT:    ret i1 false
813;
814  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
815  %cmp = fcmp ueq float %max, 1.0
816  ret i1 %cmp
817}
818
819; max(x, 1.5) < 1.0 --> false
820
821define i1 @maxnum_ult_large_max_constant(float %x) {
822; CHECK-LABEL: @maxnum_ult_large_max_constant(
823; CHECK-NEXT:    ret i1 false
824;
825  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
826  %cmp = fcmp ult float %max, 1.0
827  ret i1 %cmp
828}
829
830; max(x, 1.5) <= 1.0 --> false
831
832define <2 x i1> @maxnum_ule_large_max_constant(<2 x float> %x) {
833; CHECK-LABEL: @maxnum_ule_large_max_constant(
834; CHECK-NEXT:    ret <2 x i1> zeroinitializer
835;
836  %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
837  %cmp = fcmp ule <2 x float> %max, <float 1.0, float 1.0>
838  ret <2 x i1> %cmp
839}
840
841; max(x, 1.5) > 1.0 --> true
842
843define <2 x i1> @maxnum_ogt_large_max_constant(<2 x float> %x) {
844; CHECK-LABEL: @maxnum_ogt_large_max_constant(
845; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
846;
847  %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
848  %cmp = fcmp ogt <2 x float> %max, <float 1.0, float 1.0>
849  ret <2 x i1> %cmp
850}
851
852; max(x, 1.5) >= 1.0 --> true
853
854define i1 @maxnum_oge_large_max_constant(float %x) {
855; CHECK-LABEL: @maxnum_oge_large_max_constant(
856; CHECK-NEXT:    ret i1 true
857;
858  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
859  %cmp = fcmp oge float %max, 1.0
860  ret i1 %cmp
861}
862
863; max(x, 1.5) != 1.0 --> true
864
865define i1 @maxnum_one_large_max_constant(float %x) {
866; CHECK-LABEL: @maxnum_one_large_max_constant(
867; CHECK-NEXT:    ret i1 true
868;
869  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
870  %cmp = fcmp one float %max, 1.0
871  ret i1 %cmp
872}
873
874; max(x, 1.5) > 1.0 --> true
875
876define i1 @maxnum_ugt_large_max_constant(float %x) {
877; CHECK-LABEL: @maxnum_ugt_large_max_constant(
878; CHECK-NEXT:    ret i1 true
879;
880  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
881  %cmp = fcmp ugt float %max, 1.0
882  ret i1 %cmp
883}
884
885; max(x, 1.5) >= 1.0 --> true
886
887define i1 @maxnum_uge_large_max_constant(float %x) {
888; CHECK-LABEL: @maxnum_uge_large_max_constant(
889; CHECK-NEXT:    ret i1 true
890;
891  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
892  %cmp = fcmp uge float %max, 1.0
893  ret i1 %cmp
894}
895
896; max(x, 1.5) != 1.0 --> true
897
898define i1 @maxnum_une_large_max_constant(float %x) {
899; CHECK-LABEL: @maxnum_une_large_max_constant(
900; CHECK-NEXT:    ret i1 true
901;
902  %max = call float @llvm.maxnum.f32(float %x, float 1.5)
903  %cmp = fcmp une float %max, 1.0
904  ret i1 %cmp
905}
906
907; Negative test:
908; max(x, 1.0) != 1.0 --> ?
909
910define i1 @maxnum_une_equal_max_constant(float %x) {
911; CHECK-LABEL: @maxnum_une_equal_max_constant(
912; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
913; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
914; CHECK-NEXT:    ret i1 [[CMP]]
915;
916  %max = call float @llvm.maxnum.f32(float %x, float 1.0)
917  %cmp = fcmp une float %max, 1.0
918  ret i1 %cmp
919}
920
921; Negative test:
922; max(x, 0.5) != 1.0 --> ?
923
924define i1 @maxnum_une_small_max_constant(float %x) {
925; CHECK-LABEL: @maxnum_une_small_max_constant(
926; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 5.000000e-01)
927; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
928; CHECK-NEXT:    ret i1 [[CMP]]
929;
930  %max = call float @llvm.maxnum.f32(float %x, float 0.5)
931  %cmp = fcmp une float %max, 1.0
932  ret i1 %cmp
933}
934
935; Partial negative test (the maxnum simplifies):
936; max(x, NaN) != 1.0 --> x != 1.0
937
938define i1 @maxnum_une_nan_max_constant(float %x) {
939; CHECK-LABEL: @maxnum_une_nan_max_constant(
940; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
941; CHECK-NEXT:    ret i1 [[CMP]]
942;
943  %max = call float @llvm.maxnum.f32(float %x, float 0x7FF8000000000000)
944  %cmp = fcmp une float %max, 1.0
945  ret i1 %cmp
946}
947
948define i1 @known_positive_olt_with_negative_constant(double %a) {
949; CHECK-LABEL: @known_positive_olt_with_negative_constant(
950; CHECK-NEXT:    ret i1 false
951;
952  %call = call double @llvm.fabs.f64(double %a)
953  %cmp = fcmp olt double %call, -1.0
954  ret i1 %cmp
955}
956
957define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) {
958; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec(
959; CHECK-NEXT:    ret <2 x i1> zeroinitializer
960;
961  %call = uitofp <2 x i32> %a to <2 x double>
962  %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0>
963  ret <2 x i1> %cmp
964}
965
966define i1 @known_positive_ugt_with_negative_constant(i32 %a) {
967; CHECK-LABEL: @known_positive_ugt_with_negative_constant(
968; CHECK-NEXT:    ret i1 true
969;
970  %call = uitofp i32 %a to float
971  %cmp = fcmp ugt float %call, -3.0
972  ret i1 %cmp
973}
974
975define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) {
976; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec(
977; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
978;
979  %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
980  %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0>
981  ret <2 x i1> %cmp
982}
983
984define i1 @known_positive_oeq_with_negative_constant(half %a) {
985; CHECK-LABEL: @known_positive_oeq_with_negative_constant(
986; CHECK-NEXT:    ret i1 false
987;
988  %call = call half @llvm.fabs.f16(half %a)
989  %cmp = fcmp oeq half %call, -5.0
990  ret i1 %cmp
991}
992
993define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) {
994; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec(
995; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
996;
997  %call = uitofp <2 x i32> %a to <2 x half>
998  %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0>
999  ret <2 x i1> %cmp
1000}
1001
1002define i1 @nonans1(double %in1, double %in2) {
1003; CHECK-LABEL: @nonans1(
1004; CHECK-NEXT:    ret i1 false
1005;
1006  %cmp = fcmp nnan uno double %in1, %in2
1007  ret i1 %cmp
1008}
1009
1010define i1 @nonans2(double %in1, double %in2) {
1011; CHECK-LABEL: @nonans2(
1012; CHECK-NEXT:    ret i1 true
1013;
1014  %cmp = fcmp nnan ord double %in1, %in2
1015  ret i1 %cmp
1016}
1017
1018define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) {
1019; CHECK-LABEL: @orderedCompareWithNaNVector(
1020; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1021;
1022  %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
1023  ret <2 x i1> %cmp
1024}
1025
1026define <2 x i1> @orderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
1027; CHECK-LABEL: @orderedCompareWithNaNVector_undef_elt(
1028; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1029;
1030  %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double undef>
1031  ret <2 x i1> %cmp
1032}
1033
1034define <2 x i1> @unorderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
1035; CHECK-LABEL: @unorderedCompareWithNaNVector_undef_elt(
1036; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1037;
1038  %cmp = fcmp ult <2 x double> %A, <double undef, double 0xFFFFFFFFFFFFFFFF>
1039  ret <2 x i1> %cmp
1040}
1041
1042define i1 @is_infinite(float %x) {
1043; CHECK-LABEL: @is_infinite(
1044; CHECK-NEXT:    ret i1 false
1045;
1046  %xabs = call ninf float @llvm.fabs.f32(float %x)
1047  %r = fcmp oeq float %xabs, 0x7FF0000000000000
1048  ret i1 %r
1049}
1050
1051define <2 x i1> @is_infinite_neg(<2 x float> %x) {
1052; CHECK-LABEL: @is_infinite_neg(
1053; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1054;
1055  %x42 = fadd ninf <2 x float> %x, <float 42.0, float 42.0>
1056  %r = fcmp oeq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1057  ret <2 x i1> %r
1058}
1059
1060; Negative test - but this could be reduced to 'uno' outside of instsimplify.
1061
1062define i1 @is_infinite_or_nan(float %x) {
1063; CHECK-LABEL: @is_infinite_or_nan(
1064; CHECK-NEXT:    [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01
1065; CHECK-NEXT:    [[R:%.*]] = fcmp ueq float [[X42]], 0xFFF0000000000000
1066; CHECK-NEXT:    ret i1 [[R]]
1067;
1068  %x42 = fadd ninf float %x, 42.0
1069  %r = fcmp ueq float %x42, 0xFFF0000000000000
1070  ret i1 %r
1071}
1072
1073define i1 @is_infinite_or_nan2(float %x) {
1074; CHECK-LABEL: @is_infinite_or_nan2(
1075; CHECK-NEXT:    ret i1 false
1076;
1077  %xabs = call nnan ninf float @llvm.fabs.f32(float %x)
1078  %r = fcmp ueq float %xabs, 0x7FF0000000000000
1079  ret i1 %r
1080}
1081
1082define <2 x i1> @is_infinite_neg_or_nan(<2 x float> %x) {
1083; CHECK-LABEL: @is_infinite_neg_or_nan(
1084; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1085;
1086  %x42 = fadd nnan ninf <2 x float> %x, <float 42.0, float 42.0>
1087  %r = fcmp ueq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1088  ret <2 x i1> %r
1089}
1090
1091define i1 @is_finite_or_nan(i1 %c, double %x) {
1092; CHECK-LABEL: @is_finite_or_nan(
1093; CHECK-NEXT:    ret i1 true
1094;
1095  %xx = fmul ninf double %x, %x
1096  %s = select i1 %c, double 42.0, double %xx
1097  %r = fcmp une double %s, 0x7FF0000000000000
1098  ret i1 %r
1099}
1100
1101define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) {
1102; CHECK-LABEL: @is_finite_or_nan_commute(
1103; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1104;
1105  %cast = uitofp <2 x i8> %x to <2 x float>
1106  %r = fcmp une <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1107  ret <2 x i1> %r
1108}
1109
1110; Negative test - but this could be reduced to 'ord' outside of instsimplify.
1111
1112define i1 @is_finite_and_ordered(double %x) {
1113; CHECK-LABEL: @is_finite_and_ordered(
1114; CHECK-NEXT:    [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]]
1115; CHECK-NEXT:    [[R:%.*]] = fcmp one double [[XX]], 0x7FF0000000000000
1116; CHECK-NEXT:    ret i1 [[R]]
1117;
1118  %xx = fmul ninf double %x, %x
1119  %r = fcmp one double %xx, 0x7FF0000000000000
1120  ret i1 %r
1121}
1122
1123define i1 @is_finite(i1 %c, double %x) {
1124; CHECK-LABEL: @is_finite(
1125; CHECK-NEXT:    ret i1 true
1126;
1127  %xx = fmul nnan ninf double %x, %x
1128  %s = select i1 %c, double 42.0, double %xx
1129  %r = fcmp one double %s, 0x7FF0000000000000
1130  ret i1 %r
1131}
1132
1133define <2 x i1> @is_finite_commute(<2 x i8> %x) {
1134; CHECK-LABEL: @is_finite_commute(
1135; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1136;
1137  %cast = uitofp <2 x i8> %x to <2 x float>
1138  %r = fcmp one <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1139  ret <2 x i1> %r
1140}
1141
1142; largest unsigned i15 = 2^15 - 1 = 32767
1143; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504
1144
1145define i1 @isKnownNeverInfinity_uitofp(i15 %x) {
1146; CHECK-LABEL: @isKnownNeverInfinity_uitofp(
1147; CHECK-NEXT:    ret i1 true
1148;
1149  %f = uitofp i15 %x to half
1150  %r = fcmp une half %f, 0xH7c00
1151  ret i1 %r
1152}
1153
1154; negative test
1155
1156define i1 @isNotKnownNeverInfinity_uitofp(i16 %x) {
1157; CHECK-LABEL: @isNotKnownNeverInfinity_uitofp(
1158; CHECK-NEXT:    [[F:%.*]] = uitofp i16 [[X:%.*]] to half
1159; CHECK-NEXT:    [[R:%.*]] = fcmp une half [[F]], 0xH7C00
1160; CHECK-NEXT:    ret i1 [[R]]
1161;
1162  %f = uitofp i16 %x to half
1163  %r = fcmp une half %f, 0xH7c00
1164  ret i1 %r
1165}
1166
1167define i1 @isKnownNeverNegativeInfinity_uitofp(i15 %x) {
1168; CHECK-LABEL: @isKnownNeverNegativeInfinity_uitofp(
1169; CHECK-NEXT:    ret i1 false
1170;
1171  %f = uitofp i15 %x to half
1172  %r = fcmp oeq half %f, 0xHfc00
1173  ret i1 %r
1174}
1175
1176; uitofp can't be negative, so this still works.
1177
1178define i1 @isNotKnownNeverNegativeInfinity_uitofp(i16 %x) {
1179; CHECK-LABEL: @isNotKnownNeverNegativeInfinity_uitofp(
1180; CHECK-NEXT:    ret i1 false
1181;
1182  %f = uitofp i16 %x to half
1183  %r = fcmp oeq half %f, 0xHfc00
1184  ret i1 %r
1185}
1186
1187; largest magnitude signed i16 = 2^15 - 1 = 32767 --> -32768
1188; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504
1189
1190define i1 @isKnownNeverInfinity_sitofp(i16 %x) {
1191; CHECK-LABEL: @isKnownNeverInfinity_sitofp(
1192; CHECK-NEXT:    ret i1 true
1193;
1194  %f = sitofp i16 %x to half
1195  %r = fcmp une half %f, 0xH7c00
1196  ret i1 %r
1197}
1198
1199; negative test
1200
1201define i1 @isNotKnownNeverInfinity_sitofp(i17 %x) {
1202; CHECK-LABEL: @isNotKnownNeverInfinity_sitofp(
1203; CHECK-NEXT:    [[F:%.*]] = sitofp i17 [[X:%.*]] to half
1204; CHECK-NEXT:    [[R:%.*]] = fcmp une half [[F]], 0xH7C00
1205; CHECK-NEXT:    ret i1 [[R]]
1206;
1207  %f = sitofp i17 %x to half
1208  %r = fcmp une half %f, 0xH7c00
1209  ret i1 %r
1210}
1211
1212define i1 @isKnownNeverNegativeInfinity_sitofp(i16 %x) {
1213; CHECK-LABEL: @isKnownNeverNegativeInfinity_sitofp(
1214; CHECK-NEXT:    ret i1 false
1215;
1216  %f = sitofp i16 %x to half
1217  %r = fcmp oeq half %f, 0xHfc00
1218  ret i1 %r
1219}
1220
1221; negative test
1222
1223define i1 @isNotKnownNeverNegativeInfinity_sitofp(i17 %x) {
1224; CHECK-LABEL: @isNotKnownNeverNegativeInfinity_sitofp(
1225; CHECK-NEXT:    [[F:%.*]] = sitofp i17 [[X:%.*]] to half
1226; CHECK-NEXT:    [[R:%.*]] = fcmp oeq half [[F]], 0xHFC00
1227; CHECK-NEXT:    ret i1 [[R]]
1228;
1229  %f = sitofp i17 %x to half
1230  %r = fcmp oeq half %f, 0xHfc00
1231  ret i1 %r
1232}
1233