1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
6 define i1 @inf0(double %arg) {
8 ; CHECK-NEXT: ret i1 false
10 %tmp = fcmp ogt double %arg, 0x7FF0000000000000
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
23 define i1 @inf1(double %arg) {
25 ; CHECK-NEXT: ret i1 true
27 %tmp = fcmp ule double %arg, 0x7FF0000000000000
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
42 define i1 @ninf0(double %arg) {
43 ; CHECK-LABEL: @ninf0(
44 ; CHECK-NEXT: ret i1 false
46 %tmp = fcmp olt double %arg, 0xFFF0000000000000
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
59 define i1 @ninf1(double %arg) {
60 ; CHECK-LABEL: @ninf1(
61 ; CHECK-NEXT: ret i1 true
63 %tmp = fcmp uge double %arg, 0xFFF0000000000000
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
78 define i1 @nan0(double %arg) {
80 ; CHECK-NEXT: ret i1 false
82 %tmp = fcmp ord double %arg, 0x7FF00000FFFFFFFF
86 define i1 @nan1(double %arg) {
88 ; CHECK-NEXT: ret i1 false
90 %tmp = fcmp oeq double %arg, 0x7FF00000FFFFFFFF
94 define i1 @nan2(double %arg) {
96 ; CHECK-NEXT: ret i1 false
98 %tmp = fcmp olt double %arg, 0x7FF00000FFFFFFFF
102 define i1 @nan3(double %arg) {
103 ; CHECK-LABEL: @nan3(
104 ; CHECK-NEXT: ret i1 true
106 %tmp = fcmp uno double %arg, 0x7FF00000FFFFFFFF
110 define i1 @nan4(double %arg) {
111 ; CHECK-LABEL: @nan4(
112 ; CHECK-NEXT: ret i1 true
114 %tmp = fcmp une double %arg, 0x7FF00000FFFFFFFF
118 define i1 @nan5(double %arg) {
119 ; CHECK-LABEL: @nan5(
120 ; CHECK-NEXT: ret i1 true
122 %tmp = fcmp ult double %arg, 0x7FF00000FFFFFFFF
128 define i1 @nnan0(double %arg) {
129 ; CHECK-LABEL: @nnan0(
130 ; CHECK-NEXT: ret i1 false
132 %tmp = fcmp ord double %arg, 0xFFF00000FFFFFFFF
136 define i1 @nnan1(double %arg) {
137 ; CHECK-LABEL: @nnan1(
138 ; CHECK-NEXT: ret i1 false
140 %tmp = fcmp oeq double %arg, 0xFFF00000FFFFFFFF
144 define i1 @nnan2(double %arg) {
145 ; CHECK-LABEL: @nnan2(
146 ; CHECK-NEXT: ret i1 false
148 %tmp = fcmp olt double %arg, 0xFFF00000FFFFFFFF
152 define i1 @nnan3(double %arg) {
153 ; CHECK-LABEL: @nnan3(
154 ; CHECK-NEXT: ret i1 true
156 %tmp = fcmp uno double %arg, 0xFFF00000FFFFFFFF
160 define i1 @nnan4(double %arg) {
161 ; CHECK-LABEL: @nnan4(
162 ; CHECK-NEXT: ret i1 true
164 %tmp = fcmp une double %arg, 0xFFF00000FFFFFFFF
168 define i1 @nnan5(double %arg) {
169 ; CHECK-LABEL: @nnan5(
170 ; CHECK-NEXT: ret i1 true
172 %tmp = fcmp ult double %arg, 0xFFF00000FFFFFFFF
178 define i1 @nzero0() {
179 ; CHECK-LABEL: @nzero0(
180 ; CHECK-NEXT: ret i1 true
182 %tmp = fcmp oeq double 0.0, -0.0
186 define i1 @nzero1() {
187 ; CHECK-LABEL: @nzero1(
188 ; CHECK-NEXT: ret i1 false
190 %tmp = fcmp ogt double 0.0, -0.0
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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>
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>
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>
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>
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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
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
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
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
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>
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
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>
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
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
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
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>
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>
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>
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
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
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
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>
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
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
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
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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(
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
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(
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
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(
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
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(
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
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(
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
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(
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
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" }