Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstSimplify / floating-point-compare.ll
blobe9d5c353cbccfc336a3e06f966ba1e5feec6c1a6
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_poison(<3 x float> %V) {
551 ; CHECK-LABEL: @fabs_is_not_negative_negzero_poison(
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 poison>
556   ret <3 x i1> %cmp
559 define <3 x i1> @fabs_is_not_negative_poszero_poison(<3 x float> %V) {
560 ; CHECK-LABEL: @fabs_is_not_negative_poszero_poison(
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 poison>
565   ret <3 x i1> %cmp
568 define <3 x i1> @fabs_is_not_negative_anyzero_poison(<3 x float> %V) {
569 ; CHECK-LABEL: @fabs_is_not_negative_anyzero_poison(
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 poison>
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_nan_x2_uno(float %x, float %y) {
676 ; CHECK-LABEL: @assume_nan_x2_uno(
677 ; CHECK-NEXT:    [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
678 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO_X]])
679 ; CHECK-NEXT:    [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00
680 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO_Y]])
681 ; CHECK-NEXT:    ret i1 true
683   %uno.x = fcmp uno float %x, 0.0
684   call void @llvm.assume(i1 %uno.x)
685   %uno.y = fcmp uno float %y, 0.0
686   call void @llvm.assume(i1 %uno.y)
687   %cmp = fcmp uno float %x, %y
688   ret i1 %cmp
691 define i1 @assume_nan_x2_ord(float %x, float %y) {
692 ; CHECK-LABEL: @assume_nan_x2_ord(
693 ; CHECK-NEXT:    [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
694 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO_X]])
695 ; CHECK-NEXT:    [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00
696 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO_Y]])
697 ; CHECK-NEXT:    ret i1 false
699   %uno.x = fcmp uno float %x, 0.0
700   call void @llvm.assume(i1 %uno.x)
701   %uno.y = fcmp uno float %y, 0.0
702   call void @llvm.assume(i1 %uno.y)
703   %cmp = fcmp ord float %x, %y
704   ret i1 %cmp
707 define i1 @assume_nonan_x2_uno(float %x, float %y) {
708 ; CHECK-LABEL: @assume_nonan_x2_uno(
709 ; CHECK-NEXT:    [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
710 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_X]])
711 ; CHECK-NEXT:    [[ORD_Y:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00
712 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD_Y]])
713 ; CHECK-NEXT:    ret i1 false
715   %ord.x = fcmp ord float %x, 0.0
716   call void @llvm.assume(i1 %ord.x)
717   %ord.y = fcmp ord float %y, 0.0
718   call void @llvm.assume(i1 %ord.y)
719   %cmp = fcmp uno float %x, %y
720   ret i1 %cmp
723 define i1 @assume_nan_ord(float %x) {
724 ; CHECK-LABEL: @assume_nan_ord(
725 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
726 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
727 ; CHECK-NEXT:    ret i1 false
729   %uno = fcmp uno float %x, 0.0
730   call void @llvm.assume(i1 %uno)
731   %cmp = fcmp ord float %x, 1.0
732   ret i1 %cmp
735 define i1 @assume_nonnan_uno(float %x) {
736 ; CHECK-LABEL: @assume_nonnan_uno(
737 ; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
738 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
739 ; CHECK-NEXT:    ret i1 false
741   %ord = fcmp ord float %x, 0.0
742   call void @llvm.assume(i1 %ord)
743   %cmp = fcmp uno float %x, 1.0
744   ret i1 %cmp
747 define i1 @assume_nan_uno(float %x) {
748 ; CHECK-LABEL: @assume_nan_uno(
749 ; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
750 ; CHECK-NEXT:    call void @llvm.assume(i1 [[UNO]])
751 ; CHECK-NEXT:    ret i1 true
753   %uno = fcmp uno float %x, 0.0
754   call void @llvm.assume(i1 %uno)
755   %cmp = fcmp uno float %x, 1.0
756   ret i1 %cmp
759 ; min(x, 0.5) == 1.0 --> false
761 define i1 @minnum_oeq_small_min_constant(float %x) {
762 ; CHECK-LABEL: @minnum_oeq_small_min_constant(
763 ; CHECK-NEXT:    ret i1 false
765   %min = call float @llvm.minnum.f32(float %x, float 0.5)
766   %cmp = fcmp oeq float %min, 1.0
767   ret i1 %cmp
770 ; min(x, 0.5) > 1.0 --> false
772 define i1 @minnum_ogt_small_min_constant(float %x) {
773 ; CHECK-LABEL: @minnum_ogt_small_min_constant(
774 ; CHECK-NEXT:    ret i1 false
776   %min = call float @llvm.minnum.f32(float %x, float 0.5)
777   %cmp = fcmp ogt float %min, 1.0
778   ret i1 %cmp
781 ; min(x, 0.5) >= 1.0 --> false
783 define i1 @minnum_oge_small_min_constant(float %x) {
784 ; CHECK-LABEL: @minnum_oge_small_min_constant(
785 ; CHECK-NEXT:    ret i1 false
787   %min = call float @llvm.minnum.f32(float %x, float 0.5)
788   %cmp = fcmp oge float %min, 1.0
789   ret i1 %cmp
792 ; min(x, 0.5) == 1.0 --> false
794 define i1 @minnum_ueq_small_min_constant(float %x) {
795 ; CHECK-LABEL: @minnum_ueq_small_min_constant(
796 ; CHECK-NEXT:    ret i1 false
798   %min = call float @llvm.minnum.f32(float %x, float 0.5)
799   %cmp = fcmp ueq float %min, 1.0
800   ret i1 %cmp
803 ; min(x, 0.5) > 1.0 --> false
805 define i1 @minnum_ugt_small_min_constant(float %x) {
806 ; CHECK-LABEL: @minnum_ugt_small_min_constant(
807 ; CHECK-NEXT:    ret i1 false
809   %min = call float @llvm.minnum.f32(float %x, float 0.5)
810   %cmp = fcmp ugt float %min, 1.0
811   ret i1 %cmp
814 ; min(x, 0.5) >= 1.0 --> false
816 define <2 x i1> @minnum_uge_small_min_constant(<2 x float> %x) {
817 ; CHECK-LABEL: @minnum_uge_small_min_constant(
818 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
820   %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
821   %cmp = fcmp uge <2 x float> %min, <float 1.0, float 1.0>
822   ret <2 x i1> %cmp
825 ; min(x, 0.5) < 1.0 --> true
827 define <2 x i1> @minnum_olt_small_min_constant(<2 x float> %x) {
828 ; CHECK-LABEL: @minnum_olt_small_min_constant(
829 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
831   %min = call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> <float 0.5, float 0.5>)
832   %cmp = fcmp olt <2 x float> %min, <float 1.0, float 1.0>
833   ret <2 x i1> %cmp
836 ; min(x, 0.5) <= 1.0 --> true
838 define i1 @minnum_ole_small_min_constant(float %x) {
839 ; CHECK-LABEL: @minnum_ole_small_min_constant(
840 ; CHECK-NEXT:    ret i1 true
842   %min = call float @llvm.minnum.f32(float %x, float 0.5)
843   %cmp = fcmp ole float %min, 1.0
844   ret i1 %cmp
847 ; min(x, 0.5) != 1.0 --> true
849 define i1 @minnum_one_small_min_constant(float %x) {
850 ; CHECK-LABEL: @minnum_one_small_min_constant(
851 ; CHECK-NEXT:    ret i1 true
853   %min = call float @llvm.minnum.f32(float %x, float 0.5)
854   %cmp = fcmp one float %min, 1.0
855   ret i1 %cmp
858 ; min(x, 0.5) < 1.0 --> true
860 define i1 @minnum_ult_small_min_constant(float %x) {
861 ; CHECK-LABEL: @minnum_ult_small_min_constant(
862 ; CHECK-NEXT:    ret i1 true
864   %min = call float @llvm.minnum.f32(float %x, float 0.5)
865   %cmp = fcmp ult float %min, 1.0
866   ret i1 %cmp
869 ; min(x, 0.5) <= 1.0 --> true
871 define i1 @minnum_ule_small_min_constant(float %x) {
872 ; CHECK-LABEL: @minnum_ule_small_min_constant(
873 ; CHECK-NEXT:    ret i1 true
875   %min = call float @llvm.minnum.f32(float %x, float 0.5)
876   %cmp = fcmp ule float %min, 1.0
877   ret i1 %cmp
880 ; min(x, 0.5) != 1.0 --> true
882 define i1 @minnum_une_small_min_constant(float %x) {
883 ; CHECK-LABEL: @minnum_une_small_min_constant(
884 ; CHECK-NEXT:    ret i1 true
886   %min = call float @llvm.minnum.f32(float %x, float 0.5)
887   %cmp = fcmp une float %min, 1.0
888   ret i1 %cmp
891 ; Negative test:
892 ; min(x, 1.0) != 1.0 --> ?
894 define i1 @minnum_une_equal_min_constant(float %x) {
895 ; CHECK-LABEL: @minnum_une_equal_min_constant(
896 ; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00)
897 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
898 ; CHECK-NEXT:    ret i1 [[CMP]]
900   %min = call float @llvm.minnum.f32(float %x, float 1.0)
901   %cmp = fcmp une float %min, 1.0
902   ret i1 %cmp
905 ; Negative test:
906 ; min(x, 2.0) != 1.0 --> ?
908 define i1 @minnum_une_large_min_constant(float %x) {
909 ; CHECK-LABEL: @minnum_une_large_min_constant(
910 ; CHECK-NEXT:    [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.000000e+00)
911 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MIN]], 1.000000e+00
912 ; CHECK-NEXT:    ret i1 [[CMP]]
914   %min = call float @llvm.minnum.f32(float %x, float 2.0)
915   %cmp = fcmp une float %min, 1.0
916   ret i1 %cmp
919 ; Partial negative test (the minnum simplifies):
920 ; min(x, NaN) != 1.0 --> x != 1.0
922 define i1 @minnum_une_nan_min_constant(float %x) {
923 ; CHECK-LABEL: @minnum_une_nan_min_constant(
924 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
925 ; CHECK-NEXT:    ret i1 [[CMP]]
927   %min = call float @llvm.minnum.f32(float %x, float 0x7FF8000000000000)
928   %cmp = fcmp une float %min, 1.0
929   ret i1 %cmp
932 ; max(x, 1.5) == 1.0 --> false
934 define i1 @maxnum_oeq_large_max_constant(float %x) {
935 ; CHECK-LABEL: @maxnum_oeq_large_max_constant(
936 ; CHECK-NEXT:    ret i1 false
938   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
939   %cmp = fcmp oeq float %max, 1.0
940   ret i1 %cmp
943 ; max(x, 1.5) < 1.0 --> false
945 define i1 @maxnum_olt_large_max_constant(float %x) {
946 ; CHECK-LABEL: @maxnum_olt_large_max_constant(
947 ; CHECK-NEXT:    ret i1 false
949   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
950   %cmp = fcmp olt float %max, 1.0
951   ret i1 %cmp
954 ; max(x, 1.5) <= 1.0 --> false
956 define i1 @maxnum_ole_large_max_constant(float %x) {
957 ; CHECK-LABEL: @maxnum_ole_large_max_constant(
958 ; CHECK-NEXT:    ret i1 false
960   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
961   %cmp = fcmp ole float %max, 1.0
962   ret i1 %cmp
965 ; max(x, 1.5) == 1.0 --> false
967 define i1 @maxnum_ueq_large_max_constant(float %x) {
968 ; CHECK-LABEL: @maxnum_ueq_large_max_constant(
969 ; CHECK-NEXT:    ret i1 false
971   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
972   %cmp = fcmp ueq float %max, 1.0
973   ret i1 %cmp
976 ; max(x, 1.5) < 1.0 --> false
978 define i1 @maxnum_ult_large_max_constant(float %x) {
979 ; CHECK-LABEL: @maxnum_ult_large_max_constant(
980 ; CHECK-NEXT:    ret i1 false
982   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
983   %cmp = fcmp ult float %max, 1.0
984   ret i1 %cmp
987 ; max(x, 1.5) <= 1.0 --> false
989 define <2 x i1> @maxnum_ule_large_max_constant(<2 x float> %x) {
990 ; CHECK-LABEL: @maxnum_ule_large_max_constant(
991 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
993   %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
994   %cmp = fcmp ule <2 x float> %max, <float 1.0, float 1.0>
995   ret <2 x i1> %cmp
998 ; max(x, 1.5) > 1.0 --> true
1000 define <2 x i1> @maxnum_ogt_large_max_constant(<2 x float> %x) {
1001 ; CHECK-LABEL: @maxnum_ogt_large_max_constant(
1002 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1004   %max = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> <float 1.5, float 1.5>)
1005   %cmp = fcmp ogt <2 x float> %max, <float 1.0, float 1.0>
1006   ret <2 x i1> %cmp
1009 ; max(x, 1.5) >= 1.0 --> true
1011 define i1 @maxnum_oge_large_max_constant(float %x) {
1012 ; CHECK-LABEL: @maxnum_oge_large_max_constant(
1013 ; CHECK-NEXT:    ret i1 true
1015   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1016   %cmp = fcmp oge float %max, 1.0
1017   ret i1 %cmp
1020 ; max(x, 1.5) != 1.0 --> true
1022 define i1 @maxnum_one_large_max_constant(float %x) {
1023 ; CHECK-LABEL: @maxnum_one_large_max_constant(
1024 ; CHECK-NEXT:    ret i1 true
1026   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1027   %cmp = fcmp one float %max, 1.0
1028   ret i1 %cmp
1031 ; max(x, 1.5) > 1.0 --> true
1033 define i1 @maxnum_ugt_large_max_constant(float %x) {
1034 ; CHECK-LABEL: @maxnum_ugt_large_max_constant(
1035 ; CHECK-NEXT:    ret i1 true
1037   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1038   %cmp = fcmp ugt float %max, 1.0
1039   ret i1 %cmp
1042 ; max(x, 1.5) >= 1.0 --> true
1044 define i1 @maxnum_uge_large_max_constant(float %x) {
1045 ; CHECK-LABEL: @maxnum_uge_large_max_constant(
1046 ; CHECK-NEXT:    ret i1 true
1048   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1049   %cmp = fcmp uge float %max, 1.0
1050   ret i1 %cmp
1053 ; max(x, 1.5) != 1.0 --> true
1055 define i1 @maxnum_une_large_max_constant(float %x) {
1056 ; CHECK-LABEL: @maxnum_une_large_max_constant(
1057 ; CHECK-NEXT:    ret i1 true
1059   %max = call float @llvm.maxnum.f32(float %x, float 1.5)
1060   %cmp = fcmp une float %max, 1.0
1061   ret i1 %cmp
1064 ; Negative test:
1065 ; max(x, 1.0) != 1.0 --> ?
1067 define i1 @maxnum_une_equal_max_constant(float %x) {
1068 ; CHECK-LABEL: @maxnum_une_equal_max_constant(
1069 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
1070 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
1071 ; CHECK-NEXT:    ret i1 [[CMP]]
1073   %max = call float @llvm.maxnum.f32(float %x, float 1.0)
1074   %cmp = fcmp une float %max, 1.0
1075   ret i1 %cmp
1078 ; Negative test:
1079 ; max(x, 0.5) != 1.0 --> ?
1081 define i1 @maxnum_une_small_max_constant(float %x) {
1082 ; CHECK-LABEL: @maxnum_une_small_max_constant(
1083 ; CHECK-NEXT:    [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 5.000000e-01)
1084 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MAX]], 1.000000e+00
1085 ; CHECK-NEXT:    ret i1 [[CMP]]
1087   %max = call float @llvm.maxnum.f32(float %x, float 0.5)
1088   %cmp = fcmp une float %max, 1.0
1089   ret i1 %cmp
1092 ; Partial negative test (the maxnum simplifies):
1093 ; max(x, NaN) != 1.0 --> x != 1.0
1095 define i1 @maxnum_une_nan_max_constant(float %x) {
1096 ; CHECK-LABEL: @maxnum_une_nan_max_constant(
1097 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 1.000000e+00
1098 ; CHECK-NEXT:    ret i1 [[CMP]]
1100   %max = call float @llvm.maxnum.f32(float %x, float 0x7FF8000000000000)
1101   %cmp = fcmp une float %max, 1.0
1102   ret i1 %cmp
1105 define i1 @known_positive_olt_with_negative_constant(double %a) {
1106 ; CHECK-LABEL: @known_positive_olt_with_negative_constant(
1107 ; CHECK-NEXT:    ret i1 false
1109   %call = call double @llvm.fabs.f64(double %a)
1110   %cmp = fcmp olt double %call, -1.0
1111   ret i1 %cmp
1114 define i1 @known_positive_nsz_olt_with_negative_constant(double %mag, double %a) {
1115 ; CHECK-LABEL: @known_positive_nsz_olt_with_negative_constant(
1116 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1117 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1118 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00
1119 ; CHECK-NEXT:    ret i1 [[CMP]]
1121   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1122   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1123   %cmp = fcmp olt double %copysign, -1.0
1124   ret i1 %cmp
1127 define i1 @known_positive_maybe_neg0_olt_with_negative_constant(double %mag, double %a) {
1128 ; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_negative_constant(
1129 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1130 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1131 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], -1.000000e+00
1132 ; CHECK-NEXT:    ret i1 [[CMP]]
1134   %sqrt = call double @llvm.sqrt.f64(double %a)
1135   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1136   %cmp = fcmp olt double %copysign, -1.0
1137   ret i1 %cmp
1140 define i1 @known_positive_nsz_uge_with_negative_constant(double %mag, double %a) {
1141 ; CHECK-LABEL: @known_positive_nsz_uge_with_negative_constant(
1142 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1143 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1144 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00
1145 ; CHECK-NEXT:    ret i1 [[CMP]]
1147   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1148   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1149   %cmp = fcmp uge double %copysign, -1.0
1150   ret i1 %cmp
1153 define i1 @known_positive_maybe_neg0_uge_with_negative_constant(double %mag, double %a) {
1154 ; CHECK-LABEL: @known_positive_maybe_neg0_uge_with_negative_constant(
1155 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1156 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1157 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[COPYSIGN]], -1.000000e+00
1158 ; CHECK-NEXT:    ret i1 [[CMP]]
1160   %sqrt = call double @llvm.sqrt.f64(double %a)
1161   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1162   %cmp = fcmp uge double %copysign, -1.0
1163   ret i1 %cmp
1166 define i1 @known_positive_nsz_oge_with_zero_constant(double %mag, double %a) {
1167 ; CHECK-LABEL: @known_positive_nsz_oge_with_zero_constant(
1168 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1169 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1170 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00
1171 ; CHECK-NEXT:    ret i1 [[CMP]]
1173   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1174   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1175   %cmp = fcmp oge double %copysign, 0.0
1176   ret i1 %cmp
1179 define i1 @known_positive_maybe_neg0_oge_with_zero_constant(double %mag, double %a) {
1180 ; CHECK-LABEL: @known_positive_maybe_neg0_oge_with_zero_constant(
1181 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1182 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1183 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[COPYSIGN]], 0.000000e+00
1184 ; CHECK-NEXT:    ret i1 [[CMP]]
1186   %sqrt = call double @llvm.sqrt.f64(double %a)
1187   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1188   %cmp = fcmp oge double %copysign, 0.0
1189   ret i1 %cmp
1192 define i1 @known_positive_nsz_olt_with_zero_constant(double %mag, double %a) {
1193 ; CHECK-LABEL: @known_positive_nsz_olt_with_zero_constant(
1194 ; CHECK-NEXT:    [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[A:%.*]])
1195 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1196 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00
1197 ; CHECK-NEXT:    ret i1 [[CMP]]
1199   %sqrt = call nsz double @llvm.sqrt.f64(double %a)
1200   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1201   %cmp = fcmp olt double %copysign, 0.0
1202   ret i1 %cmp
1205 define i1 @known_positive_maybe_neg0_olt_with_zero_constant(double %mag, double %a) {
1206 ; CHECK-LABEL: @known_positive_maybe_neg0_olt_with_zero_constant(
1207 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]])
1208 ; CHECK-NEXT:    [[COPYSIGN:%.*]] = call double @llvm.copysign.f64(double [[MAG:%.*]], double [[SQRT]])
1209 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[COPYSIGN]], 0.000000e+00
1210 ; CHECK-NEXT:    ret i1 [[CMP]]
1212   %sqrt = call double @llvm.sqrt.f64(double %a)
1213   %copysign = call double @llvm.copysign.f64(double %mag, double %sqrt)
1214   %cmp = fcmp olt double %copysign, 0.0
1215   ret i1 %cmp
1218 define i1 @assumed_positive_olt_with_negative_constant(double %a) {
1219 ; CHECK-LABEL: @assumed_positive_olt_with_negative_constant(
1220 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1221 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1222 ; CHECK-NEXT:    ret i1 false
1224   %assume.cmp = fcmp oge double %a, 0.0
1225   call void @llvm.assume(i1 %assume.cmp)
1226   %cmp = fcmp olt double %a, -1.0
1227   ret i1 %cmp
1230 define i1 @assumed_positive_ole_with_negative_constant(double %a) {
1231 ; CHECK-LABEL: @assumed_positive_ole_with_negative_constant(
1232 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1233 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1234 ; CHECK-NEXT:    ret i1 false
1236   %assume.cmp = fcmp oge double %a, 0.0
1237   call void @llvm.assume(i1 %assume.cmp)
1238   %cmp = fcmp ole double %a, -1.0
1239   ret i1 %cmp
1242 define i1 @assumed_positive_oeq_with_negative_constant(double %a) {
1243 ; CHECK-LABEL: @assumed_positive_oeq_with_negative_constant(
1244 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
1245 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1246 ; CHECK-NEXT:    ret i1 false
1248   %assume.cmp = fcmp oge double %a, 0.0
1249   call void @llvm.assume(i1 %assume.cmp)
1250   %cmp = fcmp oeq double %a, -1.0
1251   ret i1 %cmp
1254 define <2 x i1> @known_positive_ole_with_negative_constant_splat_vec(<2 x i32> %a) {
1255 ; CHECK-LABEL: @known_positive_ole_with_negative_constant_splat_vec(
1256 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1258   %call = uitofp <2 x i32> %a to <2 x double>
1259   %cmp = fcmp ole <2 x double> %call, <double -2.0, double -2.0>
1260   ret <2 x i1> %cmp
1263 define i1 @known_positive_ugt_with_negative_constant(i32 %a) {
1264 ; CHECK-LABEL: @known_positive_ugt_with_negative_constant(
1265 ; CHECK-NEXT:    ret i1 true
1267   %call = uitofp i32 %a to float
1268   %cmp = fcmp ugt float %call, -3.0
1269   ret i1 %cmp
1272 define i1 @assumed_positive_ugt_with_negative_constant(float %a) {
1273 ; CHECK-LABEL: @assumed_positive_ugt_with_negative_constant(
1274 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1275 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1276 ; CHECK-NEXT:    ret i1 true
1278   %assume.cmp = fcmp ogt float %a, 0.0
1279   call void @llvm.assume(i1 %assume.cmp)
1280   %cmp = fcmp ugt float %a, -3.0
1281   ret i1 %cmp
1284 define i1 @assumed_positive_uge_with_negative_constant(float %a) {
1285 ; CHECK-LABEL: @assumed_positive_uge_with_negative_constant(
1286 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1287 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1288 ; CHECK-NEXT:    ret i1 true
1290   %assume.cmp = fcmp ogt float %a, 0.0
1291   call void @llvm.assume(i1 %assume.cmp)
1292   %cmp = fcmp uge float %a, -3.0
1293   ret i1 %cmp
1296 define i1 @assumed_positive_une_with_negative_constant(float %a) {
1297 ; CHECK-LABEL: @assumed_positive_une_with_negative_constant(
1298 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
1299 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1300 ; CHECK-NEXT:    ret i1 true
1302   %assume.cmp = fcmp ogt float %a, 0.0
1303   call void @llvm.assume(i1 %assume.cmp)
1304   %cmp = fcmp une float %a, -3.0
1305   ret i1 %cmp
1308 define <2 x i1> @known_positive_uge_with_negative_constant_splat_vec(<2 x float> %a) {
1309 ; CHECK-LABEL: @known_positive_uge_with_negative_constant_splat_vec(
1310 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1312   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
1313   %cmp = fcmp uge <2 x float> %call, <float -4.0, float -4.0>
1314   ret <2 x i1> %cmp
1317 define i1 @known_positive_oeq_with_negative_constant(half %a) {
1318 ; CHECK-LABEL: @known_positive_oeq_with_negative_constant(
1319 ; CHECK-NEXT:    ret i1 false
1321   %call = call half @llvm.fabs.f16(half %a)
1322   %cmp = fcmp oeq half %call, -5.0
1323   ret i1 %cmp
1326 define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %a) {
1327 ; CHECK-LABEL: @known_positive_une_with_negative_constant_splat_vec(
1328 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1330   %call = uitofp <2 x i32> %a to <2 x half>
1331   %cmp = fcmp une <2 x half> %call, <half -6.0, half -6.0>
1332   ret <2 x i1> %cmp
1335 define i1 @pr58046(i64 %arg) {
1336 ; CHECK-LABEL: @pr58046(
1337 ; CHECK-NEXT:    ret i1 true
1339   %fp = uitofp i64 %arg to double
1340   %mul = fmul double -0.000000e+00, %fp
1341   %div = fdiv double 1.000000e+00, %mul
1342   %cmp = fcmp oeq double %div, 0xFFF0000000000000
1343   ret i1 %cmp
1346 define i1 @nonans1(double %in1, double %in2) {
1347 ; CHECK-LABEL: @nonans1(
1348 ; CHECK-NEXT:    ret i1 false
1350   %cmp = fcmp nnan uno double %in1, %in2
1351   ret i1 %cmp
1354 define i1 @nonans2(double %in1, double %in2) {
1355 ; CHECK-LABEL: @nonans2(
1356 ; CHECK-NEXT:    ret i1 true
1358   %cmp = fcmp nnan ord double %in1, %in2
1359   ret i1 %cmp
1362 define <2 x i1> @orderedCompareWithNaNVector(<2 x double> %A) {
1363 ; CHECK-LABEL: @orderedCompareWithNaNVector(
1364 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1366   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
1367   ret <2 x i1> %cmp
1370 define <2 x i1> @orderedCompareWithNaNVector_poison_elt(<2 x double> %A) {
1371 ; CHECK-LABEL: @orderedCompareWithNaNVector_poison_elt(
1372 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1374   %cmp = fcmp olt <2 x double> %A, <double 0xFFFFFFFFFFFFFFFF, double poison>
1375   ret <2 x i1> %cmp
1378 define <2 x i1> @unorderedCompareWithNaNVector_poison_elt(<2 x double> %A) {
1379 ; CHECK-LABEL: @unorderedCompareWithNaNVector_poison_elt(
1380 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1382   %cmp = fcmp ult <2 x double> %A, <double poison, double 0xFFFFFFFFFFFFFFFF>
1383   ret <2 x i1> %cmp
1386 define i1 @is_infinite(float %x) {
1387 ; CHECK-LABEL: @is_infinite(
1388 ; CHECK-NEXT:    ret i1 false
1390   %xabs = call ninf float @llvm.fabs.f32(float %x)
1391   %r = fcmp oeq float %xabs, 0x7FF0000000000000
1392   ret i1 %r
1395 define i1 @is_infinite_assumed_finite(float %x) {
1396 ; CHECK-LABEL: @is_infinite_assumed_finite(
1397 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1398 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1399 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
1400 ; CHECK-NEXT:    ret i1 false
1402   %xabs = call float @llvm.fabs.f32(float %x)
1403   %not.inf = fcmp one float %xabs, 0x7FF0000000000000
1404   call void @llvm.assume(i1 %not.inf)
1405   %r = fcmp oeq float %xabs, 0x7FF0000000000000
1406   ret i1 %r
1409 define i1 @une_inf_assumed_not_inf(float %x) {
1410 ; CHECK-LABEL: @une_inf_assumed_not_inf(
1411 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1412 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1413 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_INF]])
1414 ; CHECK-NEXT:    ret i1 true
1416   %xabs = call float @llvm.fabs.f32(float %x)
1417   %not.inf = fcmp one float %xabs, 0x7FF0000000000000
1418   call void @llvm.assume(i1 %not.inf)
1419   %r = fcmp une float %xabs, 0x7FF0000000000000
1420   ret i1 %r
1423 define <2 x i1> @is_infinite_neg(<2 x float> %x) {
1424 ; CHECK-LABEL: @is_infinite_neg(
1425 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1427   %x42 = fadd ninf <2 x float> %x, <float 42.0, float 42.0>
1428   %r = fcmp oeq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1429   ret <2 x i1> %r
1432 ; Negative test - but this could be reduced to 'uno' outside of instsimplify.
1434 define i1 @is_infinite_or_nan(float %x) {
1435 ; CHECK-LABEL: @is_infinite_or_nan(
1436 ; CHECK-NEXT:    [[X42:%.*]] = fadd ninf float [[X:%.*]], 4.200000e+01
1437 ; CHECK-NEXT:    [[R:%.*]] = fcmp ueq float [[X42]], 0xFFF0000000000000
1438 ; CHECK-NEXT:    ret i1 [[R]]
1440   %x42 = fadd ninf float %x, 42.0
1441   %r = fcmp ueq float %x42, 0xFFF0000000000000
1442   ret i1 %r
1445 define i1 @is_infinite_or_nan2(float %x) {
1446 ; CHECK-LABEL: @is_infinite_or_nan2(
1447 ; CHECK-NEXT:    ret i1 false
1449   %xabs = call nnan ninf float @llvm.fabs.f32(float %x)
1450   %r = fcmp ueq float %xabs, 0x7FF0000000000000
1451   ret i1 %r
1454 define i1 @is_infinite_or_nan2_assume(float %x) {
1455 ; CHECK-LABEL: @is_infinite_or_nan2_assume(
1456 ; CHECK-NEXT:    [[XABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1457 ; CHECK-NEXT:    [[IS_INF_OR_NAN:%.*]] = fcmp one float [[XABS]], 0x7FF0000000000000
1458 ; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_INF_OR_NAN]])
1459 ; CHECK-NEXT:    ret i1 false
1461   %xabs = call float @llvm.fabs.f32(float %x)
1462   %is.inf.or.nan = fcmp one float %xabs, 0x7FF0000000000000
1463   call void @llvm.assume(i1 %is.inf.or.nan)
1464   %r = fcmp ueq float %xabs, 0x7FF0000000000000
1465   ret i1 %r
1468 define <2 x i1> @is_infinite_neg_or_nan(<2 x float> %x) {
1469 ; CHECK-LABEL: @is_infinite_neg_or_nan(
1470 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1472   %x42 = fadd nnan ninf <2 x float> %x, <float 42.0, float 42.0>
1473   %r = fcmp ueq <2 x float> %x42, <float 0xFFF0000000000000, float 0xFFF0000000000000>
1474   ret <2 x i1> %r
1477 define i1 @is_finite_or_nan(i1 %c, double %x) {
1478 ; CHECK-LABEL: @is_finite_or_nan(
1479 ; CHECK-NEXT:    ret i1 true
1481   %xx = fmul ninf double %x, %x
1482   %s = select i1 %c, double 42.0, double %xx
1483   %r = fcmp une double %s, 0x7FF0000000000000
1484   ret i1 %r
1487 define <2 x i1> @is_finite_or_nan_commute(<2 x i8> %x) {
1488 ; CHECK-LABEL: @is_finite_or_nan_commute(
1489 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1491   %cast = uitofp <2 x i8> %x to <2 x float>
1492   %r = fcmp une <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1493   ret <2 x i1> %r
1496 ; Negative test - but this could be reduced to 'ord' outside of instsimplify.
1498 define i1 @is_finite_and_ordered(double %x) {
1499 ; CHECK-LABEL: @is_finite_and_ordered(
1500 ; CHECK-NEXT:    [[XX:%.*]] = fmul ninf double [[X:%.*]], [[X]]
1501 ; CHECK-NEXT:    [[R:%.*]] = fcmp one double [[XX]], 0x7FF0000000000000
1502 ; CHECK-NEXT:    ret i1 [[R]]
1504   %xx = fmul ninf double %x, %x
1505   %r = fcmp one double %xx, 0x7FF0000000000000
1506   ret i1 %r
1509 define i1 @is_finite(i1 %c, double %x) {
1510 ; CHECK-LABEL: @is_finite(
1511 ; CHECK-NEXT:    ret i1 true
1513   %xx = fmul nnan ninf double %x, %x
1514   %s = select i1 %c, double 42.0, double %xx
1515   %r = fcmp one double %s, 0x7FF0000000000000
1516   ret i1 %r
1519 define i1 @is_finite_assume(i1 %c, double %x) {
1520 ; CHECK-LABEL: @is_finite_assume(
1521 ; CHECK-NEXT:    [[XABS:%.*]] = call double @llvm.fabs.f64(double [[X:%.*]])
1522 ; CHECK-NEXT:    [[IS_INF_OR_NAN:%.*]] = fcmp one double [[XABS]], 0x7FF0000000000000
1523 ; CHECK-NEXT:    call void @llvm.assume(i1 [[IS_INF_OR_NAN]])
1524 ; CHECK-NEXT:    ret i1 true
1526   %xabs = call double @llvm.fabs.f64(double %x)
1527   %is.inf.or.nan = fcmp one double %xabs, 0x7FF0000000000000
1528   call void @llvm.assume(i1 %is.inf.or.nan)
1529   %s = select i1 %c, double 42.0, double %x
1530   %r = fcmp one double %s, 0x7FF0000000000000
1531   ret i1 %r
1534 define <2 x i1> @is_finite_commute(<2 x i8> %x) {
1535 ; CHECK-LABEL: @is_finite_commute(
1536 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1538   %cast = uitofp <2 x i8> %x to <2 x float>
1539   %r = fcmp one <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, %cast
1540   ret <2 x i1> %r
1543 define i1 @fcmp_oge_0_assumed_oge_zero(float %x) {
1544 ; CHECK-LABEL: @fcmp_oge_0_assumed_oge_zero(
1545 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1546 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1547 ; CHECK-NEXT:    ret i1 true
1549   %assume.cmp = fcmp oge float %x, 0.0
1550   call void @llvm.assume(i1 %assume.cmp)
1551   %r = fcmp oge float %x, 0.000000e+00
1552   ret i1 %r
1555 define i1 @fcmp_ult_0_assumed_oge_zero(float %x) {
1556 ; CHECK-LABEL: @fcmp_ult_0_assumed_oge_zero(
1557 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1558 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1559 ; CHECK-NEXT:    ret i1 false
1561   %assume.cmp = fcmp oge float %x, 0.0
1562   call void @llvm.assume(i1 %assume.cmp)
1563   %r = fcmp ult float %x, 0.000000e+00
1564   ret i1 %r
1567 define i1 @fcmp_uge_0_assumed_oge_zero(float %x) {
1568 ; CHECK-LABEL: @fcmp_uge_0_assumed_oge_zero(
1569 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1570 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1571 ; CHECK-NEXT:    ret i1 true
1573   %assume.cmp = fcmp oge float %x, 0.0
1574   call void @llvm.assume(i1 %assume.cmp)
1575   %r = fcmp uge float %x, 0.000000e+00
1576   ret i1 %r
1579 define i1 @fcmp_olt_0_assumed_oge_zero(float %x) {
1580 ; CHECK-LABEL: @fcmp_olt_0_assumed_oge_zero(
1581 ; CHECK-NEXT:    [[ASSUME_CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1582 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME_CMP]])
1583 ; CHECK-NEXT:    ret i1 false
1585   %assume.cmp = fcmp oge float %x, 0.0
1586   call void @llvm.assume(i1 %assume.cmp)
1587   %r = fcmp olt float %x, 0.000000e+00
1588   ret i1 %r
1591 define i1 @ogt_zero_fabs_select_negone_or_pinf(i1 %cond) {
1592 ; CHECK-LABEL: @ogt_zero_fabs_select_negone_or_pinf(
1593 ; CHECK-NEXT:  entry:
1594 ; CHECK-NEXT:    ret i1 true
1596 entry:
1597   %select = select i1 %cond, float -1.0, float 0x7FF0000000000000
1598   %fabs = call float @llvm.fabs.f32(float %select)
1599   %one = fcmp ogt float %fabs, 0.0
1600   ret i1 %one
1603 define i1 @ogt_zero_fabs_select_one_or_ninf(i1 %cond) {
1604 ; CHECK-LABEL: @ogt_zero_fabs_select_one_or_ninf(
1605 ; CHECK-NEXT:  entry:
1606 ; CHECK-NEXT:    ret i1 true
1608 entry:
1609   %select = select i1 %cond, float 1.0, float 0xFFF0000000000000
1610   %fabs = call float @llvm.fabs.f32(float %select)
1611   %one = fcmp ogt float %fabs, 0.0
1612   ret i1 %one
1615 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1616 define float @fast_square_must_be_positive_ieee(float %arg, float %arg1) {
1617 ; CHECK-LABEL: @fast_square_must_be_positive_ieee(
1618 ; CHECK-NEXT:  bb:
1619 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1620 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1621 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1622 ; CHECK-NEXT:    ret float [[I3]]
1625   %i = fmul float %arg, %arg
1626   %i2 = fmul float %arg1, %arg1
1627   %i3 = fadd float %i2, %i
1628   %i4 = fcmp olt float %i3, 0.000000e+00
1629   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1630   ret float %i5
1633 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1634 define float @fast_square_must_be_positive_ieee_nnan(float %arg, float %arg1) {
1635 ; CHECK-LABEL: @fast_square_must_be_positive_ieee_nnan(
1636 ; CHECK-NEXT:  bb:
1637 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1638 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1639 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1640 ; CHECK-NEXT:    ret float [[I3]]
1643   %i = fmul float %arg, %arg
1644   %i2 = fmul float %arg1, %arg1
1645   %i3 = fadd float %i2, %i
1646   %i4 = fcmp nnan olt float %i3, 0.000000e+00
1647   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1648   ret float %i5
1651 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1652 define float @fast_square_must_be_positive_daz(float %arg, float %arg1) #0 {
1653 ; CHECK-LABEL: @fast_square_must_be_positive_daz(
1654 ; CHECK-NEXT:  bb:
1655 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1656 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1657 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1658 ; CHECK-NEXT:    ret float [[I3]]
1661   %i = fmul float %arg, %arg
1662   %i2 = fmul float %arg1, %arg1
1663   %i3 = fadd float %i2, %i
1664   %i4 = fcmp olt float %i3, 0.000000e+00
1665   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1666   ret float %i5
1669 ; Make sure we recognize fcmp < 0 is recognized as impossible here when simplifying the fcmp
1670 define float @fast_square_must_be_positive_daz_nnan(float %arg, float %arg1) #0 {
1671 ; CHECK-LABEL: @fast_square_must_be_positive_daz_nnan(
1672 ; CHECK-NEXT:  bb:
1673 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1674 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1675 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1676 ; CHECK-NEXT:    ret float [[I3]]
1679   %i = fmul float %arg, %arg
1680   %i2 = fmul float %arg1, %arg1
1681   %i3 = fadd float %i2, %i
1682   %i4 = fcmp nnan olt float %i3, 0.000000e+00
1683   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1684   ret float %i5
1687 ; Make the compare to negative constant is folded out
1688 define float @must_be_olt_negative_constant_daz(float %arg, float %arg1) #0 {
1689 ; CHECK-LABEL: @must_be_olt_negative_constant_daz(
1690 ; CHECK-NEXT:  bb:
1691 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1692 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1693 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1694 ; CHECK-NEXT:    ret float [[I3]]
1697   %i = fmul float %arg, %arg
1698   %i2 = fmul float %arg1, %arg1
1699   %i3 = fadd float %i2, %i
1700   %i4 = fcmp olt float %i3, -1.0
1701   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1702   ret float %i5
1705 ; Make the compare to negative constant is folded out
1706 define float @must_be_olt_negative_constant_daz_nnan(float %arg, float %arg1) #0 {
1707 ; CHECK-LABEL: @must_be_olt_negative_constant_daz_nnan(
1708 ; CHECK-NEXT:  bb:
1709 ; CHECK-NEXT:    [[I:%.*]] = fmul float [[ARG:%.*]], [[ARG]]
1710 ; CHECK-NEXT:    [[I2:%.*]] = fmul float [[ARG1:%.*]], [[ARG1]]
1711 ; CHECK-NEXT:    [[I3:%.*]] = fadd float [[I2]], [[I]]
1712 ; CHECK-NEXT:    ret float [[I3]]
1715   %i = fmul float %arg, %arg
1716   %i2 = fmul float %arg1, %arg1
1717   %i3 = fadd float %i2, %i
1718   %i4 = fcmp nnan olt float %i3, -1.0
1719   %i5 = select i1 %i4, float 0.000000e+00, float %i3
1720   ret float %i5
1723 define i1 @is_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
1724 ; CHECK-LABEL: @is_olt_smallest_normal_dynamic(
1725 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1726 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1728   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1729   ret i1 %is.denorm.or.zero
1732 define i1 @is_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
1733 ; CHECK-LABEL: @is_olt_smallest_normal_ieee(
1734 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1735 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1737   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1738   ret i1 %is.denorm.or.zero
1741 define i1 @is_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
1742 ; CHECK-LABEL: @is_olt_smallest_normal_preserve_sign(
1743 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1744 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1746   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1747   ret i1 %is.denorm.or.zero
1750 define i1 @is_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
1751 ; CHECK-LABEL: @is_olt_smallest_normal_positive_zero(
1752 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
1753 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1755   %is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
1756   ret i1 %is.denorm.or.zero
1759 define i1 @is_fabs_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
1760 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_dynamic(
1761 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1762 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1763 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1765   %fabs.x = call float @llvm.fabs.f32(float %x)
1766   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1767   ret i1 %is.denorm.or.zero
1770 define i1 @is_fabs_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
1771 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_ieee(
1772 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1773 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1774 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1776   %fabs.x = call float @llvm.fabs.f32(float %x)
1777   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1778   ret i1 %is.denorm.or.zero
1781 define i1 @is_fabs_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
1782 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_preserve_sign(
1783 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1784 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1785 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1787   %fabs.x = call float @llvm.fabs.f32(float %x)
1788   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1789   ret i1 %is.denorm.or.zero
1792 define i1 @is_fabs_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
1793 ; CHECK-LABEL: @is_fabs_olt_smallest_normal_positive_zero(
1794 ; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1795 ; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
1796 ; CHECK-NEXT:    ret i1 [[IS_DENORM_OR_ZERO]]
1798   %fabs.x = call float @llvm.fabs.f32(float %x)
1799   %is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
1800   ret i1 %is.denorm.or.zero
1804 declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
1805 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
1806 declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)
1807 declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>)
1808 declare <3 x float> @llvm.fabs.v3f32(<3 x float>)
1809 declare double @llvm.exp2.f64(double)
1810 declare double @llvm.fabs.f64(double)
1811 declare double @llvm.powi.f64.i32(double, i32)
1812 declare float @llvm.exp.f32(float)
1813 declare float @llvm.fabs.f32(float)
1814 declare float @llvm.fma.f32(float, float, float)
1815 declare float @llvm.maximum.f32(float, float)
1816 declare float @llvm.maxnum.f32(float, float)
1817 declare float @llvm.minnum.f32(float, float)
1818 declare float @llvm.sqrt.f32(float)
1819 declare double @llvm.sqrt.f64(double)
1820 declare double @llvm.copysign.f64(double, double)
1821 declare half @llvm.fabs.f16(half)
1822 declare void @llvm.assume(i1 noundef)
1824 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }