Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / floating-point-compare.ll
blob3c1794c81284d748e9441b87f5982bc6362c4fa2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; Infinity
6 define i1 @inf0(double %arg) {
7 ; CHECK-LABEL: @inf0(
8 ; CHECK-NEXT:    ret i1 false
10   %tmp = fcmp ogt double %arg, 0x7FF0000000000000
11   ret i1 %tmp
14 define i1 @inf0_fabs(double %arg) {
15 ; CHECK-LABEL: @inf0_fabs(
16 ; CHECK-NEXT:    ret i1 false
18   %fabs.arg = call double @llvm.fabs.f64(double %arg)
19   %tmp = fcmp ogt double %fabs.arg, 0x7FF0000000000000
20   ret i1 %tmp
23 define i1 @inf1(double %arg) {
24 ; CHECK-LABEL: @inf1(
25 ; CHECK-NEXT:    ret i1 true
27   %tmp = fcmp ule double %arg, 0x7FF0000000000000
28   ret i1 %tmp
31 define i1 @inf1_fabs(double %arg) {
32 ; CHECK-LABEL: @inf1_fabs(
33 ; CHECK-NEXT:    ret i1 true
35   %fabs.arg = call double @llvm.fabs.f64(double %arg)
36   %tmp = fcmp ule double %fabs.arg, 0x7FF0000000000000
37   ret i1 %tmp
40 ; Negative infinity
42 define i1 @ninf0(double %arg) {
43 ; CHECK-LABEL: @ninf0(
44 ; CHECK-NEXT:    ret i1 false
46   %tmp = fcmp olt double %arg, 0xFFF0000000000000
47   ret i1 %tmp
50 define i1 @ninf0_fabs(double %arg) {
51 ; CHECK-LABEL: @ninf0_fabs(
52 ; CHECK-NEXT:    ret i1 false
54   %fabs.arg = call double @llvm.fabs.f64(double %arg)
55   %tmp = fcmp olt double %fabs.arg, 0xFFF0000000000000
56   ret i1 %tmp
59 define i1 @ninf1(double %arg) {
60 ; CHECK-LABEL: @ninf1(
61 ; CHECK-NEXT:    ret i1 true
63   %tmp = fcmp uge double %arg, 0xFFF0000000000000
64   ret i1 %tmp
67 define i1 @ninf1_fabs(double %arg) {
68 ; CHECK-LABEL: @ninf1_fabs(
69 ; CHECK-NEXT:    ret i1 true
71   %fabs.arg = call double @llvm.fabs.f64(double %arg)
72   %tmp = fcmp uge double %fabs.arg, 0xFFF0000000000000
73   ret i1 %tmp
76 ; NaNs
78 define i1 @nan0(double %arg) {
79 ; CHECK-LABEL: @nan0(
80 ; CHECK-NEXT:    ret i1 false
82   %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF
83   ret i1 %tmp
86 define i1 @nan1(double %arg) {
87 ; CHECK-LABEL: @nan1(
88 ; CHECK-NEXT:    ret i1 false
90   %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF
91   ret i1 %tmp
94 define i1 @nan2(double %arg) {
95 ; CHECK-LABEL: @nan2(
96 ; CHECK-NEXT:    ret i1 false
98   %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF
99   ret i1 %tmp
102 define i1 @nan3(double %arg) {
103 ; CHECK-LABEL: @nan3(
104 ; CHECK-NEXT:    ret i1 true
106   %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF
107   ret i1 %tmp
110 define i1 @nan4(double %arg) {
111 ; CHECK-LABEL: @nan4(
112 ; CHECK-NEXT:    ret i1 true
114   %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF
115   ret i1 %tmp
118 define i1 @nan5(double %arg) {
119 ; CHECK-LABEL: @nan5(
120 ; CHECK-NEXT:    ret i1 true
122   %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF
123   ret i1 %tmp
126 ; Negative NaN.
128 define i1 @nnan0(double %arg) {
129 ; CHECK-LABEL: @nnan0(
130 ; CHECK-NEXT:    ret i1 false
132   %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF
133   ret i1 %tmp
136 define i1 @nnan1(double %arg) {
137 ; CHECK-LABEL: @nnan1(
138 ; CHECK-NEXT:    ret i1 false
140   %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF
141   ret i1 %tmp
144 define i1 @nnan2(double %arg) {
145 ; CHECK-LABEL: @nnan2(
146 ; CHECK-NEXT:    ret i1 false
148   %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF
149   ret i1 %tmp
152 define i1 @nnan3(double %arg) {
153 ; CHECK-LABEL: @nnan3(
154 ; CHECK-NEXT:    ret i1 true
156   %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF
157   ret i1 %tmp
160 define i1 @nnan4(double %arg) {
161 ; CHECK-LABEL: @nnan4(
162 ; CHECK-NEXT:    ret i1 true
164   %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF
165   ret i1 %tmp
168 define i1 @nnan5(double %arg) {
169 ; CHECK-LABEL: @nnan5(
170 ; CHECK-NEXT:    ret i1 true
172   %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF
173   ret i1 %tmp
176 ; Negative zero.
178 define i1 @nzero0() {
179 ; CHECK-LABEL: @nzero0(
180 ; CHECK-NEXT:    ret i1 true
182   %tmp = fcmp oeq double 0.0, -0.0
183   ret i1 %tmp
186 define i1 @nzero1() {
187 ; CHECK-LABEL: @nzero1(
188 ; CHECK-NEXT:    ret i1 false
190   %tmp = fcmp ogt double 0.0, -0.0
191   ret i1 %tmp
194 ; No enlightenment here.
196 define i1 @one_with_self(double %arg) {
197 ; CHECK-LABEL: @one_with_self(
198 ; CHECK-NEXT:    ret i1 false
200   %tmp = fcmp one double %arg, %arg
201   ret i1 %tmp
204 ; These tests choose arbitrarily between float and double,
205 ; and between uge and olt, to give reasonble coverage
206 ; without combinatorial explosion.
208 define i1 @orderedLessZeroTree(float,float,float,float) {
209 ; CHECK-LABEL: @orderedLessZeroTree(
210 ; CHECK-NEXT:    ret i1 true
212   %square = fmul float %0, %0
213   %abs = call float @llvm.fabs.f32(float %1)
214   %sqrt = call float @llvm.sqrt.f32(float %2)
215   %fma = call float @llvm.fma.f32(float %3, float %3, float %sqrt)
216   %div = fdiv float %square, %abs
217   %rem = frem float %sqrt, %fma
218   %add = fadd float %div, %rem
219   %uge = fcmp uge float %add, 0.000000e+00
220   ret i1 %uge
223 define i1 @orderedLessZero_fdiv(float %x) {
224 ; CHECK-LABEL: @orderedLessZero_fdiv(
225 ; CHECK-NEXT:    ret i1 true
227   %d = fdiv float %x, %x
228   %uge = fcmp uge float %d, 0.0
229   ret i1 %uge
232 ; If x == -0.0, maxnum can return -0.0, but that still compares equal to 0.0.
234 define i1 @orderedLessZero_maxnum(float %x) {
235 ; CHECK-LABEL: @orderedLessZero_maxnum(
236 ; CHECK-NEXT:    ret i1 true
238   %d = call float @llvm.maxnum.f32(float %x, float 0.0)
239   %uge = fcmp uge float %d, 0.0
240   ret i1 %uge
243 define i1 @orderedLessZeroExpExt(float) {
244 ; CHECK-LABEL: @orderedLessZeroExpExt(
245 ; CHECK-NEXT:    ret i1 true
247   %a = call float @llvm.exp.f32(float %0)
248   %b = fpext float %a to double
249   %uge = fcmp uge double %b, 0.000000e+00
250   ret i1 %uge
253 define i1 @orderedLessZeroExp2Trunc(double) {
254 ; CHECK-LABEL: @orderedLessZeroExp2Trunc(
255 ; CHECK-NEXT:    ret i1 false
257   %a = call double @llvm.exp2.f64(double %0)
258   %b = fptrunc double %a to float
259   %olt = fcmp olt float %b, 0.000000e+00
260   ret i1 %olt
263 define i1 @orderedLessZeroPowi(double,double) {
264 ; CHECK-LABEL: @orderedLessZeroPowi(
265 ; CHECK-NEXT:    ret i1 false
267   ; Even constant exponent
268   %a = call double @llvm.powi.f64.i32(double %0, i32 2)
269   %square = fmul double %1, %1
270   ; Odd constant exponent with provably non-negative base
271   %b = call double @llvm.powi.f64.i32(double %square, i32 3)
272   %c = fadd double %a, %b
273   %olt = fcmp olt double %b, 0.000000e+00
274   ret i1 %olt
277 define i1 @UIToFP_is_nan_or_positive_or_zero(i32 %x) {
278 ; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero(
279 ; CHECK-NEXT:    ret i1 true
281   %a = uitofp i32 %x to float
282   %r = fcmp uge float %a, 0.000000e+00
283   ret i1 %r
286 define <2 x i1> @UIToFP_is_nan_or_positive_or_zero_vec(<2 x i32> %x) {
287 ; CHECK-LABEL: @UIToFP_is_nan_or_positive_or_zero_vec(
288 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
290   %a = uitofp <2 x i32> %x to <2 x float>
291   %r = fcmp uge <2 x float> %a, zeroinitializer
292   ret <2 x i1> %r
295 define i1 @UIToFP_is_positive_or_zero(i32 %x) {
296 ; CHECK-LABEL: @UIToFP_is_positive_or_zero(
297 ; CHECK-NEXT:    ret i1 true
299   %a = uitofp i32 %x to float
300   %r = fcmp oge float %a, 0.000000e+00
301   ret i1 %r
304 define <2 x i1> @UIToFP_is_positive_or_zero_vec(<2 x i32> %x) {
305 ; CHECK-LABEL: @UIToFP_is_positive_or_zero_vec(
306 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
308   %a = uitofp <2 x i32> %x to <2 x float>
309   %r = fcmp oge <2 x float> %a, zeroinitializer
310   ret <2 x i1> %r
313 define i1 @UIToFP_nnan_is_positive_or_zero(i32 %x) {
314 ; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero(
315 ; CHECK-NEXT:    ret i1 true
317   %a = uitofp i32 %x to float
318   %r = fcmp nnan oge float %a, 0.000000e+00
319   ret i1 %r
322 define <2 x i1> @UIToFP_nnan_is_positive_or_zero_vec(<2 x i32> %x) {
323 ; CHECK-LABEL: @UIToFP_nnan_is_positive_or_zero_vec(
324 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
326   %a = uitofp <2 x i32> %x to <2 x float>
327   %r = fcmp nnan oge <2 x float> %a, zeroinitializer
328   ret <2 x i1> %r
331 define i1 @UIToFP_is_not_negative(i32 %x) {
332 ; CHECK-LABEL: @UIToFP_is_not_negative(
333 ; CHECK-NEXT:    ret i1 false
335   %a = uitofp i32 %x to float
336   %r = fcmp olt float %a, 0.000000e+00
337   ret i1 %r
340 define <2 x i1> @UIToFP_is_not_negative_vec(<2 x i32> %x) {
341 ; CHECK-LABEL: @UIToFP_is_not_negative_vec(
342 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
344   %a = uitofp <2 x i32> %x to <2 x float>
345   %r = fcmp olt <2 x float> %a, zeroinitializer
346   ret <2 x i1> %r
349 ; No FMF are required for this transform.
351 define i1 @UIToFP_is_not_negative_or_nan(i32 %x) {
352 ; CHECK-LABEL: @UIToFP_is_not_negative_or_nan(
353 ; CHECK-NEXT:    ret i1 false
355   %a = uitofp i32 %x to float
356   %r = fcmp ult float %a, 0.000000e+00
357   ret i1 %r
360 define <2 x i1> @UIToFP_is_not_negative_or_nan_vec(<2 x i32> %x) {
361 ; CHECK-LABEL: @UIToFP_is_not_negative_or_nan_vec(
362 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
364   %a = uitofp <2 x i32> %x to <2 x float>
365   %r = fcmp ult <2 x float> %a, zeroinitializer
366   ret <2 x i1> %r
369 define i1 @UIToFP_nnan_is_not_negative(i32 %x) {
370 ; CHECK-LABEL: @UIToFP_nnan_is_not_negative(
371 ; CHECK-NEXT:    ret i1 false
373   %a = uitofp i32 %x to float
374   %r = fcmp nnan ult float %a, 0.000000e+00
375   ret i1 %r
378 define <2 x i1> @UIToFP_nnan_is_not_negative_vec(<2 x i32> %x) {
379 ; CHECK-LABEL: @UIToFP_nnan_is_not_negative_vec(
380 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
382   %a = uitofp <2 x i32> %x to <2 x float>
383   %r = fcmp nnan ult <2 x float> %a, zeroinitializer
384   ret <2 x i1> %r
387 define i1 @fabs_is_nan_or_positive_or_zero(double %x) {
388 ; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero(
389 ; CHECK-NEXT:    ret i1 true
391   %fabs = tail call double @llvm.fabs.f64(double %x)
392   %cmp = fcmp uge double %fabs, 0.0
393   ret i1 %cmp
396 define <2 x i1> @fabs_is_nan_or_positive_or_zero_vec(<2 x double> %x) {
397 ; CHECK-LABEL: @fabs_is_nan_or_positive_or_zero_vec(
398 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
400   %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
401   %cmp = fcmp uge <2 x double> %fabs, zeroinitializer
402   ret <2 x i1> %cmp
405 define i1 @fabs_nnan_is_positive_or_zero(double %x) {
406 ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero(
407 ; CHECK-NEXT:    ret i1 true
409   %fabs = tail call nnan double @llvm.fabs.f64(double %x)
410   %cmp = fcmp oge double %fabs, 0.0
411   ret i1 %cmp
414 define <2 x i1> @fabs_nnan_is_positive_or_zero_vec(<2 x double> %x) {
415 ; CHECK-LABEL: @fabs_nnan_is_positive_or_zero_vec(
416 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
418   %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
419   %cmp = fcmp oge <2 x double> %fabs, zeroinitializer
420   ret <2 x i1> %cmp
423 define i1 @fabs_fcmp-nnan_is_positive_or_zero(double %x) {
424 ; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero(
425 ; CHECK-NEXT:    ret i1 true
427   %fabs = tail call double @llvm.fabs.f64(double %x)
428   %cmp = fcmp nnan oge double %fabs, 0.0
429   ret i1 %cmp
432 define i1 @fabs_fcmp_oge0-assume-nnan_is_positive_or_zero(double %x) {
433 ; CHECK-LABEL: @fabs_fcmp_oge0-assume-nnan_is_positive_or_zero(
434 ; CHECK-NEXT:    [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
435 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord double [[FABS]], 0.000000e+00
436 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
437 ; CHECK-NEXT:    ret i1 true
439   %fabs = tail call double @llvm.fabs.f64(double %x)
440   %ord = fcmp ord double %fabs, 0.0
441   call void @llvm.assume(i1 %ord)
442   %cmp = fcmp oge double %fabs, 0.0
443   ret i1 %cmp
446 define i1 @fabs_fcmp_olt0_-assume-nnan_is_positive_or_zero(double %x) {
447 ; CHECK-LABEL: @fabs_fcmp_olt0_-assume-nnan_is_positive_or_zero(
448 ; CHECK-NEXT:    [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
449 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord double [[FABS]], 0.000000e+00
450 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
451 ; CHECK-NEXT:    ret i1 false
453   %fabs = tail call double @llvm.fabs.f64(double %x)
454   %ord = fcmp ord double %fabs, 0.0
455   call void @llvm.assume(i1 %ord)
456   %cmp = fcmp olt double %fabs, 0.0
457   ret i1 %cmp
460 define <2 x i1> @fabs_fcmp-nnan_is_positive_or_zero_vec(<2 x double> %x) {
461 ; CHECK-LABEL: @fabs_fcmp-nnan_is_positive_or_zero_vec(
462 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
464   %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
465   %cmp = fcmp nnan oge <2 x double> %fabs, zeroinitializer
466   ret <2 x i1> %cmp
469 define i1 @fabs_is_not_negative(double %x) {
470 ; CHECK-LABEL: @fabs_is_not_negative(
471 ; CHECK-NEXT:    ret i1 false
473   %fabs = tail call double @llvm.fabs.f64(double %x)
474   %cmp = fcmp olt double %fabs, 0.0
475   ret i1 %cmp
478 define <2 x i1> @fabs_is_not_negative_vec(<2 x double> %x) {
479 ; CHECK-LABEL: @fabs_is_not_negative_vec(
480 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
482   %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
483   %cmp = fcmp olt <2 x double> %fabs, zeroinitializer
484   ret <2 x i1> %cmp
487 define i1 @fabs_nnan_is_not_negative(double %x) {
488 ; CHECK-LABEL: @fabs_nnan_is_not_negative(
489 ; CHECK-NEXT:    ret i1 false
491   %fabs = tail call nnan double @llvm.fabs.f64(double %x)
492   %cmp = fcmp ult double %fabs, 0.0
493   ret i1 %cmp
496 define <2 x i1> @fabs_nnan_is_not_negative_vec(<2 x double> %x) {
497 ; CHECK-LABEL: @fabs_nnan_is_not_negative_vec(
498 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
500   %fabs = tail call nnan <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
501   %cmp = fcmp ult <2 x double> %fabs, zeroinitializer
502   ret <2 x i1> %cmp
505 define i1 @fabs_fcmp-nnan_is_not_negative(double %x) {
506 ; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative(
507 ; CHECK-NEXT:    ret i1 false
509   %fabs = tail call double @llvm.fabs.f64(double %x)
510   %cmp = fcmp nnan ult double %fabs, 0.0
511   ret i1 %cmp
514 define <2 x i1> @fabs_fcmp-nnan_is_not_negative_vec(<2 x double> %x) {
515 ; CHECK-LABEL: @fabs_fcmp-nnan_is_not_negative_vec(
516 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
518   %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
519   %cmp = fcmp nnan ult <2 x double> %fabs, zeroinitializer
520   ret <2 x i1> %cmp
523 define <2 x i1> @fabs_is_not_negative_negzero(<2 x float> %V) {
524 ; CHECK-LABEL: @fabs_is_not_negative_negzero(
525 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
527   %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
528   %cmp = fcmp olt <2 x float> %abs, <float -0.0, float -0.0>
529   ret <2 x i1> %cmp
532 define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) {
533 ; CHECK-LABEL: @fabs_is_not_negative_poszero(
534 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
536   %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
537   %cmp = fcmp olt <2 x float> %abs, <float 0.0, float 0.0>
538   ret <2 x i1> %cmp
541 define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) {
542 ; CHECK-LABEL: @fabs_is_not_negative_anyzero(
543 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
545   %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V)
546   %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0>
547   ret <2 x i1> %cmp
550 define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) {
551 ; CHECK-LABEL: @fabs_is_not_negative_negzero_undef(
552 ; CHECK-NEXT:    ret <3 x i1> zeroinitializer
554   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
555   %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float undef>
556   ret <3 x i1> %cmp
559 define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) {
560 ; CHECK-LABEL: @fabs_is_not_negative_poszero_undef(
561 ; CHECK-NEXT:    ret <3 x i1> zeroinitializer
563   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
564   %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float undef>
565   ret <3 x i1> %cmp
568 define <3 x i1> @fabs_is_not_negative_anyzero_undef(<3 x float> %V) {
569 ; CHECK-LABEL: @fabs_is_not_negative_anyzero_undef(
570 ; CHECK-NEXT:    ret <3 x i1> zeroinitializer
572   %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V)
573   %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float undef>
574   ret <3 x i1> %cmp
577 define i1 @orderedLessZeroSelect(float, float) {
578 ; CHECK-LABEL: @orderedLessZeroSelect(
579 ; CHECK-NEXT:    ret i1 true
581   %a = call float @llvm.exp.f32(float %0)
582   %b = call float @llvm.fabs.f32(float %1)
583   %c = fcmp olt float %0, %1
584   %d = select i1 %c, float %a, float %b
585   %e = fadd float %d, 1.0
586   %uge = fcmp uge float %e, 0.000000e+00
587   ret i1 %uge
590 define i1 @orderedLessZeroMinNum(float, float) {
591 ; CHECK-LABEL: @orderedLessZeroMinNum(
592 ; CHECK-NEXT:    ret i1 true
594   %a = call float @llvm.exp.f32(float %0)
595   %b = call float @llvm.fabs.f32(float %1)
596   %c = call float @llvm.minnum.f32(float %a, float %b)
597   %uge = fcmp uge float %c, 0.000000e+00
598   ret i1 %uge
601 ; PR37776: https://bugs.llvm.org/show_bug.cgi?id=37776
602 ; exp() may return nan, leaving %1 as the unknown result, so we can't simplify.
604 define i1 @orderedLessZeroMaxNum(float, float) {
605 ; CHECK-LABEL: @orderedLessZeroMaxNum(
606 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.exp.f32(float [[TMP0:%.*]])
607 ; CHECK-NEXT:    [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[TMP1:%.*]])
608 ; CHECK-NEXT:    [[UGE:%.*]] = fcmp uge float [[B]], 0.000000e+00
609 ; CHECK-NEXT:    ret i1 [[UGE]]
611   %a = call float @llvm.exp.f32(float %0)
612   %b = call float @llvm.maxnum.f32(float %a, float %1)
613   %uge = fcmp uge float %b, 0.000000e+00
614   ret i1 %uge
617 ; But using maximum, we can simplify, since the NaN would be propagated
619 define i1 @orderedLessZeroMaximum(float, float) {
620 ; CHECK-LABEL: @orderedLessZeroMaximum(
621 ; CHECK-NEXT:    ret i1 true
623   %a = call float @llvm.exp.f32(float %0)
624   %b = call float @llvm.maximum.f32(float %a, float %1)
625   %uge = fcmp uge float %b, 0.000000e+00
626   ret i1 %uge
629 define i1 @minnum_non_nan(float %x) {
630 ; CHECK-LABEL: @minnum_non_nan(
631 ; CHECK-NEXT:    ret i1 true
633   %min = call float @llvm.minnum.f32(float 0.5, float %x)
634   %cmp = fcmp ord float %min, 1.0
635   ret i1 %cmp
638 define i1 @maxnum_non_nan(float %x) {
639 ; CHECK-LABEL: @maxnum_non_nan(
640 ; CHECK-NEXT:    ret i1 false
642   %min = call float @llvm.maxnum.f32(float %x, float 42.0)
643   %cmp = fcmp uno float %min, 12.0
644   ret i1 %cmp
647 define i1 @assume_nonnan_ord(float %x) {
648 ; CHECK-LABEL: @assume_nonnan_ord(
649 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
650 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
651 ; CHECK-NEXT:    ret i1 true
653   %ord = fcmp ord float %x, 0.0
654   call void @llvm.assume(i1 %ord)
655   %cmp = fcmp ord float %x, 1.0
656   ret i1 %cmp
659 define i1 @assume_nonnan_x2_ord(float %x, float %y) {
660 ; CHECK-LABEL: @assume_nonnan_x2_ord(
661 ; CHECK-NEXT:    [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
662 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_X]])
663 ; CHECK-NEXT:    [[ORD_Y:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00
664 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_Y]])
665 ; CHECK-NEXT:    ret i1 true
667   %ord.x = fcmp ord float %x, 0.0
668   call void @llvm.assume(i1 %ord.x)
669   %ord.y = fcmp ord float %y, 0.0
670   call void @llvm.assume(i1 %ord.y)
671   %cmp = fcmp ord float %x, %y
672   ret i1 %cmp
675 define i1 @assume_nonan_x2_uno(float %x, float %y) {
676 ; CHECK-LABEL: @assume_nonan_x2_uno(
677 ; CHECK-NEXT:    [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
678 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_X]])
679 ; CHECK-NEXT:    [[ORD_Y:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00
680 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_Y]])
681 ; CHECK-NEXT:    ret i1 false
683   %ord.x = fcmp ord float %x, 0.0
684   call void @llvm.assume(i1 %ord.x)
685   %ord.y = fcmp ord float %y, 0.0
686   call void @llvm.assume(i1 %ord.y)
687   %cmp = fcmp uno float %x, %y
688   ret i1 %cmp
691 define i1 @assume_nan_ord(float %x) {
692 ; CHECK-LABEL: @assume_nan_ord(
693 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
694 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
695 ; CHECK-NEXT:    ret i1 false
697   %uno = fcmp uno float %x, 0.0
698   call void @llvm.assume(i1 %uno)
699   %cmp = fcmp ord float %x, 1.0
700   ret i1 %cmp
703 define i1 @assume_nonnan_uno(float %x) {
704 ; CHECK-LABEL: @assume_nonnan_uno(
705 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
706 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
707 ; CHECK-NEXT:    ret i1 false
709   %ord = fcmp ord float %x, 0.0
710   call void @llvm.assume(i1 %ord)
711   %cmp = fcmp uno float %x, 1.0
712   ret i1 %cmp
715 define i1 @assume_nan_uno(float %x) {
716 ; CHECK-LABEL: @assume_nan_uno(
717 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
718 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
719 ; CHECK-NEXT:    ret i1 true
721   %uno = fcmp uno float %x, 0.0
722   call void @llvm.assume(i1 %uno)
723   %cmp = fcmp uno float %x, 1.0
724   ret i1 %cmp
727 ; min(x, 0.5) == 1.0 --> false
729 define i1 @minnum_oeq_small_min_constant(float %x) {
730 ; CHECK-LABEL: @minnum_oeq_small_min_constant(
731 ; CHECK-NEXT:    ret i1 false
733   %min = call float @llvm.minnum.f32(float %x, float 0.5)
734   %cmp = fcmp oeq float %min, 1.0
735   ret i1 %cmp
738 ; min(x, 0.5) > 1.0 --> false
740 define i1 @minnum_ogt_small_min_constant(float %x) {
741 ; CHECK-LABEL: @minnum_ogt_small_min_constant(
742 ; CHECK-NEXT:    ret i1 false
744   %min = call float @llvm.minnum.f32(float %x, float 0.5)
745   %cmp = fcmp ogt float %min, 1.0
746   ret i1 %cmp
749 ; min(x, 0.5) >= 1.0 --> false
751 define i1 @minnum_oge_small_min_constant(float %x) {
752 ; CHECK-LABEL: @minnum_oge_small_min_constant(
753 ; CHECK-NEXT:    ret i1 false
755   %min = call float @llvm.minnum.f32(float %x, float 0.5)
756   %cmp = fcmp oge float %min, 1.0
757   ret i1 %cmp
760 ; min(x, 0.5) == 1.0 --> false
762 define i1 @minnum_ueq_small_min_constant(float %x) {
763 ; CHECK-LABEL: @minnum_ueq_small_min_constant(
764 ; CHECK-NEXT:    ret i1 false
766   %min = call float @llvm.minnum.f32(float %x, float 0.5)
767   %cmp = fcmp ueq float %min, 1.0
768   ret i1 %cmp
771 ; min(x, 0.5) > 1.0 --> false
773 define i1 @minnum_ugt_small_min_constant(float %x) {
774 ; CHECK-LABEL: @minnum_ugt_small_min_constant(
775 ; CHECK-NEXT:    ret i1 false
777   %min = call float @llvm.minnum.f32(float %x, float 0.5)
778   %cmp = fcmp ugt float %min, 1.0
779   ret i1 %cmp
782 ; min(x, 0.5) >= 1.0 --> false
784 define <2 x i1> @minnum_uge_small_min_constant(<2 x float> %x) {
785 ; CHECK-LABEL: @minnum_uge_small_min_constant(
786 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
788   %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
789   %cmp = fcmp uge <2 x float> %min, <float 1.0, float 1.0>
790   ret <2 x i1> %cmp
793 ; min(x, 0.5) < 1.0 --> true
795 define <2 x i1> @minnum_olt_small_min_constant(<2 x float> %x) {
796 ; CHECK-LABEL: @minnum_olt_small_min_constant(
797 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
799   %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
800   %cmp = fcmp olt <2 x float> %min, <float 1.0, float 1.0>
801   ret <2 x i1> %cmp
804 ; min(x, 0.5) <= 1.0 --> true
806 define i1 @minnum_ole_small_min_constant(float %x) {
807 ; CHECK-LABEL: @minnum_ole_small_min_constant(
808 ; CHECK-NEXT:    ret i1 true
810   %min = call float @llvm.minnum.f32(float %x, float 0.5)
811   %cmp = fcmp ole float %min, 1.0
812   ret i1 %cmp
815 ; min(x, 0.5) != 1.0 --> true
817 define i1 @minnum_one_small_min_constant(float %x) {
818 ; CHECK-LABEL: @minnum_one_small_min_constant(
819 ; CHECK-NEXT:    ret i1 true
821   %min = call float @llvm.minnum.f32(float %x, float 0.5)
822   %cmp = fcmp one float %min, 1.0
823   ret i1 %cmp
826 ; min(x, 0.5) < 1.0 --> true
828 define i1 @minnum_ult_small_min_constant(float %x) {
829 ; CHECK-LABEL: @minnum_ult_small_min_constant(
830 ; CHECK-NEXT:    ret i1 true
832   %min = call float @llvm.minnum.f32(float %x, float 0.5)
833   %cmp = fcmp ult float %min, 1.0
834   ret i1 %cmp
837 ; min(x, 0.5) <= 1.0 --> true
839 define i1 @minnum_ule_small_min_constant(float %x) {
840 ; CHECK-LABEL: @minnum_ule_small_min_constant(
841 ; CHECK-NEXT:    ret i1 true
843   %min = call float @llvm.minnum.f32(float %x, float 0.5)
844   %cmp = fcmp ule float %min, 1.0
845   ret i1 %cmp
848 ; min(x, 0.5) != 1.0 --> true
850 define i1 @minnum_une_small_min_constant(float %x) {
851 ; CHECK-LABEL: @minnum_une_small_min_constant(
852 ; CHECK-NEXT:    ret i1 true
854   %min = call float @llvm.minnum.f32(float %x, float 0.5)
855   %cmp = fcmp une float %min, 1.0
856   ret i1 %cmp
859 ; Negative test:
860 ; min(x, 1.0) != 1.0 --> ?
862 define i1 @minnum_une_equal_min_constant(float %x) {
863 ; CHECK-LABEL: @minnum_une_equal_min_constant(
864 ; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00)
865 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
866 ; CHECK-NEXT:    ret i1 [[CMP]]
868   %min = call float @llvm.minnum.f32(float %x, float 1.0)
869   %cmp = fcmp une float %min, 1.0
870   ret i1 %cmp
873 ; Negative test:
874 ; min(x, 2.0) != 1.0 --> ?
876 define i1 @minnum_une_large_min_constant(float %x) {
877 ; CHECK-LABEL: @minnum_une_large_min_constant(
878 ; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.000000e+00)
879 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
880 ; CHECK-NEXT:    ret i1 [[CMP]]
882   %min = call float @llvm.minnum.f32(float %x, float 2.0)
883   %cmp = fcmp une float %min, 1.0
884   ret i1 %cmp
887 ; Partial negative test (the minnum simplifies):
888 ; min(x, NaN) != 1.0 --> x != 1.0
890 define i1 @minnum_une_nan_min_constant(float %x) {
891 ; CHECK-LABEL: @minnum_une_nan_min_constant(
892 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
893 ; CHECK-NEXT:    ret i1 [[CMP]]
895   %min = call float @llvm.minnum.f32(float %x, float 0x7FF8000000000000)
896   %cmp = fcmp une float %min, 1.0
897   ret i1 %cmp
900 ; max(x, 1.5) == 1.0 --> false
902 define i1 @maxnum_oeq_large_max_constant(float %x) {
903 ; CHECK-LABEL: @maxnum_oeq_large_max_constant(
904 ; CHECK-NEXT:    ret i1 false
906   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
907   %cmp = fcmp oeq float %max, 1.0
908   ret i1 %cmp
911 ; max(x, 1.5) < 1.0 --> false
913 define i1 @maxnum_olt_large_max_constant(float %x) {
914 ; CHECK-LABEL: @maxnum_olt_large_max_constant(
915 ; CHECK-NEXT:    ret i1 false
917   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
918   %cmp = fcmp olt float %max, 1.0
919   ret i1 %cmp
922 ; max(x, 1.5) <= 1.0 --> false
924 define i1 @maxnum_ole_large_max_constant(float %x) {
925 ; CHECK-LABEL: @maxnum_ole_large_max_constant(
926 ; CHECK-NEXT:    ret i1 false
928   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
929   %cmp = fcmp ole float %max, 1.0
930   ret i1 %cmp
933 ; max(x, 1.5) == 1.0 --> false
935 define i1 @maxnum_ueq_large_max_constant(float %x) {
936 ; CHECK-LABEL: @maxnum_ueq_large_max_constant(
937 ; CHECK-NEXT:    ret i1 false
939   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
940   %cmp = fcmp ueq float %max, 1.0
941   ret i1 %cmp
944 ; max(x, 1.5) < 1.0 --> false
946 define i1 @maxnum_ult_large_max_constant(float %x) {
947 ; CHECK-LABEL: @maxnum_ult_large_max_constant(
948 ; CHECK-NEXT:    ret i1 false
950   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
951   %cmp = fcmp ult float %max, 1.0
952   ret i1 %cmp
955 ; max(x, 1.5) <= 1.0 --> false
957 define <2 x i1> @maxnum_ule_large_max_constant(<2 x float> %x) {
958 ; CHECK-LABEL: @maxnum_ule_large_max_constant(
959 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
961   %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
962   %cmp = fcmp ule <2 x float> %max, <float 1.0, float 1.0>
963   ret <2 x i1> %cmp
966 ; max(x, 1.5) > 1.0 --> true
968 define <2 x i1> @maxnum_ogt_large_max_constant(<2 x float> %x) {
969 ; CHECK-LABEL: @maxnum_ogt_large_max_constant(
970 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
972   %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
973   %cmp = fcmp ogt <2 x float> %max, <float 1.0, float 1.0>
974   ret <2 x i1> %cmp
977 ; max(x, 1.5) >= 1.0 --> true
979 define i1 @maxnum_oge_large_max_constant(float %x) {
980 ; CHECK-LABEL: @maxnum_oge_large_max_constant(
981 ; CHECK-NEXT:    ret i1 true
983   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
984   %cmp = fcmp oge float %max, 1.0
985   ret i1 %cmp
988 ; max(x, 1.5) != 1.0 --> true
990 define i1 @maxnum_one_large_max_constant(float %x) {
991 ; CHECK-LABEL: @maxnum_one_large_max_constant(
992 ; CHECK-NEXT:    ret i1 true
994   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
995   %cmp = fcmp one float %max, 1.0
996   ret i1 %cmp
999 ; max(x, 1.5) > 1.0 --> true
1001 define i1 @maxnum_ugt_large_max_constant(float %x) {
1002 ; CHECK-LABEL: @maxnum_ugt_large_max_constant(
1003 ; CHECK-NEXT:    ret i1 true
1005   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1006   %cmp = fcmp ugt float %max, 1.0
1007   ret i1 %cmp
1010 ; max(x, 1.5) >= 1.0 --> true
1012 define i1 @maxnum_uge_large_max_constant(float %x) {
1013 ; CHECK-LABEL: @maxnum_uge_large_max_constant(
1014 ; CHECK-NEXT:    ret i1 true
1016   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1017   %cmp = fcmp uge float %max, 1.0
1018   ret i1 %cmp
1021 ; max(x, 1.5) != 1.0 --> true
1023 define i1 @maxnum_une_large_max_constant(float %x) {
1024 ; CHECK-LABEL: @maxnum_une_large_max_constant(
1025 ; CHECK-NEXT:    ret i1 true
1027   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1028   %cmp = fcmp une float %max, 1.0
1029   ret i1 %cmp
1032 ; Negative test:
1033 ; max(x, 1.0) != 1.0 --> ?
1035 define i1 @maxnum_une_equal_max_constant(float %x) {
1036 ; CHECK-LABEL: @maxnum_une_equal_max_constant(
1037 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
1038 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
1039 ; CHECK-NEXT:    ret i1 [[CMP]]
1041   %max = call float @llvm.maxnum.f32(float %x, float 1.0)
1042   %cmp = fcmp une float %max, 1.0
1043   ret i1 %cmp
1046 ; Negative test:
1047 ; max(x, 0.5) != 1.0 --> ?
1049 define i1 @maxnum_une_small_max_constant(float %x) {
1050 ; CHECK-LABEL: @maxnum_une_small_max_constant(
1051 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 5.000000e-01)
1052 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
1053 ; CHECK-NEXT:    ret i1 [[CMP]]
1055   %max = call float @llvm.maxnum.f32(float %x, float 0.5)
1056   %cmp = fcmp une float %max, 1.0
1057   ret i1 %cmp
1060 ; Partial negative test (the maxnum simplifies):
1061 ; max(x, NaN) != 1.0 --> x != 1.0
1063 define i1 @maxnum_une_nan_max_constant(float %x) {
1064 ; CHECK-LABEL: @maxnum_une_nan_max_constant(
1065 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
1066 ; CHECK-NEXT:    ret i1 [[CMP]]
1068   %max = call float @llvm.maxnum.f32(float %x, float 0x7FF8000000000000)
1069   %cmp = fcmp une float %max, 1.0
1070   ret i1 %cmp
1073 define i1 @known_positive_olt_with_negative_constant(double %a) {
1074 ; CHECK-LABEL: @known_positive_olt_with_negative_constant(
1075 ; CHECK-NEXT:    ret i1 false
1077   %call = call double @llvm.fabs.f64(double %a)
1078   %cmp = fcmp olt double %call, -1.0
1079   ret i1 %cmp
1082 define i1 @known_positive_nsz_olt_with_negative_constant(double %mag, double %a) {
1083 ; CHECK-LABEL: @known_positive_nsz_olt_with_negative_constant(
1084 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1085 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1086 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00
1087 ; CHECK-NEXT:    ret i1 [[CMP]]
1089   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1090   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1091   %cmp = fcmp olt double %copysign, -1.0
1092   ret i1 %cmp
1095 define i1 @known_positive_maybe_neg0_olt_with_negative_constant(double %mag, double %a) {
1096 ; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_negative_constant(
1097 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1098 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1099 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00
1100 ; CHECK-NEXT:    ret i1 [[CMP]]
1102   %sqrt = call double @llvm.sqrt.f64(double %a)
1103   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1104   %cmp = fcmp olt double %copysign, -1.0
1105   ret i1 %cmp
1108 define i1 @known_positive_nsz_uge_with_negative_constant(double %mag, double %a) {
1109 ; CHECK-LABEL: @known_positive_nsz_uge_with_negative_constant(
1110 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1111 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1112 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00
1113 ; CHECK-NEXT:    ret i1 [[CMP]]
1115   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1116   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1117   %cmp = fcmp uge double %copysign, -1.0
1118   ret i1 %cmp
1121 define i1 @known_positive_maybe_neg0_uge_with_negative_constant(double %mag, double %a) {
1122 ; CHECK-LABEL: @known_positive_maybe_neg0_uge_with_negative_constant(
1123 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1124 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1125 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00
1126 ; CHECK-NEXT:    ret i1 [[CMP]]
1128   %sqrt = call double @llvm.sqrt.f64(double %a)
1129   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1130   %cmp = fcmp uge double %copysign, -1.0
1131   ret i1 %cmp
1134 define i1 @known_positive_nsz_oge_with_zero_constant(double %mag, double %a) {
1135 ; CHECK-LABEL: @known_positive_nsz_oge_with_zero_constant(
1136 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1137 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1138 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00
1139 ; CHECK-NEXT:    ret i1 [[CMP]]
1141   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1142   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1143   %cmp = fcmp oge double %copysign, 0.0
1144   ret i1 %cmp
1147 define i1 @known_positive_maybe_neg0_oge_with_zero_constant(double %mag, double %a) {
1148 ; CHECK-LABEL: @known_positive_maybe_neg0_oge_with_zero_constant(
1149 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1150 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1151 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00
1152 ; CHECK-NEXT:    ret i1 [[CMP]]
1154   %sqrt = call double @llvm.sqrt.f64(double %a)
1155   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1156   %cmp = fcmp oge double %copysign, 0.0
1157   ret i1 %cmp
1160 define i1 @known_positive_nsz_olt_with_zero_constant(double %mag, double %a) {
1161 ; CHECK-LABEL: @known_positive_nsz_olt_with_zero_constant(
1162 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1163 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1164 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00
1165 ; CHECK-NEXT:    ret i1 [[CMP]]
1167   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1168   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1169   %cmp = fcmp olt double %copysign, 0.0
1170   ret i1 %cmp
1173 define i1 @known_positive_maybe_neg0_olt_with_zero_constant(double %mag, double %a) {
1174 ; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_zero_constant(
1175 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1176 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1177 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00
1178 ; CHECK-NEXT:    ret i1 [[CMP]]
1180   %sqrt = call double @llvm.sqrt.f64(double %a)
1181   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1182   %cmp = fcmp olt double %copysign, 0.0
1183   ret i1 %cmp
1186 define i1 @assumed_positive_olt_with_negative_constant(double %a) {
1187 ; CHECK-LABEL: @assumed_positive_olt_with_negative_constant(
1188 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1189 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1190 ; CHECK-NEXT:    ret i1 false
1192   %assume.cmp = fcmp oge double %a, 0.0
1193   call void @llvm.assume(i1 %assume.cmp)
1194   %cmp = fcmp olt double %a, -1.0
1195   ret i1 %cmp
1198 define i1 @assumed_positive_ole_with_negative_constant(double %a) {
1199 ; CHECK-LABEL: @assumed_positive_ole_with_negative_constant(
1200 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1201 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1202 ; CHECK-NEXT:    ret i1 false
1204   %assume.cmp = fcmp oge double %a, 0.0
1205   call void @llvm.assume(i1 %assume.cmp)
1206   %cmp = fcmp ole double %a, -1.0
1207   ret i1 %cmp
1210 define i1 @assumed_positive_oeq_with_negative_constant(double %a) {
1211 ; CHECK-LABEL: @assumed_positive_oeq_with_negative_constant(
1212 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1213 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1214 ; CHECK-NEXT:    ret i1 false
1216   %assume.cmp = fcmp oge double %a, 0.0
1217   call void @llvm.assume(i1 %assume.cmp)
1218   %cmp = fcmp oeq double %a, -1.0
1219   ret i1 %cmp
1222 define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) {
1223 ; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec(
1224 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1226   %call = uitofp <2 x i32> %a to <2 x double>
1227   %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0>
1228   ret <2 x i1> %cmp
1231 define i1 @known_positive_ugt_with_negative_constant(i32 %a) {
1232 ; CHECK-LABEL: @known_positive_ugt_with_negative_constant(
1233 ; CHECK-NEXT:    ret i1 true
1235   %call = uitofp i32 %a to float
1236   %cmp = fcmp ugt float %call, -3.0
1237   ret i1 %cmp
1240 define i1 @assumed_positive_ugt_with_negative_constant(float %a) {
1241 ; CHECK-LABEL: @assumed_positive_ugt_with_negative_constant(
1242 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1243 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1244 ; CHECK-NEXT:    ret i1 true
1246   %assume.cmp = fcmp ogt float %a, 0.0
1247   call void @llvm.assume(i1 %assume.cmp)
1248   %cmp = fcmp ugt float %a, -3.0
1249   ret i1 %cmp
1252 define i1 @assumed_positive_uge_with_negative_constant(float %a) {
1253 ; CHECK-LABEL: @assumed_positive_uge_with_negative_constant(
1254 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1255 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1256 ; CHECK-NEXT:    ret i1 true
1258   %assume.cmp = fcmp ogt float %a, 0.0
1259   call void @llvm.assume(i1 %assume.cmp)
1260   %cmp = fcmp uge float %a, -3.0
1261   ret i1 %cmp
1264 define i1 @assumed_positive_une_with_negative_constant(float %a) {
1265 ; CHECK-LABEL: @assumed_positive_une_with_negative_constant(
1266 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1267 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1268 ; CHECK-NEXT:    ret i1 true
1270   %assume.cmp = fcmp ogt float %a, 0.0
1271   call void @llvm.assume(i1 %assume.cmp)
1272   %cmp = fcmp une float %a, -3.0
1273   ret i1 %cmp
1276 define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) {
1277 ; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec(
1278 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1280   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
1281   %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0>
1282   ret <2 x i1> %cmp
1285 define i1 @known_positive_oeq_with_negative_constant(half %a) {
1286 ; CHECK-LABEL: @known_positive_oeq_with_negative_constant(
1287 ; CHECK-NEXT:    ret i1 false
1289   %call = call half @llvm.fabs.f16(half %a)
1290   %cmp = fcmp oeq half %call, -5.0
1291   ret i1 %cmp
1294 define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) {
1295 ; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec(
1296 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1298   %call = uitofp <2 x i32> %a to <2 x half>
1299   %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0>
1300   ret <2 x i1> %cmp
1303 define i1 @pr58046(i64 %arg) {
1304 ; CHECK-LABEL: @pr58046(
1305 ; CHECK-NEXT:    ret i1 true
1307   %fp = uitofp i64 %arg to double
1308   %mul = fmul double -0.000000e+00, %fp
1309   %div = fdiv double 1.000000e+00, %mul
1310   %cmp = fcmp oeq double %div, 0xFFF0000000000000
1311   ret i1 %cmp
1314 define i1 @nonans1(double %in1, double %in2) {
1315 ; CHECK-LABEL: @nonans1(
1316 ; CHECK-NEXT:    ret i1 false
1318   %cmp = fcmp nnan uno double %in1, %in2
1319   ret i1 %cmp
1322 define i1 @nonans2(double %in1, double %in2) {
1323 ; CHECK-LABEL: @nonans2(
1324 ; CHECK-NEXT:    ret i1 true
1326   %cmp = fcmp nnan ord double %in1, %in2
1327   ret i1 %cmp
1330 define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) {
1331 ; CHECK-LABEL: @orderedCompareWithNaNVector(
1332 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1334   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
1335   ret <2 x i1> %cmp
1338 define <2 x i1> @orderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
1339 ; CHECK-LABEL: @orderedCompareWithNaNVector_undef_elt(
1340 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1342   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double undef>
1343   ret <2 x i1> %cmp
1346 define <2 x i1> @unorderedCompareWithNaNVector_undef_elt(<2 x double> %A) {
1347 ; CHECK-LABEL: @unorderedCompareWithNaNVector_undef_elt(
1348 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1350   %cmp = fcmp ult <2 x double> %A, <double undef, double 0xFFFFFFFFFFFFFFFF>
1351   ret <2 x i1> %cmp
1354 define i1 @is_infinite(float %x) {
1355 ; CHECK-LABEL: @is_infinite(
1356 ; CHECK-NEXT:    ret i1 false
1358   %xabs = call ninf float @llvm.fabs.f32(float %x)
1359   %r = fcmp oeq float %xabs, 0x7FF0000000000000
1360   ret i1 %r
1363 define i1 @is_infinite_assumed_finite(float %x) {
1364 ; CHECK-LABEL: @is_infinite_assumed_finite(
1365 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1366 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1367 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
1368 ; CHECK-NEXT:    ret i1 false
1370   %xabs = call float @llvm.fabs.f32(float %x)
1371   %not.inf = fcmp one float %xabs, 0x7FF0000000000000
1372   call void @llvm.assume(i1 %not.inf)
1373   %r = fcmp oeq float %xabs, 0x7FF0000000000000
1374   ret i1 %r
1377 define i1 @une_inf_assumed_not_inf(float %x) {
1378 ; CHECK-LABEL: @une_inf_assumed_not_inf(
1379 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1380 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1381 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
1382 ; CHECK-NEXT:    ret i1 true
1384   %xabs = call float @llvm.fabs.f32(float %x)
1385   %not.inf = fcmp one float %xabs, 0x7FF0000000000000
1386   call void @llvm.assume(i1 %not.inf)
1387   %r = fcmp une float %xabs, 0x7FF0000000000000
1388   ret i1 %r
1391 define <2 x i1> @is_infinite_neg(<2 x float> %x) {
1392 ; CHECK-LABEL: @is_infinite_neg(
1393 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1395   %x42 = fadd ninf <2 x float> %x, <float 42.0, float 42.0>
1396   %r = fcmp oeq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1397   ret <2 x i1> %r
1400 ; Negative test - but this could be reduced to 'uno' outside of instsimplify.
1402 define i1 @is_infinite_or_nan(float %x) {
1403 ; CHECK-LABEL: @is_infinite_or_nan(
1404 ; CHECK-NEXT:    [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01
1405 ; CHECK-NEXT:    [[R:%.*]] = fcmp ueq float [[X42]], 0xFFF0000000000000
1406 ; CHECK-NEXT:    ret i1 [[R]]
1408   %x42 = fadd ninf float %x, 42.0
1409   %r = fcmp ueq float %x42, 0xFFF0000000000000
1410   ret i1 %r
1413 define i1 @is_infinite_or_nan2(float %x) {
1414 ; CHECK-LABEL: @is_infinite_or_nan2(
1415 ; CHECK-NEXT:    ret i1 false
1417   %xabs = call nnan ninf float @llvm.fabs.f32(float %x)
1418   %r = fcmp ueq float %xabs, 0x7FF0000000000000
1419   ret i1 %r
1422 define i1 @is_infinite_or_nan2_assume(float %x) {
1423 ; CHECK-LABEL: @is_infinite_or_nan2_assume(
1424 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1425 ; CHECK-NEXT:    [[IS_INF_OR_NAN:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1426 ; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_INF_OR_NAN]])
1427 ; CHECK-NEXT:    ret i1 false
1429   %xabs = call float @llvm.fabs.f32(float %x)
1430   %is.inf.or.nan = fcmp one float %xabs, 0x7FF0000000000000
1431   call void @llvm.assume(i1 %is.inf.or.nan)
1432   %r = fcmp ueq float %xabs, 0x7FF0000000000000
1433   ret i1 %r
1436 define <2 x i1> @is_infinite_neg_or_nan(<2 x float> %x) {
1437 ; CHECK-LABEL: @is_infinite_neg_or_nan(
1438 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1440   %x42 = fadd nnan ninf <2 x float> %x, <float 42.0, float 42.0>
1441   %r = fcmp ueq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1442   ret <2 x i1> %r
1445 define i1 @is_finite_or_nan(i1 %c, double %x) {
1446 ; CHECK-LABEL: @is_finite_or_nan(
1447 ; CHECK-NEXT:    ret i1 true
1449   %xx = fmul ninf double %x, %x
1450   %s = select i1 %c, double 42.0, double %xx
1451   %r = fcmp une double %s, 0x7FF0000000000000
1452   ret i1 %r
1455 define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) {
1456 ; CHECK-LABEL: @is_finite_or_nan_commute(
1457 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1459   %cast = uitofp <2 x i8> %x to <2 x float>
1460   %r = fcmp une <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1461   ret <2 x i1> %r
1464 ; Negative test - but this could be reduced to 'ord' outside of instsimplify.
1466 define i1 @is_finite_and_ordered(double %x) {
1467 ; CHECK-LABEL: @is_finite_and_ordered(
1468 ; CHECK-NEXT:    [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]]
1469 ; CHECK-NEXT:    [[R:%.*]] = fcmp one double [[XX]], 0x7FF0000000000000
1470 ; CHECK-NEXT:    ret i1 [[R]]
1472   %xx = fmul ninf double %x, %x
1473   %r = fcmp one double %xx, 0x7FF0000000000000
1474   ret i1 %r
1477 define i1 @is_finite(i1 %c, double %x) {
1478 ; CHECK-LABEL: @is_finite(
1479 ; CHECK-NEXT:    ret i1 true
1481   %xx = fmul nnan ninf double %x, %x
1482   %s = select i1 %c, double 42.0, double %xx
1483   %r = fcmp one double %s, 0x7FF0000000000000
1484   ret i1 %r
1487 define i1 @is_finite_assume(i1 %c, double %x) {
1488 ; CHECK-LABEL: @is_finite_assume(
1489 ; CHECK-NEXT:    [[XABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
1490 ; CHECK-NEXT:    [[IS_INF_OR_NAN:%.*]] = fcmp one double [[XABS]], 0x7FF0000000000000
1491 ; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_INF_OR_NAN]])
1492 ; CHECK-NEXT:    ret i1 true
1494   %xabs = call double @llvm.fabs.f64(double %x)
1495   %is.inf.or.nan = fcmp one double %xabs, 0x7FF0000000000000
1496   call void @llvm.assume(i1 %is.inf.or.nan)
1497   %s = select i1 %c, double 42.0, double %x
1498   %r = fcmp one double %s, 0x7FF0000000000000
1499   ret i1 %r
1502 define <2 x i1> @is_finite_commute(<2 x i8> %x) {
1503 ; CHECK-LABEL: @is_finite_commute(
1504 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1506   %cast = uitofp <2 x i8> %x to <2 x float>
1507   %r = fcmp one <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1508   ret <2 x i1> %r
1511 define i1 @fcmp_oge_0_assumed_oge_zero(float %x) {
1512 ; CHECK-LABEL: @fcmp_oge_0_assumed_oge_zero(
1513 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1514 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1515 ; CHECK-NEXT:    ret i1 true
1517   %assume.cmp = fcmp oge float %x, 0.0
1518   call void @llvm.assume(i1 %assume.cmp)
1519   %r = fcmp oge float %x, 0.000000e+00
1520   ret i1 %r
1523 define i1 @fcmp_ult_0_assumed_oge_zero(float %x) {
1524 ; CHECK-LABEL: @fcmp_ult_0_assumed_oge_zero(
1525 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1526 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1527 ; CHECK-NEXT:    ret i1 false
1529   %assume.cmp = fcmp oge float %x, 0.0
1530   call void @llvm.assume(i1 %assume.cmp)
1531   %r = fcmp ult float %x, 0.000000e+00
1532   ret i1 %r
1535 define i1 @fcmp_uge_0_assumed_oge_zero(float %x) {
1536 ; CHECK-LABEL: @fcmp_uge_0_assumed_oge_zero(
1537 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1538 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1539 ; CHECK-NEXT:    ret i1 true
1541   %assume.cmp = fcmp oge float %x, 0.0
1542   call void @llvm.assume(i1 %assume.cmp)
1543   %r = fcmp uge float %x, 0.000000e+00
1544   ret i1 %r
1547 define i1 @fcmp_olt_0_assumed_oge_zero(float %x) {
1548 ; CHECK-LABEL: @fcmp_olt_0_assumed_oge_zero(
1549 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1550 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1551 ; CHECK-NEXT:    ret i1 false
1553   %assume.cmp = fcmp oge float %x, 0.0
1554   call void @llvm.assume(i1 %assume.cmp)
1555   %r = fcmp olt float %x, 0.000000e+00
1556   ret i1 %r
1559 define i1 @ogt_zero_fabs_select_negone_or_pinf(i1 %cond) {
1560 ; CHECK-LABEL: @ogt_zero_fabs_select_negone_or_pinf(
1561 ; CHECK-NEXT:  entry:
1562 ; CHECK-NEXT:    ret i1 true
1564 entry:
1565   %select = select i1 %cond, float -1.0, float 0x7FF0000000000000
1566   %fabs = call float @llvm.fabs.f32(float %select)
1567   %one = fcmp ogt float %fabs, 0.0
1568   ret i1 %one
1571 define i1 @ogt_zero_fabs_select_one_or_ninf(i1 %cond) {
1572 ; CHECK-LABEL: @ogt_zero_fabs_select_one_or_ninf(
1573 ; CHECK-NEXT:  entry:
1574 ; CHECK-NEXT:    ret i1 true
1576 entry:
1577   %select = select i1 %cond, float 1.0, float 0xFFF0000000000000
1578   %fabs = call float @llvm.fabs.f32(float %select)
1579   %one = fcmp ogt float %fabs, 0.0
1580   ret i1 %one
1583 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1584 define float @fast_square_must_be_positive_ieee(float %arg, float %arg1) {
1585 ; CHECK-LABEL: @fast_square_must_be_positive_ieee(
1586 ; CHECK-NEXT:  bb:
1587 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1588 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1589 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1590 ; CHECK-NEXT:    ret float [[I3]]
1593   %i = fmul float %arg, %arg
1594   %i2 = fmul float %arg1, %arg1
1595   %i3 = fadd float %i2, %i
1596   %i4 = fcmp olt float %i3, 0.000000e+00
1597   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1598   ret float %i5
1601 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1602 define float @fast_square_must_be_positive_ieee_nnan(float %arg, float %arg1) {
1603 ; CHECK-LABEL: @fast_square_must_be_positive_ieee_nnan(
1604 ; CHECK-NEXT:  bb:
1605 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1606 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1607 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1608 ; CHECK-NEXT:    ret float [[I3]]
1611   %i = fmul float %arg, %arg
1612   %i2 = fmul float %arg1, %arg1
1613   %i3 = fadd float %i2, %i
1614   %i4 = fcmp nnan olt float %i3, 0.000000e+00
1615   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1616   ret float %i5
1619 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1620 define float @fast_square_must_be_positive_daz(float %arg, float %arg1) #0 {
1621 ; CHECK-LABEL: @fast_square_must_be_positive_daz(
1622 ; CHECK-NEXT:  bb:
1623 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1624 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1625 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1626 ; CHECK-NEXT:    ret float [[I3]]
1629   %i = fmul float %arg, %arg
1630   %i2 = fmul float %arg1, %arg1
1631   %i3 = fadd float %i2, %i
1632   %i4 = fcmp olt float %i3, 0.000000e+00
1633   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1634   ret float %i5
1637 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1638 define float @fast_square_must_be_positive_daz_nnan(float %arg, float %arg1) #0 {
1639 ; CHECK-LABEL: @fast_square_must_be_positive_daz_nnan(
1640 ; CHECK-NEXT:  bb:
1641 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1642 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1643 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1644 ; CHECK-NEXT:    ret float [[I3]]
1647   %i = fmul float %arg, %arg
1648   %i2 = fmul float %arg1, %arg1
1649   %i3 = fadd float %i2, %i
1650   %i4 = fcmp nnan olt float %i3, 0.000000e+00
1651   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1652   ret float %i5
1655 ; Make the compare to negative constant is folded out
1656 define float @must_be_olt_negative_constant_daz(float %arg, float %arg1) #0 {
1657 ; CHECK-LABEL: @must_be_olt_negative_constant_daz(
1658 ; CHECK-NEXT:  bb:
1659 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1660 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1661 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1662 ; CHECK-NEXT:    ret float [[I3]]
1665   %i = fmul float %arg, %arg
1666   %i2 = fmul float %arg1, %arg1
1667   %i3 = fadd float %i2, %i
1668   %i4 = fcmp olt float %i3, -1.0
1669   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1670   ret float %i5
1673 ; Make the compare to negative constant is folded out
1674 define float @must_be_olt_negative_constant_daz_nnan(float %arg, float %arg1) #0 {
1675 ; CHECK-LABEL: @must_be_olt_negative_constant_daz_nnan(
1676 ; CHECK-NEXT:  bb:
1677 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1678 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1679 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1680 ; CHECK-NEXT:    ret float [[I3]]
1683   %i = fmul float %arg, %arg
1684   %i2 = fmul float %arg1, %arg1
1685   %i3 = fadd float %i2, %i
1686   %i4 = fcmp nnan olt float %i3, -1.0
1687   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1688   ret float %i5
1691 define i1 @is_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
1692 ; CHECK-LABEL: @is_olt_smallest_normal_dynamic(
1693 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1694 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1696   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1697   ret i1 %is.denorm.or.zero
1700 define i1 @is_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
1701 ; CHECK-LABEL: @is_olt_smallest_normal_ieee(
1702 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1703 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1705   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1706   ret i1 %is.denorm.or.zero
1709 define i1 @is_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
1710 ; CHECK-LABEL: @is_olt_smallest_normal_preserve_sign(
1711 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1712 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1714   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1715   ret i1 %is.denorm.or.zero
1718 define i1 @is_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
1719 ; CHECK-LABEL: @is_olt_smallest_normal_positive_zero(
1720 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1721 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1723   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1724   ret i1 %is.denorm.or.zero
1727 define i1 @is_fabs_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
1728 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_dynamic(
1729 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1730 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1731 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1733   %fabs.x = call float @llvm.fabs.f32(float %x)
1734   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1735   ret i1 %is.denorm.or.zero
1738 define i1 @is_fabs_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
1739 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_ieee(
1740 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1741 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1742 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1744   %fabs.x = call float @llvm.fabs.f32(float %x)
1745   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1746   ret i1 %is.denorm.or.zero
1749 define i1 @is_fabs_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
1750 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_preserve_sign(
1751 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1752 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1753 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1755   %fabs.x = call float @llvm.fabs.f32(float %x)
1756   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1757   ret i1 %is.denorm.or.zero
1760 define i1 @is_fabs_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
1761 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_positive_zero(
1762 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1763 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1764 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1766   %fabs.x = call float @llvm.fabs.f32(float %x)
1767   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1768   ret i1 %is.denorm.or.zero
1772 declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
1773 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
1774 declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)
1775 declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>)
1776 declare <3 x float> @llvm.fabs.v3f32(<3 x float>)
1777 declare double @llvm.exp2.f64(double)
1778 declare double @llvm.fabs.f64(double)
1779 declare double @llvm.powi.f64.i32(double, i32)
1780 declare float @llvm.exp.f32(float)
1781 declare float @llvm.fabs.f32(float)
1782 declare float @llvm.fma.f32(float, float, float)
1783 declare float @llvm.maximum.f32(float, float)
1784 declare float @llvm.maxnum.f32(float, float)
1785 declare float @llvm.minnum.f32(float, float)
1786 declare float @llvm.sqrt.f32(float)
1787 declare double @llvm.sqrt.f64(double)
1788 declare double @llvm.copysign.f64(double, double)
1789 declare half @llvm.fabs.f16(half)
1790 declare void @llvm.assume(i1 noundef)
1792 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }