1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare half @llvm.fabs.f16(half)
5 declare double @llvm.fabs.f64(double)
6 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
7 declare double @llvm.copysign.f64(double, double)
8 declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>)
10 declare void @use(float)
12 define i1 @fpext_fpext(float %x, float %y) {
13 ; CHECK-LABEL: @fpext_fpext(
14 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
15 ; CHECK-NEXT: ret i1 [[CMP]]
17 %ext1 = fpext float %x to double
18 %ext2 = fpext float %y to double
19 %cmp = fcmp nnan ogt double %ext1, %ext2
23 define i1 @fpext_constant(float %a) {
24 ; CHECK-LABEL: @fpext_constant(
25 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[A:%.*]], 1.000000e+00
26 ; CHECK-NEXT: ret i1 [[CMP]]
28 %ext = fpext float %a to double
29 %cmp = fcmp ninf ogt double %ext, 1.000000e+00
33 define <2 x i1> @fpext_constant_vec_splat(<2 x half> %a) {
34 ; CHECK-LABEL: @fpext_constant_vec_splat(
35 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ole <2 x half> [[A:%.*]], splat (half 0xH5140)
36 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
38 %ext = fpext <2 x half> %a to <2 x double>
39 %cmp = fcmp nnan ole <2 x double> %ext, <double 42.0, double 42.0>
43 define i1 @fpext_constant_lossy(float %a) {
44 ; CHECK-LABEL: @fpext_constant_lossy(
45 ; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
46 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
47 ; CHECK-NEXT: ret i1 [[CMP]]
49 %ext = fpext float %a to double
50 %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
54 define i1 @fpext_constant_denorm(float %a) {
55 ; CHECK-LABEL: @fpext_constant_denorm(
56 ; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
57 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
58 ; CHECK-NEXT: ret i1 [[CMP]]
60 %ext = fpext float %a to double
61 %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
65 define i1 @fneg_constant_swap_pred(float %x) {
66 ; CHECK-LABEL: @fneg_constant_swap_pred(
67 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
68 ; CHECK-NEXT: ret i1 [[CMP]]
70 %neg = fsub float -0.0, %x
71 %cmp = fcmp ogt float %neg, 1.0
75 define i1 @unary_fneg_constant_swap_pred(float %x) {
76 ; CHECK-LABEL: @unary_fneg_constant_swap_pred(
77 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
78 ; CHECK-NEXT: ret i1 [[CMP]]
81 %cmp = fcmp ogt float %neg, 1.0
85 define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
86 ; CHECK-LABEL: @fneg_constant_swap_pred_vec(
87 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
88 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
90 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
91 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
95 define <2 x i1> @unary_fneg_constant_swap_pred_vec(<2 x float> %x) {
96 ; CHECK-LABEL: @unary_fneg_constant_swap_pred_vec(
97 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
98 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
100 %neg = fneg <2 x float> %x
101 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
105 define <2 x i1> @fneg_constant_swap_pred_vec_poison(<2 x float> %x) {
106 ; CHECK-LABEL: @fneg_constant_swap_pred_vec_poison(
107 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
108 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
110 %neg = fsub <2 x float> <float poison, float -0.0>, %x
111 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
115 ; The new fcmp should have the same FMF as the original.
117 define i1 @fneg_fmf(float %x) {
118 ; CHECK-LABEL: @fneg_fmf(
119 ; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
120 ; CHECK-NEXT: ret i1 [[R]]
122 %n = fsub fast float -0.0, %x
123 %r = fcmp fast oeq float %n, 42.0
127 define i1 @unary_fneg_fmf(float %x) {
128 ; CHECK-LABEL: @unary_fneg_fmf(
129 ; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
130 ; CHECK-NEXT: ret i1 [[R]]
132 %n = fneg fast float %x
133 %r = fcmp fast oeq float %n, 42.0
137 ; The new fcmp should have the same FMF as the original, vector edition.
139 define <2 x i1> @fcmp_fneg_fmf_vec(<2 x float> %x) {
140 ; CHECK-LABEL: @fcmp_fneg_fmf_vec(
141 ; CHECK-NEXT: [[R:%.*]] = fcmp reassoc nnan ule <2 x float> [[X:%.*]], <float -4.200000e+01, float 1.900000e+01>
142 ; CHECK-NEXT: ret <2 x i1> [[R]]
144 %n = fsub nsz <2 x float> zeroinitializer, %x
145 %r = fcmp nnan reassoc uge <2 x float> %n, <float 42.0, float -19.0>
149 define i1 @fneg_fneg_swap_pred(float %x, float %y) {
150 ; CHECK-LABEL: @fneg_fneg_swap_pred(
151 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
152 ; CHECK-NEXT: ret i1 [[CMP]]
154 %neg1 = fsub float -0.0, %x
155 %neg2 = fsub float -0.0, %y
156 %cmp = fcmp nnan olt float %neg1, %neg2
160 define i1 @unary_fneg_unary_fneg_swap_pred(float %x, float %y) {
161 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred(
162 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
163 ; CHECK-NEXT: ret i1 [[CMP]]
165 %neg1 = fneg float %x
166 %neg2 = fneg float %y
167 %cmp = fcmp nnan olt float %neg1, %neg2
171 define i1 @unary_fneg_fneg_swap_pred(float %x, float %y) {
172 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred(
173 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
174 ; CHECK-NEXT: ret i1 [[CMP]]
176 %neg1 = fneg float %x
177 %neg2 = fsub float -0.0, %y
178 %cmp = fcmp nnan olt float %neg1, %neg2
182 define i1 @fneg_unary_fneg_swap_pred(float %x, float %y) {
183 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred(
184 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
185 ; CHECK-NEXT: ret i1 [[CMP]]
187 %neg1 = fsub float -0.0, %x
188 %neg2 = fneg float %y
189 %cmp = fcmp nnan olt float %neg1, %neg2
193 define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
194 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
195 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
196 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
198 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
199 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
200 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
204 define <2 x i1> @unary_fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
205 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred_vec(
206 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
207 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
209 %neg1 = fneg <2 x float> %x
210 %neg2 = fneg <2 x float> %y
211 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
215 define <2 x i1> @unary_fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
216 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec(
217 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
218 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
220 %neg1 = fneg <2 x float> %x
221 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
222 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
226 define <2 x i1> @fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
227 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec(
228 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
229 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
231 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
232 %neg2 = fneg <2 x float> %y
233 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
237 define <2 x i1> @fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
238 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec_poison(
239 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
240 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
242 %neg1 = fsub <2 x float> <float -0.0, float poison>, %x
243 %neg2 = fsub <2 x float> <float poison, float -0.0>, %y
244 %cmp = fcmp olt <2 x float> %neg1, %neg2
248 define <2 x i1> @unary_fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
249 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec_poison(
250 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
251 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
253 %neg1 = fneg <2 x float> %x
254 %neg2 = fsub <2 x float> <float poison, float -0.0>, %y
255 %cmp = fcmp olt <2 x float> %neg1, %neg2
259 define <2 x i1> @fneg_unary_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
260 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec_poison(
261 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
262 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
264 %neg1 = fsub <2 x float> <float -0.0, float poison>, %x
265 %neg2 = fneg <2 x float> %y
266 %cmp = fcmp olt <2 x float> %neg1, %neg2
270 define i1 @test7(float %x) {
271 ; CHECK-LABEL: @test7(
272 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
273 ; CHECK-NEXT: ret i1 [[CMP]]
275 %ext = fpext float %x to ppc_fp128
276 %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
280 define float @test8(float %x) {
281 ; CHECK-LABEL: @test8(
282 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
283 ; CHECK-NEXT: [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
284 ; CHECK-NEXT: ret float [[CONV2]]
286 %conv = fpext float %x to double
287 %cmp = fcmp olt double %conv, 0.000000e+00
288 %conv1 = zext i1 %cmp to i32
289 %conv2 = sitofp i32 %conv1 to float
291 ; Float comparison to zero shouldn't cast to double.
294 define i1 @fabs_uge(double %a) {
295 ; CHECK-LABEL: @fabs_uge(
296 ; CHECK-NEXT: ret i1 true
298 %call = call double @llvm.fabs.f64(double %a)
299 %cmp = fcmp uge double %call, 0.0
303 define i1 @fabs_olt(half %a) {
304 ; CHECK-LABEL: @fabs_olt(
305 ; CHECK-NEXT: ret i1 false
307 %call = call half @llvm.fabs.f16(half %a)
308 %cmp = fcmp olt half %call, 0.0
312 define <2 x i1> @fabs_ole(<2 x float> %a) {
313 ; CHECK-LABEL: @fabs_ole(
314 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq <2 x float> [[A:%.*]], zeroinitializer
315 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
317 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
318 %cmp = fcmp ninf ole <2 x float> %call, zeroinitializer
322 define <2 x i1> @fabs_ule(<2 x float> %a) {
323 ; CHECK-LABEL: @fabs_ule(
324 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf arcp ueq <2 x float> [[A:%.*]], zeroinitializer
325 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
327 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
328 %cmp = fcmp ninf arcp ule <2 x float> %call, zeroinitializer
332 define i1 @fabs_ogt(double %a) {
333 ; CHECK-LABEL: @fabs_ogt(
334 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc one double [[A:%.*]], 0.000000e+00
335 ; CHECK-NEXT: ret i1 [[CMP]]
337 %call = call double @llvm.fabs.f64(double %a)
338 %cmp = fcmp reassoc ogt double %call, 0.0
342 define i1 @fabs_ugt(double %a) {
343 ; CHECK-LABEL: @fabs_ugt(
344 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf une double [[A:%.*]], 0.000000e+00
345 ; CHECK-NEXT: ret i1 [[CMP]]
347 %call = call double @llvm.fabs.f64(double %a)
348 %cmp = fcmp ninf reassoc ugt double %call, 0.0
352 define i1 @fabs_oge(double %a) {
353 ; CHECK-LABEL: @fabs_oge(
354 ; CHECK-NEXT: [[CMP:%.*]] = fcmp afn ord double [[A:%.*]], 0.000000e+00
355 ; CHECK-NEXT: ret i1 [[CMP]]
357 %call = call double @llvm.fabs.f64(double %a)
358 %cmp = fcmp afn oge double %call, 0.0
362 define i1 @fabs_ult(double %a) {
363 ; CHECK-LABEL: @fabs_ult(
364 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc arcp uno double [[A:%.*]], 0.000000e+00
365 ; CHECK-NEXT: ret i1 [[CMP]]
367 %call = call double @llvm.fabs.f64(double %a)
368 %cmp = fcmp reassoc arcp ult double %call, 0.0
372 define <2 x i1> @fabs_ult_nnan(<2 x float> %a) {
373 ; CHECK-LABEL: @fabs_ult_nnan(
374 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
376 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
377 %cmp = fcmp nnan reassoc arcp ult <2 x float> %call, zeroinitializer
381 define i1 @fabs_une(half %a) {
382 ; CHECK-LABEL: @fabs_une(
383 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une half [[A:%.*]], 0xH0000
384 ; CHECK-NEXT: ret i1 [[CMP]]
386 %call = call half @llvm.fabs.f16(half %a)
387 %cmp = fcmp ninf une half %call, 0.0
391 define i1 @fabs_oeq(double %a) {
392 ; CHECK-LABEL: @fabs_oeq(
393 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf oeq double [[A:%.*]], 0.000000e+00
394 ; CHECK-NEXT: ret i1 [[CMP]]
396 %call = call double @llvm.fabs.f64(double %a)
397 %cmp = fcmp ninf reassoc oeq double %call, 0.0
401 define i1 @fabs_one(double %a) {
402 ; CHECK-LABEL: @fabs_one(
403 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast one double [[A:%.*]], 0.000000e+00
404 ; CHECK-NEXT: ret i1 [[CMP]]
406 %call = call double @llvm.fabs.f64(double %a)
407 %cmp = fcmp fast one double %call, 0.0
411 define <2 x i1> @fabs_ueq(<2 x float> %a) {
412 ; CHECK-LABEL: @fabs_ueq(
413 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ueq <2 x float> [[A:%.*]], zeroinitializer
414 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
416 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
417 %cmp = fcmp arcp ueq <2 x float> %call, zeroinitializer
421 define <2 x i1> @fabs_ord(<2 x float> %a) {
422 ; CHECK-LABEL: @fabs_ord(
423 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ord <2 x float> [[A:%.*]], zeroinitializer
424 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
426 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
427 %cmp = fcmp arcp ord <2 x float> %call, zeroinitializer
431 define <2 x i1> @fabs_uno(<2 x float> %a) {
432 ; CHECK-LABEL: @fabs_uno(
433 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp uno <2 x float> [[A:%.*]], zeroinitializer
434 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
436 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
437 %cmp = fcmp arcp uno <2 x float> %call, zeroinitializer
442 define i32 @test17(double %a, ptr %p) {
443 ; CHECK-LABEL: @test17(
444 ; CHECK-NEXT: [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
445 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
446 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
447 ; CHECK-NEXT: ret i32 [[CONV]]
449 %call = tail call double %p(double %a)
450 %cmp = fcmp ueq double %call, 0.000000e+00
451 %conv = zext i1 %cmp to i32
455 ; Can fold fcmp with undef on one side by choosing NaN for the undef
456 define i32 @test18_undef_unordered(float %a) {
457 ; CHECK-LABEL: @test18_undef_unordered(
458 ; CHECK-NEXT: ret i32 1
460 %cmp = fcmp ueq float %a, undef
461 %conv = zext i1 %cmp to i32
464 ; Can fold fcmp with undef on one side by choosing NaN for the undef
465 define i32 @test18_undef_ordered(float %a) {
466 ; CHECK-LABEL: @test18_undef_ordered(
467 ; CHECK-NEXT: ret i32 0
469 %cmp = fcmp oeq float %a, undef
470 %conv = zext i1 %cmp to i32
474 ; Can fold fcmp with undef on both side
475 ; fcmp u_pred undef, undef -> true
476 ; fcmp o_pred undef, undef -> false
477 ; because whatever you choose for the first undef
478 ; you can choose NaN for the other undef
479 define i1 @test19_undef_unordered() {
480 ; CHECK-LABEL: @test19_undef_unordered(
481 ; CHECK-NEXT: ret i1 true
483 %cmp = fcmp ueq float undef, undef
487 define i1 @test19_undef_ordered() {
488 ; CHECK-LABEL: @test19_undef_ordered(
489 ; CHECK-NEXT: ret i1 false
491 %cmp = fcmp oeq float undef, undef
495 ; Can fold 1.0 / X < 0.0 --> X < 0 with ninf
496 define i1 @test20_recipX_olt_0(float %X) {
497 ; CHECK-LABEL: @test20_recipX_olt_0(
498 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt float [[X:%.*]], 0.000000e+00
499 ; CHECK-NEXT: ret i1 [[CMP]]
501 %div = fdiv ninf float 1.0, %X
502 %cmp = fcmp ninf olt float %div, 0.0
506 ; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf
507 define i1 @test21_recipX_ole_0(float %X) {
508 ; CHECK-LABEL: @test21_recipX_ole_0(
509 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oge float [[X:%.*]], 0.000000e+00
510 ; CHECK-NEXT: ret i1 [[CMP]]
512 %div = fdiv ninf float -2.0, %X
513 %cmp = fcmp ninf ole float %div, 0.0
517 ; Can fold 2.0 / X > 0.0 --> X > 0 with ninf
518 define i1 @test22_recipX_ogt_0(float %X) {
519 ; CHECK-LABEL: @test22_recipX_ogt_0(
520 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[X:%.*]], 0.000000e+00
521 ; CHECK-NEXT: ret i1 [[CMP]]
523 %div = fdiv ninf float 2.0, %X
524 %cmp = fcmp ninf ogt float %div, 0.0
528 ; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf
529 define i1 @test23_recipX_oge_0(float %X) {
530 ; CHECK-LABEL: @test23_recipX_oge_0(
531 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ole float [[X:%.*]], 0.000000e+00
532 ; CHECK-NEXT: ret i1 [[CMP]]
534 %div = fdiv ninf float -1.0, %X
535 %cmp = fcmp ninf oge float %div, 0.0
539 ; Do not fold 1.0 / X > 0.0 when ninf is missing
540 define i1 @test24_recipX_noninf_cmp(float %X) {
541 ; CHECK-LABEL: @test24_recipX_noninf_cmp(
542 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
543 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[DIV]], 0.000000e+00
544 ; CHECK-NEXT: ret i1 [[CMP]]
546 %div = fdiv ninf float 2.0, %X
547 %cmp = fcmp ogt float %div, 0.0
551 ; Do not fold 1.0 / X > 0.0 when ninf is missing
552 define i1 @test25_recipX_noninf_div(float %X) {
553 ; CHECK-LABEL: @test25_recipX_noninf_div(
554 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float 2.000000e+00, [[X:%.*]]
555 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[DIV]], 0.000000e+00
556 ; CHECK-NEXT: ret i1 [[CMP]]
558 %div = fdiv float 2.0, %X
559 %cmp = fcmp ninf ogt float %div, 0.0
563 ; Do not fold 1.0 / X > 0.0 with unordered predicates
564 define i1 @test26_recipX_unorderd(float %X) {
565 ; CHECK-LABEL: @test26_recipX_unorderd(
566 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
567 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ugt float [[DIV]], 0.000000e+00
568 ; CHECK-NEXT: ret i1 [[CMP]]
570 %div = fdiv ninf float 2.0, %X
571 %cmp = fcmp ninf ugt float %div, 0.0
575 ; Fold <-1.0, -1.0> / X > <-0.0, -0.0>
576 define <2 x i1> @test27_recipX_gt_vecsplat(<2 x float> %X) {
577 ; CHECK-LABEL: @test27_recipX_gt_vecsplat(
578 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer
579 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
581 %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X
582 %cmp = fcmp ninf ogt <2 x float> %div, <float -0.0, float -0.0>
586 define i1 @is_signbit_set(double %x) {
587 ; CHECK-LABEL: @is_signbit_set(
588 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
589 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[TMP1]], 0
590 ; CHECK-NEXT: ret i1 [[R]]
592 %s = call double @llvm.copysign.f64(double 1.0, double %x)
593 %r = fcmp olt double %s, 0.0
597 define i1 @is_signbit_set_1(double %x) {
598 ; CHECK-LABEL: @is_signbit_set_1(
599 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
600 ; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[S]], 0.000000e+00
601 ; CHECK-NEXT: ret i1 [[R]]
603 %s = call double @llvm.copysign.f64(double 1.0, double %x)
604 %r = fcmp ult double %s, 0.0
608 define i1 @is_signbit_set_2(double %x) {
609 ; CHECK-LABEL: @is_signbit_set_2(
610 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
611 ; CHECK-NEXT: [[R:%.*]] = fcmp ole double [[S]], 0.000000e+00
612 ; CHECK-NEXT: ret i1 [[R]]
614 %s = call double @llvm.copysign.f64(double 1.0, double %x)
615 %r = fcmp ole double %s, 0.0
619 define i1 @is_signbit_set_3(double %x) {
620 ; CHECK-LABEL: @is_signbit_set_3(
621 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
622 ; CHECK-NEXT: [[R:%.*]] = fcmp ule double [[S]], 0.000000e+00
623 ; CHECK-NEXT: ret i1 [[R]]
625 %s = call double @llvm.copysign.f64(double 1.0, double %x)
626 %r = fcmp ule double %s, 0.0
630 ; Vectors are ok; the sign of zero in the compare doesn't matter; the copysign constant can be any non-zero number.
632 define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) {
633 ; CHECK-LABEL: @is_signbit_set_anyzero(
634 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
635 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i64> [[TMP1]], zeroinitializer
636 ; CHECK-NEXT: ret <2 x i1> [[R]]
638 %s = call <2 x double> @llvm.copysign.v2f64(<2 x double> <double 42.0, double 42.0>, <2 x double> %x)
639 %r = fcmp olt <2 x double> %s, <double -0.0, double 0.0>
643 ; TODO: Handle different predicates.
645 define i1 @is_signbit_clear(double %x) {
646 ; CHECK-LABEL: @is_signbit_clear(
647 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
648 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
649 ; CHECK-NEXT: ret i1 [[R]]
651 %s = call double @llvm.copysign.f64(double -42.0, double %x)
652 %r = fcmp ogt double %s, 0.0
656 define i1 @is_signbit_clear_1(double %x) {
657 ; CHECK-LABEL: @is_signbit_clear_1(
658 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
659 ; CHECK-NEXT: [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00
660 ; CHECK-NEXT: ret i1 [[R]]
662 %s = call double @llvm.copysign.f64(double -42.0, double %x)
663 %r = fcmp ugt double %s, 0.0
667 define i1 @is_signbit_clear_2(double %x) {
668 ; CHECK-LABEL: @is_signbit_clear_2(
669 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
670 ; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00
671 ; CHECK-NEXT: ret i1 [[R]]
673 %s = call double @llvm.copysign.f64(double -42.0, double %x)
674 %r = fcmp oge double %s, 0.0
678 define i1 @is_signbit_clear_3(double %x) {
679 ; CHECK-LABEL: @is_signbit_clear_3(
680 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
681 ; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00
682 ; CHECK-NEXT: ret i1 [[R]]
684 %s = call double @llvm.copysign.f64(double -42.0, double %x)
685 %r = fcmp uge double %s, 0.0
689 ; Negative test - uses
691 define i1 @is_signbit_set_extra_use(double %x, ptr %p) {
692 ; CHECK-LABEL: @is_signbit_set_extra_use(
693 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
694 ; CHECK-NEXT: store double [[S]], ptr [[P:%.*]], align 8
695 ; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[S]], 0.000000e+00
696 ; CHECK-NEXT: ret i1 [[R]]
698 %s = call double @llvm.copysign.f64(double 1.0, double %x)
699 store double %s, ptr %p
700 %r = fcmp olt double %s, 0.0
704 ; TODO: Handle non-zero compare constant.
706 define i1 @is_signbit_clear_nonzero(double %x) {
707 ; CHECK-LABEL: @is_signbit_clear_nonzero(
708 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
709 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00
710 ; CHECK-NEXT: ret i1 [[R]]
712 %s = call double @llvm.copysign.f64(double -42.0, double %x)
713 %r = fcmp ogt double %s, 1.0
717 ; TODO: Handle zero copysign constant.
719 define i1 @is_signbit_set_simplify_zero(double %x) {
720 ; CHECK-LABEL: @is_signbit_set_simplify_zero(
721 ; CHECK-NEXT: ret i1 false
723 %s = call double @llvm.copysign.f64(double 0.0, double %x)
724 %r = fcmp ogt double %s, 0.0
728 ; TODO: Handle NaN copysign constant.
730 define i1 @is_signbit_set_simplify_nan(double %x) {
731 ; CHECK-LABEL: @is_signbit_set_simplify_nan(
732 ; CHECK-NEXT: ret i1 false
734 %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
735 %r = fcmp ogt double %s, 0.0
739 define <2 x i1> @lossy_oeq(<2 x float> %x) {
740 ; CHECK-LABEL: @lossy_oeq(
741 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
743 %e = fpext <2 x float> %x to <2 x double>
744 %r = fcmp oeq <2 x double> %e, <double 0.1, double 0.1>
748 define i1 @lossy_one(float %x, ptr %p) {
749 ; CHECK-LABEL: @lossy_one(
750 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
751 ; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8
752 ; CHECK-NEXT: [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00
753 ; CHECK-NEXT: ret i1 [[R]]
755 %e = fpext float %x to double
756 store double %e, ptr %p
757 %r = fcmp one double %e, 0.1
761 define i1 @lossy_ueq(half %x) {
762 ; CHECK-LABEL: @lossy_ueq(
763 ; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
764 ; CHECK-NEXT: ret i1 [[R]]
766 %e = fpext half %x to double
767 %r = fcmp ueq double %e, 65536.0
771 define i1 @lossy_une(half %x) {
772 ; CHECK-LABEL: @lossy_une(
773 ; CHECK-NEXT: ret i1 true
775 %e = fpext half %x to float
776 %r = fcmp une float %e, 2049.0
780 define <2 x i1> @lossy_ogt(<2 x float> %x) {
781 ; CHECK-LABEL: @lossy_ogt(
782 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
783 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt <2 x double> [[E]], splat (double 1.000000e-01)
784 ; CHECK-NEXT: ret <2 x i1> [[R]]
786 %e = fpext <2 x float> %x to <2 x double>
787 %r = fcmp ogt <2 x double> %e, <double 0.1, double 0.1>
791 define i1 @lossy_oge(float %x, ptr %p) {
792 ; CHECK-LABEL: @lossy_oge(
793 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
794 ; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8
795 ; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[E]], 1.000000e-01
796 ; CHECK-NEXT: ret i1 [[R]]
798 %e = fpext float %x to double
799 store double %e, ptr %p
800 %r = fcmp oge double %e, 0.1
804 define i1 @lossy_olt(half %x) {
805 ; CHECK-LABEL: @lossy_olt(
806 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
807 ; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[E]], 6.553600e+04
808 ; CHECK-NEXT: ret i1 [[R]]
810 %e = fpext half %x to double
811 %r = fcmp olt double %e, 65536.0
815 define i1 @lossy_ole(half %x) {
816 ; CHECK-LABEL: @lossy_ole(
817 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
818 ; CHECK-NEXT: [[R:%.*]] = fcmp ole float [[E]], 2.049000e+03
819 ; CHECK-NEXT: ret i1 [[R]]
821 %e = fpext half %x to float
822 %r = fcmp ole float %e, 2049.0
826 define <2 x i1> @lossy_ugt(<2 x float> %x) {
827 ; CHECK-LABEL: @lossy_ugt(
828 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
829 ; CHECK-NEXT: [[R:%.*]] = fcmp ugt <2 x double> [[E]], splat (double 1.000000e-01)
830 ; CHECK-NEXT: ret <2 x i1> [[R]]
832 %e = fpext <2 x float> %x to <2 x double>
833 %r = fcmp ugt <2 x double> %e, <double 0.1, double 0.1>
837 define i1 @lossy_uge(float %x, ptr %p) {
838 ; CHECK-LABEL: @lossy_uge(
839 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
840 ; CHECK-NEXT: store double [[E]], ptr [[P:%.*]], align 8
841 ; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[E]], 1.000000e-01
842 ; CHECK-NEXT: ret i1 [[R]]
844 %e = fpext float %x to double
845 store double %e, ptr %p
846 %r = fcmp uge double %e, 0.1
850 define i1 @lossy_ult(half %x) {
851 ; CHECK-LABEL: @lossy_ult(
852 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
853 ; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[E]], 6.553600e+04
854 ; CHECK-NEXT: ret i1 [[R]]
856 %e = fpext half %x to double
857 %r = fcmp ult double %e, 65536.0
861 define i1 @lossy_ule(half %x) {
862 ; CHECK-LABEL: @lossy_ule(
863 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
864 ; CHECK-NEXT: [[R:%.*]] = fcmp ule float [[E]], 2.049000e+03
865 ; CHECK-NEXT: ret i1 [[R]]
867 %e = fpext half %x to float
868 %r = fcmp ule float %e, 2049.0
872 define i1 @lossy_ord(half %x) {
873 ; CHECK-LABEL: @lossy_ord(
874 ; CHECK-NEXT: [[R:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
875 ; CHECK-NEXT: ret i1 [[R]]
877 %e = fpext half %x to double
878 %r = fcmp ord double %e, 65536.0
882 define i1 @lossy_uno(half %x) {
883 ; CHECK-LABEL: @lossy_uno(
884 ; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
885 ; CHECK-NEXT: ret i1 [[R]]
887 %e = fpext half %x to float
888 %r = fcmp uno float %e, 2049.0
892 define i1 @fneg_oeq(float %a) {
893 ; CHECK-LABEL: @fneg_oeq(
894 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00
895 ; CHECK-NEXT: ret i1 [[CMP]]
897 %fneg = fneg float %a
898 %cmp = fcmp oeq float %fneg, %a
902 define i1 @fneg_ogt(half %a) {
903 ; CHECK-LABEL: @fneg_ogt(
904 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000
905 ; CHECK-NEXT: ret i1 [[CMP]]
908 %cmp = fcmp fast ogt half %fneg, %a
912 define <2 x i1> @fneg_oge(<2 x float> %a) {
913 ; CHECK-LABEL: @fneg_oge(
914 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole <2 x float> [[A:%.*]], zeroinitializer
915 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
917 %fneg = fneg fast <2 x float> %a
918 %cmp = fcmp oge <2 x float> %fneg, %a
922 define i1 @fneg_olt(float %a, ptr %q) {
923 ; CHECK-LABEL: @fneg_olt(
924 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]]
925 ; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4
926 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00
927 ; CHECK-NEXT: ret i1 [[CMP]]
929 %fneg = fneg float %a
930 store float %fneg, ptr %q
931 %cmp = fcmp olt float %fneg, %a
935 define i1 @fneg_ole(float %a) {
936 ; CHECK-LABEL: @fneg_ole(
937 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
938 ; CHECK-NEXT: ret i1 [[CMP]]
940 %fneg = fneg float %a
941 %cmp = fcmp nsz ole float %fneg, %a
945 define i1 @fneg_one(float %a) {
946 ; CHECK-LABEL: @fneg_one(
947 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00
948 ; CHECK-NEXT: ret i1 [[CMP]]
950 %fneg = fneg float %a
951 %cmp = fcmp nnan one float %fneg, %a
955 define i1 @fneg_ord(float %a) {
956 ; CHECK-LABEL: @fneg_ord(
957 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00
958 ; CHECK-NEXT: ret i1 [[CMP]]
960 %fneg = fneg float %a
961 %cmp = fcmp ninf ord float %fneg, %a
965 define i1 @fneg_uno(float %a) {
966 ; CHECK-LABEL: @fneg_uno(
967 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00
968 ; CHECK-NEXT: ret i1 [[CMP]]
970 %fneg = fneg float %a
971 %cmp = fcmp uno float %fneg, %a
975 define i1 @fneg_ueq(half %a) {
976 ; CHECK-LABEL: @fneg_ueq(
977 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000
978 ; CHECK-NEXT: ret i1 [[CMP]]
981 %cmp = fcmp fast ueq half %fneg, %a
985 define <2 x i1> @fneg_ugt(<2 x float> %a) {
986 ; CHECK-LABEL: @fneg_ugt(
987 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x float> [[A:%.*]], zeroinitializer
988 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
990 %fneg = fneg fast <2 x float> %a
991 %cmp = fcmp ugt <2 x float> %fneg, %a
995 define i1 @fneg_uge(float %a, ptr %q) {
996 ; CHECK-LABEL: @fneg_uge(
997 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]]
998 ; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4
999 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+00
1000 ; CHECK-NEXT: ret i1 [[CMP]]
1002 %fneg = fneg float %a
1003 store float %fneg, ptr %q
1004 %cmp = fcmp uge float %fneg, %a
1008 define i1 @fneg_ult(float %a) {
1009 ; CHECK-LABEL: @fneg_ult(
1010 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+00
1011 ; CHECK-NEXT: ret i1 [[CMP]]
1013 %fneg = fneg float %a
1014 %cmp = fcmp nsz ult float %fneg, %a
1018 define i1 @fneg_ule(float %a) {
1019 ; CHECK-LABEL: @fneg_ule(
1020 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+00
1021 ; CHECK-NEXT: ret i1 [[CMP]]
1023 %fneg = fneg float %a
1024 %cmp = fcmp nnan ule float %fneg, %a
1028 define i1 @fneg_une(float %a) {
1029 ; CHECK-LABEL: @fneg_une(
1030 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+00
1031 ; CHECK-NEXT: ret i1 [[CMP]]
1033 %fneg = fneg float %a
1034 %cmp = fcmp ninf une float %fneg, %a
1038 define i1 @fneg_oeq_swap(float %p) {
1039 ; CHECK-LABEL: @fneg_oeq_swap(
1040 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1041 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
1042 ; CHECK-NEXT: ret i1 [[CMP]]
1044 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1045 %fneg = fneg float %a
1046 %cmp = fcmp oeq float %a, %fneg
1050 define i1 @fneg_ogt_swap(half %p) {
1051 ; CHECK-LABEL: @fneg_ogt_swap(
1052 ; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1053 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ogt half [[A]], 0xH0000
1054 ; CHECK-NEXT: ret i1 [[CMP]]
1056 %a = fadd half %p, %p ; thwart complexity-based canonicalization
1057 %fneg = fneg half %a
1058 %cmp = fcmp fast ogt half %a, %fneg
1062 define <2 x i1> @fneg_oge_swap(<2 x float> %p) {
1063 ; CHECK-LABEL: @fneg_oge_swap(
1064 ; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1065 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer
1066 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1068 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1069 %fneg = fneg fast <2 x float> %a
1070 %cmp = fcmp oge <2 x float> %a, %fneg
1074 define i1 @fneg_olt_swap(float %p, ptr %q) {
1075 ; CHECK-LABEL: @fneg_olt_swap(
1076 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1077 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]]
1078 ; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4
1079 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+00
1080 ; CHECK-NEXT: ret i1 [[CMP]]
1082 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1083 %fneg = fneg float %a
1084 store float %fneg, ptr %q
1085 %cmp = fcmp olt float %a, %fneg
1089 define i1 @fneg_ole_swap(float %p) {
1090 ; CHECK-LABEL: @fneg_ole_swap(
1091 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1092 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ole float [[A]], 0.000000e+00
1093 ; CHECK-NEXT: ret i1 [[CMP]]
1095 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1096 %fneg = fneg float %a
1097 %cmp = fcmp nsz ole float %a, %fneg
1101 define i1 @fneg_one_swap(float %p) {
1102 ; CHECK-LABEL: @fneg_one_swap(
1103 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1104 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A]], 0.000000e+00
1105 ; CHECK-NEXT: ret i1 [[CMP]]
1107 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1108 %fneg = fneg float %a
1109 %cmp = fcmp nnan one float %a, %fneg
1113 define i1 @fneg_ord_swap(float %p) {
1114 ; CHECK-LABEL: @fneg_ord_swap(
1115 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1116 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A]], 0.000000e+00
1117 ; CHECK-NEXT: ret i1 [[CMP]]
1119 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1120 %fneg = fneg float %a
1121 %cmp = fcmp ninf ord float %a, %fneg
1125 define i1 @fneg_uno_swap(float %p) {
1126 ; CHECK-LABEL: @fneg_uno_swap(
1127 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1128 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A]], 0.000000e+00
1129 ; CHECK-NEXT: ret i1 [[CMP]]
1131 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1132 %fneg = fneg float %a
1133 %cmp = fcmp uno float %a, %fneg
1137 define i1 @fneg_ueq_swap(half %p) {
1138 ; CHECK-LABEL: @fneg_ueq_swap(
1139 ; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1140 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A]], 0xH0000
1141 ; CHECK-NEXT: ret i1 [[CMP]]
1143 %a = fadd half %p, %p ; thwart complexity-based canonicalization
1144 %fneg = fneg half %a
1145 %cmp = fcmp fast ueq half %a, %fneg
1149 define <2 x i1> @fneg_ugt_swap(<2 x float> %p) {
1150 ; CHECK-LABEL: @fneg_ugt_swap(
1151 ; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1152 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], zeroinitializer
1153 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1155 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1156 %fneg = fneg fast <2 x float> %a
1157 %cmp = fcmp ugt <2 x float> %a, %fneg
1161 define i1 @fneg_uge_swap(float %p, ptr %q) {
1162 ; CHECK-LABEL: @fneg_uge_swap(
1163 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1164 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]]
1165 ; CHECK-NEXT: store float [[FNEG]], ptr [[Q:%.*]], align 4
1166 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+00
1167 ; CHECK-NEXT: ret i1 [[CMP]]
1169 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1170 %fneg = fneg float %a
1171 store float %fneg, ptr %q
1172 %cmp = fcmp uge float %a, %fneg
1176 define i1 @fneg_ult_swap(float %p) {
1177 ; CHECK-LABEL: @fneg_ult_swap(
1178 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1179 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ult float [[A]], 0.000000e+00
1180 ; CHECK-NEXT: ret i1 [[CMP]]
1182 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1183 %fneg = fneg float %a
1184 %cmp = fcmp nsz ult float %a, %fneg
1188 define i1 @fneg_ule_swap(float %p) {
1189 ; CHECK-LABEL: @fneg_ule_swap(
1190 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1191 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ule float [[A]], 0.000000e+00
1192 ; CHECK-NEXT: ret i1 [[CMP]]
1194 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1195 %fneg = fneg float %a
1196 %cmp = fcmp nnan ule float %a, %fneg
1200 define i1 @fneg_une_swap(float %p) {
1201 ; CHECK-LABEL: @fneg_une_swap(
1202 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1203 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A]], 0.000000e+00
1204 ; CHECK-NEXT: ret i1 [[CMP]]
1206 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1207 %fneg = fneg float %a
1208 %cmp = fcmp ninf une float %a, %fneg
1212 define i1 @bitcast_eq0(i32 %x) {
1213 ; CHECK-LABEL: @bitcast_eq0(
1214 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 2147483647
1215 ; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 0
1216 ; CHECK-NEXT: ret i1 [[R]]
1218 %f = bitcast i32 %x to float
1219 %r = fcmp oeq float %f, 0.0
1223 define <2 x i1> @bitcast_ne0(<2 x i32> %x) {
1224 ; CHECK-LABEL: @bitcast_ne0(
1225 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 2147483647)
1226 ; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
1227 ; CHECK-NEXT: ret <2 x i1> [[R]]
1229 %f = bitcast <2 x i32> %x to <2 x float>
1230 %r = fcmp une <2 x float> %f, <float 0.0, float 0.0>
1234 ; negative test - extra use
1236 define i1 @bitcast_eq0_use(i32 %x) {
1237 ; CHECK-LABEL: @bitcast_eq0_use(
1238 ; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to float
1239 ; CHECK-NEXT: call void @use(float [[F]])
1240 ; CHECK-NEXT: [[R:%.*]] = fcmp oeq float [[F]], 0.000000e+00
1241 ; CHECK-NEXT: ret i1 [[R]]
1243 %f = bitcast i32 %x to float
1244 call void @use(float %f)
1245 %r = fcmp oeq float %f, 0.0
1249 ; negative test - this could be transformed, but requires a new bitcast
1251 define i1 @bitcast_nonint_eq0(<2 x i16> %x) {
1252 ; CHECK-LABEL: @bitcast_nonint_eq0(
1253 ; CHECK-NEXT: [[F:%.*]] = bitcast <2 x i16> [[X:%.*]] to float
1254 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00
1255 ; CHECK-NEXT: ret i1 [[R]]
1257 %f = bitcast <2 x i16> %x to float
1258 %r = fcmp ogt float %f, 0.0
1262 ; negative test - wrong predicate
1264 define i1 @bitcast_gt0(i32 %x) {
1265 ; CHECK-LABEL: @bitcast_gt0(
1266 ; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to float
1267 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00
1268 ; CHECK-NEXT: ret i1 [[R]]
1270 %f = bitcast i32 %x to float
1271 %r = fcmp ogt float %f, 0.0
1275 ; negative test - this could be transformed, but requires a new bitcast
1277 define <1 x i1> @bitcast_1vec_eq0(i32 %x) {
1278 ; CHECK-LABEL: @bitcast_1vec_eq0(
1279 ; CHECK-NEXT: [[F:%.*]] = bitcast i32 [[X:%.*]] to <1 x float>
1280 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <1 x float> [[F]], zeroinitializer
1281 ; CHECK-NEXT: ret <1 x i1> [[CMP]]
1283 %f = bitcast i32 %x to <1 x float>
1284 %cmp = fcmp oeq <1 x float> %f, zeroinitializer
1288 ; Simplify fcmp (x + 0.0), y => fcmp x, y
1290 define i1 @fcmp_fadd_zero_ugt(float %x, float %y) {
1291 ; CHECK-LABEL: @fcmp_fadd_zero_ugt(
1292 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1293 ; CHECK-NEXT: ret i1 [[CMP]]
1295 %add = fadd float %x, 0.000000e+00
1296 %cmp = fcmp ugt float %add, %y
1300 define i1 @fcmp_fadd_zero_uge(float %x, float %y) {
1301 ; CHECK-LABEL: @fcmp_fadd_zero_uge(
1302 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
1303 ; CHECK-NEXT: ret i1 [[CMP]]
1305 %add = fadd float %x, 0.000000e+00
1306 %cmp = fcmp uge float %add, %y
1310 define i1 @fcmp_fadd_zero_ogt(float %x, float %y) {
1311 ; CHECK-LABEL: @fcmp_fadd_zero_ogt(
1312 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
1313 ; CHECK-NEXT: ret i1 [[CMP]]
1315 %add = fadd float %x, 0.000000e+00
1316 %cmp = fcmp ogt float %add, %y
1320 define i1 @fcmp_fadd_zero_oge(float %x, float %y) {
1321 ; CHECK-LABEL: @fcmp_fadd_zero_oge(
1322 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], [[Y:%.*]]
1323 ; CHECK-NEXT: ret i1 [[CMP]]
1325 %add = fadd float %x, 0.000000e+00
1326 %cmp = fcmp oge float %add, %y
1330 define i1 @fcmp_fadd_zero_ult(float %x, float %y) {
1331 ; CHECK-LABEL: @fcmp_fadd_zero_ult(
1332 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]]
1333 ; CHECK-NEXT: ret i1 [[CMP]]
1335 %add = fadd float %x, 0.000000e+00
1336 %cmp = fcmp ult float %add, %y
1340 define i1 @fcmp_fadd_zero_ule(float %x, float %y) {
1341 ; CHECK-LABEL: @fcmp_fadd_zero_ule(
1342 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
1343 ; CHECK-NEXT: ret i1 [[CMP]]
1345 %add = fadd float %x, 0.000000e+00
1346 %cmp = fcmp ule float %add, %y
1350 define i1 @fcmp_fadd_zero_olt(float %x, float %y) {
1351 ; CHECK-LABEL: @fcmp_fadd_zero_olt(
1352 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
1353 ; CHECK-NEXT: ret i1 [[CMP]]
1355 %add = fadd float %x, 0.000000e+00
1356 %cmp = fcmp olt float %add, %y
1360 define i1 @fcmp_fadd_zero_ole(float %x, float %y) {
1361 ; CHECK-LABEL: @fcmp_fadd_zero_ole(
1362 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]]
1363 ; CHECK-NEXT: ret i1 [[CMP]]
1365 %add = fadd float %x, 0.000000e+00
1366 %cmp = fcmp ole float %add, %y
1370 define i1 @fcmp_fadd_zero_oeq(float %x, float %y) {
1371 ; CHECK-LABEL: @fcmp_fadd_zero_oeq(
1372 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]]
1373 ; CHECK-NEXT: ret i1 [[CMP]]
1375 %add = fadd float %x, 0.000000e+00
1376 %cmp = fcmp oeq float %add, %y
1380 define i1 @fcmp_fadd_zero_one(float %x, float %y) {
1381 ; CHECK-LABEL: @fcmp_fadd_zero_one(
1382 ; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[X:%.*]], [[Y:%.*]]
1383 ; CHECK-NEXT: ret i1 [[CMP]]
1385 %add = fadd float %x, 0.000000e+00
1386 %cmp = fcmp one float %add, %y
1390 define i1 @fcmp_fadd_zero_ueq(float %x, float %y) {
1391 ; CHECK-LABEL: @fcmp_fadd_zero_ueq(
1392 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
1393 ; CHECK-NEXT: ret i1 [[CMP]]
1395 %add = fadd float %x, 0.000000e+00
1396 %cmp = fcmp ueq float %add, %y
1400 define i1 @fcmp_fadd_zero_une(float %x, float %y) {
1401 ; CHECK-LABEL: @fcmp_fadd_zero_une(
1402 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
1403 ; CHECK-NEXT: ret i1 [[CMP]]
1405 %add = fadd float %x, 0.000000e+00
1406 %cmp = fcmp une float %add, %y
1410 define i1 @fcmp_fadd_zero_ord(float %x, float %y) {
1411 ; CHECK-LABEL: @fcmp_fadd_zero_ord(
1412 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
1413 ; CHECK-NEXT: ret i1 [[CMP]]
1415 %add = fadd float %x, 0.000000e+00
1416 %cmp = fcmp ord float %add, %y
1420 define i1 @fcmp_fadd_zero_uno(float %x, float %y) {
1421 ; CHECK-LABEL: @fcmp_fadd_zero_uno(
1422 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
1423 ; CHECK-NEXT: ret i1 [[CMP]]
1425 %add = fadd float %x, 0.000000e+00
1426 %cmp = fcmp uno float %add, %y
1430 define i1 @fcmp_fadd_neg_zero(float %x, float %y) {
1431 ; CHECK-LABEL: @fcmp_fadd_neg_zero(
1432 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1433 ; CHECK-NEXT: ret i1 [[CMP]]
1435 %add = fadd float %x, -0.000000e+00
1436 %cmp = fcmp ugt float %add, %y
1440 define i1 @fcmp_fadd_zero_switched(float %x, float %y) {
1441 ; CHECK-LABEL: @fcmp_fadd_zero_switched(
1442 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1443 ; CHECK-NEXT: ret i1 [[CMP]]
1445 %add = fadd float %y, 0.000000e+00
1446 %cmp = fcmp ugt float %x, %add
1450 define <2 x i1> @fcmp_fadd_zero_vec(<2 x float> %x, <2 x float> %y) {
1451 ; CHECK-LABEL: @fcmp_fadd_zero_vec(
1452 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt <2 x float> [[X:%.*]], [[Y:%.*]]
1453 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1455 %add = fadd <2 x float> %x, <float 0.0, float -0.0>
1456 %cmp = fcmp ugt <2 x float> %add, %y
1460 define i1 @fcmp_fast_fadd_fast_zero(float %x, float %y) {
1461 ; CHECK-LABEL: @fcmp_fast_fadd_fast_zero(
1462 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]]
1463 ; CHECK-NEXT: ret i1 [[CMP]]
1465 %add = fadd fast float %x, 0.000000e+00
1466 %cmp = fcmp fast ugt float %add, %y
1470 define i1 @fcmp_fast_fadd_zero(float %x, float %y) {
1471 ; CHECK-LABEL: @fcmp_fast_fadd_zero(
1472 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]]
1473 ; CHECK-NEXT: ret i1 [[CMP]]
1475 %add = fadd float %x, 0.000000e+00
1476 %cmp = fcmp fast ugt float %add, %y
1480 define i1 @fcmp_fadd_fast_zero(float %x, float %y) {
1481 ; CHECK-LABEL: @fcmp_fadd_fast_zero(
1482 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1483 ; CHECK-NEXT: ret i1 [[CMP]]
1485 %add = fadd fast float %x, 0.000000e+00
1486 %cmp = fcmp ugt float %add, %y
1490 define i1 @fcmp_ueq_sel_x_negx(float %x) {
1491 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx(
1492 ; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1493 ; CHECK-NEXT: ret i1 [[RES]]
1495 %f = fcmp ueq float %x, 0.000000e+00
1496 %neg = fneg float %x
1497 %sel = select i1 %f, float %x, float %neg
1498 %res = fcmp ueq float %sel, 0.000000e+00
1502 define i1 @fcmp_une_sel_x_negx(float %x) {
1503 ; CHECK-LABEL: @fcmp_une_sel_x_negx(
1504 ; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1505 ; CHECK-NEXT: ret i1 [[RES]]
1507 %f = fcmp une float %x, 0.000000e+00
1508 %neg = fneg float %x
1509 %sel = select i1 %f, float %x, float %neg
1510 %res = fcmp une float %sel, 0.000000e+00
1514 define i1 @fcmp_oeq_sel_x_negx(float %x) {
1515 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx(
1516 ; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1517 ; CHECK-NEXT: ret i1 [[RES]]
1519 %f = fcmp oeq float %x, 0.000000e+00
1520 %neg = fneg float %x
1521 %sel = select i1 %f, float %x, float %neg
1522 %res = fcmp oeq float %sel, 0.000000e+00
1526 define i1 @fcmp_one_sel_x_negx(float %x) {
1527 ; CHECK-LABEL: @fcmp_one_sel_x_negx(
1528 ; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1529 ; CHECK-NEXT: ret i1 [[RES]]
1531 %f = fcmp one float %x, 0.000000e+00
1532 %neg = fneg float %x
1533 %sel = select i1 %f, float %x, float %neg
1534 %res = fcmp one float %sel, 0.000000e+00
1538 define i1 @fcmp_ueq_sel_x_negx_nzero(float %x) {
1539 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero(
1540 ; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1541 ; CHECK-NEXT: ret i1 [[RES]]
1543 %f = fcmp ueq float %x, 0.000000e+00
1544 %neg = fneg float %x
1545 %sel = select i1 %f, float %x, float %neg
1546 %res = fcmp ueq float %sel, -0.000000e+00
1550 define i1 @fcmp_une_sel_x_negx_nzero(float %x) {
1551 ; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero(
1552 ; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1553 ; CHECK-NEXT: ret i1 [[RES]]
1555 %f = fcmp une float %x, 0.000000e+00
1556 %neg = fneg float %x
1557 %sel = select i1 %f, float %x, float %neg
1558 %res = fcmp une float %sel, -0.000000e+00
1562 define i1 @fcmp_oeq_sel_x_negx_nzero(float %x) {
1563 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero(
1564 ; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1565 ; CHECK-NEXT: ret i1 [[RES]]
1567 %f = fcmp oeq float %x, 0.000000e+00
1568 %neg = fneg float %x
1569 %sel = select i1 %f, float %x, float %neg
1570 %res = fcmp oeq float %sel, -0.000000e+00
1574 define i1 @fcmp_one_sel_x_negx_nzero(float %x) {
1575 ; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero(
1576 ; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1577 ; CHECK-NEXT: ret i1 [[RES]]
1579 %f = fcmp one float %x, 0.000000e+00
1580 %neg = fneg float %x
1581 %sel = select i1 %f, float %x, float %neg
1582 %res = fcmp one float %sel, -0.000000e+00
1586 define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) {
1587 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec(
1588 ; CHECK-NEXT: [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer
1589 ; CHECK-NEXT: ret <8 x i1> [[RES]]
1591 %f = fcmp ueq <8 x float> %x, zeroinitializer
1592 %neg = fneg <8 x float> %x
1593 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1594 %res = fcmp ueq <8 x float> %sel, zeroinitializer
1598 define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) {
1599 ; CHECK-LABEL: @fcmp_une_sel_x_negx_vec(
1600 ; CHECK-NEXT: [[RES:%.*]] = fcmp une <8 x float> [[X:%.*]], zeroinitializer
1601 ; CHECK-NEXT: ret <8 x i1> [[RES]]
1603 %f = fcmp une <8 x float> %x, zeroinitializer
1604 %neg = fneg <8 x float> %x
1605 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1606 %res = fcmp une <8 x float> %sel, zeroinitializer
1610 define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) {
1611 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_vec(
1612 ; CHECK-NEXT: [[RES:%.*]] = fcmp oeq <8 x float> [[X:%.*]], zeroinitializer
1613 ; CHECK-NEXT: ret <8 x i1> [[RES]]
1615 %f = fcmp oeq <8 x float> %x, zeroinitializer
1616 %neg = fneg <8 x float> %x
1617 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1618 %res = fcmp oeq <8 x float> %sel, zeroinitializer
1622 define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
1623 ; CHECK-LABEL: @fcmp_one_sel_x_negx_vec(
1624 ; CHECK-NEXT: [[RES:%.*]] = fcmp one <8 x float> [[X:%.*]], zeroinitializer
1625 ; CHECK-NEXT: ret <8 x i1> [[RES]]
1627 %f = fcmp one <8 x float> %x, zeroinitializer
1628 %neg = fneg <8 x float> %x
1629 %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1630 %res = fcmp one <8 x float> %sel, zeroinitializer
1634 define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1635 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(
1636 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf oeq <2 x float> [[X:%.*]], zeroinitializer
1637 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1639 %fneg = fneg <2 x float> %x
1640 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1641 %icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0>
1645 define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1646 ; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(
1647 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf one <2 x float> [[X:%.*]], zeroinitializer
1648 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1650 %fneg = fneg <2 x float> %x
1651 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1652 %icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0>
1656 define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1657 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(
1658 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf ueq <2 x float> [[X:%.*]], zeroinitializer
1659 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1661 %fneg = fneg <2 x float> %x
1662 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1663 %icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0>
1667 define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1668 ; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(
1669 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf une <2 x float> [[X:%.*]], zeroinitializer
1670 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1672 %fneg = fneg <2 x float> %x
1673 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1674 %icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0>
1678 define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1679 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(
1680 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan oeq <2 x float> [[X:%.*]], zeroinitializer
1681 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1683 %fneg = fneg <2 x float> %x
1684 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1685 %icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0>
1689 define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1690 ; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(
1691 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan one <2 x float> [[X:%.*]], zeroinitializer
1692 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1694 %fneg = fneg <2 x float> %x
1695 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1696 %icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0>
1700 define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1701 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(
1702 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan ueq <2 x float> [[X:%.*]], zeroinitializer
1703 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1705 %fneg = fneg <2 x float> %x
1706 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1707 %icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0>
1711 define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1712 ; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(
1713 ; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan une <2 x float> [[X:%.*]], zeroinitializer
1714 ; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1716 %fneg = fneg <2 x float> %x
1717 %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1718 %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>
1722 ; negative test - extra use
1724 define i1 @fcmp_ueq_fsub_nnan_const_extra_use(float %x, float %y) {
1725 ; CHECK-LABEL: @fcmp_ueq_fsub_nnan_const_extra_use(
1726 ; CHECK-NEXT: [[FS:%.*]] = fsub nnan float [[X:%.*]], [[Y:%.*]]
1727 ; CHECK-NEXT: call void @use(float [[FS]])
1728 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq float [[FS]], 0.000000e+00
1729 ; CHECK-NEXT: ret i1 [[CMP]]
1731 %fs = fsub nnan float %x, %y
1732 call void @use(float %fs)
1733 %cmp = fcmp nnan ueq float %fs, 0.000000e+00
1737 ; negative test - extra use
1739 define i1 @fcmp_oeq_fsub_ninf_const_extra_use(float %x, float %y) {
1740 ; CHECK-LABEL: @fcmp_oeq_fsub_ninf_const_extra_use(
1741 ; CHECK-NEXT: [[FS:%.*]] = fsub ninf float [[X:%.*]], [[Y:%.*]]
1742 ; CHECK-NEXT: call void @use(float [[FS]])
1743 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq float [[FS]], 0.000000e+00
1744 ; CHECK-NEXT: ret i1 [[CMP]]
1746 %fs = fsub ninf float %x, %y
1747 call void @use(float %fs)
1748 %cmp = fcmp ninf oeq float %fs, 0.000000e+00
1752 define i1 @fcmp_oeq_fsub_const(float %x, float %y) {
1753 ; CHECK-LABEL: @fcmp_oeq_fsub_const(
1754 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1755 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[FS]], 0.000000e+00
1756 ; CHECK-NEXT: ret i1 [[CMP]]
1758 %fs = fsub float %x, %y
1759 %cmp = fcmp oeq float %fs, 0.000000e+00
1763 define i1 @fcmp_oge_fsub_const(float %x, float %y) {
1764 ; CHECK-LABEL: @fcmp_oge_fsub_const(
1765 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1766 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[FS]], 0.000000e+00
1767 ; CHECK-NEXT: ret i1 [[CMP]]
1769 %fs = fsub float %x, %y
1770 %cmp = fcmp oge float %fs, 0.000000e+00
1774 define i1 @fcmp_ole_fsub_const(float %x, float %y) {
1775 ; CHECK-LABEL: @fcmp_ole_fsub_const(
1776 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1777 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[FS]], 0.000000e+00
1778 ; CHECK-NEXT: ret i1 [[CMP]]
1780 %fs = fsub float %x, %y
1781 %cmp = fcmp ole float %fs, 0.000000e+00
1785 define i1 @fcmp_ueq_fsub_const(float %x, float %y) {
1786 ; CHECK-LABEL: @fcmp_ueq_fsub_const(
1787 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
1788 ; CHECK-NEXT: ret i1 [[CMP]]
1790 %fs = fsub float %x, %y
1791 %cmp = fcmp ueq float %fs, 0.000000e+00
1795 define i1 @fcmp_uge_fsub_const(float %x, float %y) {
1796 ; CHECK-LABEL: @fcmp_uge_fsub_const(
1797 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
1798 ; CHECK-NEXT: ret i1 [[CMP]]
1800 %fs = fsub float %x, %y
1801 %cmp = fcmp uge float %fs, 0.000000e+00
1805 define i1 @fcmp_ule_fsub_const(float %x, float %y) {
1806 ; CHECK-LABEL: @fcmp_ule_fsub_const(
1807 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
1808 ; CHECK-NEXT: ret i1 [[CMP]]
1810 %fs = fsub float %x, %y
1811 %cmp = fcmp ule float %fs, 0.000000e+00
1815 define i1 @fcmp_ugt_fsub_const(float %x, float %y) {
1816 ; CHECK-LABEL: @fcmp_ugt_fsub_const(
1817 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1818 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[FS]], 0.000000e+00
1819 ; CHECK-NEXT: ret i1 [[CMP]]
1821 %fs = fsub float %x, %y
1822 %cmp = fcmp ugt float %fs, 0.000000e+00
1826 define i1 @fcmp_ult_fsub_const(float %x, float %y) {
1827 ; CHECK-LABEL: @fcmp_ult_fsub_const(
1828 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1829 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[FS]], 0.000000e+00
1830 ; CHECK-NEXT: ret i1 [[CMP]]
1832 %fs = fsub float %x, %y
1833 %cmp = fcmp ult float %fs, 0.000000e+00
1837 define i1 @fcmp_une_fsub_const(float %x, float %y) {
1838 ; CHECK-LABEL: @fcmp_une_fsub_const(
1839 ; CHECK-NEXT: [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1840 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[FS]], 0.000000e+00
1841 ; CHECK-NEXT: ret i1 [[CMP]]
1843 %fs = fsub float %x, %y
1844 %cmp = fcmp une float %fs, 0.000000e+00
1848 define <8 x i1> @fcmp_uge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1849 ; CHECK-LABEL: @fcmp_uge_fsub_const_ninf_vec(
1850 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf uge <8 x float> [[X:%.*]], [[Y:%.*]]
1851 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1853 %fs = fsub ninf <8 x float> %x, %y
1854 %cmp = fcmp ninf uge <8 x float> %fs, zeroinitializer
1858 define <8 x i1> @fcmp_ule_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1859 ; CHECK-LABEL: @fcmp_ule_fsub_const_ninf_vec(
1860 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ule <8 x float> [[X:%.*]], [[Y:%.*]]
1861 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1863 %fs = fsub ninf <8 x float> %x, %y
1864 %cmp = fcmp ninf ule <8 x float> %fs, zeroinitializer
1868 define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1869 ; CHECK-LABEL: @fcmp_ueq_fsub_const_ninf_vec(
1870 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ueq <8 x float> [[X:%.*]], [[Y:%.*]]
1871 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1873 %fs = fsub ninf <8 x float> %x, %y
1874 %cmp = fcmp ninf ueq <8 x float> %fs, zeroinitializer
1878 define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1879 ; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec(
1880 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oge <8 x float> [[X:%.*]], [[Y:%.*]]
1881 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1883 %fs = fsub ninf <8 x float> %x, %y
1884 %cmp = fcmp ninf oge <8 x float> %fs, zeroinitializer
1888 define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1889 ; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec(
1890 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ole <8 x float> [[X:%.*]], [[Y:%.*]]
1891 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1893 %fs = fsub ninf <8 x float> %x, %y
1894 %cmp = fcmp ninf ole <8 x float> %fs, zeroinitializer
1898 define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1899 ; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec(
1900 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[X:%.*]], [[Y:%.*]]
1901 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1903 %fs = fsub ninf <8 x float> %x, %y
1904 %cmp = fcmp ninf oeq <8 x float> %fs, zeroinitializer
1908 define <8 x i1> @fcmp_ogt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1909 ; CHECK-LABEL: @fcmp_ogt_fsub_const_ninf_vec(
1910 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <8 x float> [[X:%.*]], [[Y:%.*]]
1911 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1913 %fs = fsub ninf <8 x float> %x, %y
1914 %cmp = fcmp ninf ogt <8 x float> %fs, zeroinitializer
1918 define <8 x i1> @fcmp_olt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1919 ; CHECK-LABEL: @fcmp_olt_fsub_const_ninf_vec(
1920 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <8 x float> [[X:%.*]], [[Y:%.*]]
1921 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1923 %fs = fsub ninf <8 x float> %x, %y
1924 %cmp = fcmp ninf olt <8 x float> %fs, zeroinitializer
1928 define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1929 ; CHECK-LABEL: @fcmp_one_fsub_const_ninf_vec(
1930 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf one <8 x float> [[X:%.*]], [[Y:%.*]]
1931 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1933 %fs = fsub ninf <8 x float> %x, %y
1934 %cmp = fcmp ninf one <8 x float> %fs, zeroinitializer
1938 define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1939 ; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec(
1940 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[X:%.*]], [[Y:%.*]]
1941 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1943 %fs = fsub ninf <8 x float> %x, %y
1944 %cmp = fcmp ninf ugt <8 x float> %fs, zeroinitializer
1948 define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1949 ; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec(
1950 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ult <8 x float> [[X:%.*]], [[Y:%.*]]
1951 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1953 %fs = fsub ninf <8 x float> %x, %y
1954 %cmp = fcmp ninf ult <8 x float> %fs, zeroinitializer
1958 define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1959 ; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec(
1960 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une <8 x float> [[X:%.*]], [[Y:%.*]]
1961 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1963 %fs = fsub ninf <8 x float> %x, %y
1964 %cmp = fcmp ninf une <8 x float> %fs, zeroinitializer
1968 define <8 x i1> @fcmp_uge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1969 ; CHECK-LABEL: @fcmp_uge_fsub_const_nnan_vec(
1970 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan uge <8 x float> [[X:%.*]], [[Y:%.*]]
1971 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1973 %fs = fsub nnan <8 x float> %x, %y
1974 %cmp = fcmp nnan uge <8 x float> %fs, zeroinitializer
1978 define <8 x i1> @fcmp_ule_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1979 ; CHECK-LABEL: @fcmp_ule_fsub_const_nnan_vec(
1980 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ule <8 x float> [[X:%.*]], [[Y:%.*]]
1981 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1983 %fs = fsub nnan <8 x float> %x, %y
1984 %cmp = fcmp nnan ule <8 x float> %fs, zeroinitializer
1988 define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1989 ; CHECK-LABEL: @fcmp_ueq_fsub_const_nnan_vec(
1990 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq <8 x float> [[X:%.*]], [[Y:%.*]]
1991 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
1993 %fs = fsub nnan <8 x float> %x, %y
1994 %cmp = fcmp nnan ueq <8 x float> %fs, zeroinitializer
1998 define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1999 ; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec(
2000 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge <8 x float> [[X:%.*]], [[Y:%.*]]
2001 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2003 %fs = fsub nnan <8 x float> %x, %y
2004 %cmp = fcmp nnan oge <8 x float> %fs, zeroinitializer
2008 define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2009 ; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec(
2010 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ole <8 x float> [[X:%.*]], [[Y:%.*]]
2011 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2013 %fs = fsub nnan <8 x float> %x, %y
2014 %cmp = fcmp nnan ole <8 x float> %fs, zeroinitializer
2018 define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2019 ; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec(
2020 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[X:%.*]], [[Y:%.*]]
2021 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2023 %fs = fsub nnan <8 x float> %x, %y
2024 %cmp = fcmp nnan oeq <8 x float> %fs, zeroinitializer
2028 define <8 x i1> @fcmp_ogt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2029 ; CHECK-LABEL: @fcmp_ogt_fsub_const_nnan_vec(
2030 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt <8 x float> [[X:%.*]], [[Y:%.*]]
2031 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2033 %fs = fsub nnan <8 x float> %x, %y
2034 %cmp = fcmp nnan ogt <8 x float> %fs, zeroinitializer
2038 define <8 x i1> @fcmp_olt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2039 ; CHECK-LABEL: @fcmp_olt_fsub_const_nnan_vec(
2040 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan olt <8 x float> [[X:%.*]], [[Y:%.*]]
2041 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2043 %fs = fsub nnan <8 x float> %x, %y
2044 %cmp = fcmp nnan olt <8 x float> %fs, zeroinitializer
2048 define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2049 ; CHECK-LABEL: @fcmp_one_fsub_const_nnan_vec(
2050 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one <8 x float> [[X:%.*]], [[Y:%.*]]
2051 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2053 %fs = fsub nnan <8 x float> %x, %y
2054 %cmp = fcmp nnan one <8 x float> %fs, zeroinitializer
2058 define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2059 ; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec(
2060 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[X:%.*]], [[Y:%.*]]
2061 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2063 %fs = fsub nnan <8 x float> %x, %y
2064 %cmp = fcmp nnan ugt <8 x float> %fs, zeroinitializer
2068 define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2069 ; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec(
2070 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ult <8 x float> [[X:%.*]], [[Y:%.*]]
2071 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2073 %fs = fsub nnan <8 x float> %x, %y
2074 %cmp = fcmp nnan ult <8 x float> %fs, zeroinitializer
2078 define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2079 ; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec(
2080 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan une <8 x float> [[X:%.*]], [[Y:%.*]]
2081 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2083 %fs = fsub nnan <8 x float> %x, %y
2084 %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer
2088 define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero,positive-zero" {
2089 ; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero(
2090 ; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2091 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2092 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2094 %fs = fsub <8 x float> %x, %y
2095 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2099 define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="dynamic,dynamic" {
2100 ; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_dynamic(
2101 ; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2102 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2103 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2105 %fs = fsub <8 x float> %x, %y
2106 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2110 define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign,preserve-sign" {
2111 ; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(
2112 ; CHECK-NEXT: [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2113 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2114 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
2116 %fs = fsub <8 x float> %x, %y
2117 %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2121 define i1 @fcmp_sqrt_zero_olt(half %x) {
2122 ; CHECK-LABEL: @fcmp_sqrt_zero_olt(
2123 ; CHECK-NEXT: ret i1 false
2125 %sqrt = call half @llvm.sqrt.f16(half %x)
2126 %cmp = fcmp olt half %sqrt, 0.0
2130 define i1 @fcmp_sqrt_zero_ult(half %x) {
2131 ; CHECK-LABEL: @fcmp_sqrt_zero_ult(
2132 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2133 ; CHECK-NEXT: ret i1 [[CMP]]
2135 %sqrt = call half @llvm.sqrt.f16(half %x)
2136 %cmp = fcmp ult half %sqrt, 0.0
2140 define i1 @fcmp_sqrt_zero_ult_fmf(half %x) {
2141 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf(
2142 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ult half [[X:%.*]], 0xH0000
2143 ; CHECK-NEXT: ret i1 [[CMP]]
2145 %sqrt = call half @llvm.sqrt.f16(half %x)
2146 %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2150 define i1 @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(half %x) {
2151 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(
2152 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf nsz ult half [[X:%.*]], 0xH0000
2153 ; CHECK-NEXT: ret i1 [[CMP]]
2155 %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2156 %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2160 define i1 @fcmp_sqrt_zero_ult_nzero(half %x) {
2161 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_nzero(
2162 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2163 ; CHECK-NEXT: ret i1 [[CMP]]
2165 %sqrt = call half @llvm.sqrt.f16(half %x)
2166 %cmp = fcmp ult half %sqrt, -0.0
2170 define <2 x i1> @fcmp_sqrt_zero_ult_vec(<2 x half> %x) {
2171 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec(
2172 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer
2173 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2175 %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)
2176 %cmp = fcmp ult <2 x half> %sqrt, zeroinitializer
2180 define <2 x i1> @fcmp_sqrt_zero_ult_vec_mixed_zero(<2 x half> %x) {
2181 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec_mixed_zero(
2182 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer
2183 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2185 %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)
2186 %cmp = fcmp ult <2 x half> %sqrt, <half 0.0, half -0.0>
2190 define i1 @fcmp_sqrt_zero_ole(half %x) {
2191 ; CHECK-LABEL: @fcmp_sqrt_zero_ole(
2192 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
2193 ; CHECK-NEXT: ret i1 [[CMP]]
2195 %sqrt = call half @llvm.sqrt.f16(half %x)
2196 %cmp = fcmp ole half %sqrt, 0.0
2200 define i1 @fcmp_sqrt_zero_ule(half %x) {
2201 ; CHECK-LABEL: @fcmp_sqrt_zero_ule(
2202 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000
2203 ; CHECK-NEXT: ret i1 [[CMP]]
2205 %sqrt = call half @llvm.sqrt.f16(half %x)
2206 %cmp = fcmp ule half %sqrt, 0.0
2210 define i1 @fcmp_sqrt_zero_ogt(half %x) {
2211 ; CHECK-LABEL: @fcmp_sqrt_zero_ogt(
2212 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
2213 ; CHECK-NEXT: ret i1 [[CMP]]
2215 %sqrt = call half @llvm.sqrt.f16(half %x)
2216 %cmp = fcmp ogt half %sqrt, 0.0
2220 define i1 @fcmp_sqrt_zero_ugt(half %x) {
2221 ; CHECK-LABEL: @fcmp_sqrt_zero_ugt(
2222 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000
2223 ; CHECK-NEXT: ret i1 [[CMP]]
2225 %sqrt = call half @llvm.sqrt.f16(half %x)
2226 %cmp = fcmp ugt half %sqrt, 0.0
2230 define i1 @fcmp_sqrt_zero_oge(half %x) {
2231 ; CHECK-LABEL: @fcmp_sqrt_zero_oge(
2232 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
2233 ; CHECK-NEXT: ret i1 [[CMP]]
2235 %sqrt = call half @llvm.sqrt.f16(half %x)
2236 %cmp = fcmp oge half %sqrt, 0.0
2240 define i1 @fcmp_sqrt_zero_uge(half %x) {
2241 ; CHECK-LABEL: @fcmp_sqrt_zero_uge(
2242 ; CHECK-NEXT: ret i1 true
2244 %sqrt = call half @llvm.sqrt.f16(half %x)
2245 %cmp = fcmp uge half %sqrt, 0.0
2249 define i1 @fcmp_sqrt_zero_oeq(half %x) {
2250 ; CHECK-LABEL: @fcmp_sqrt_zero_oeq(
2251 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
2252 ; CHECK-NEXT: ret i1 [[CMP]]
2254 %sqrt = call half @llvm.sqrt.f16(half %x)
2255 %cmp = fcmp oeq half %sqrt, 0.0
2259 define i1 @fcmp_sqrt_zero_ueq(half %x) {
2260 ; CHECK-LABEL: @fcmp_sqrt_zero_ueq(
2261 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000
2262 ; CHECK-NEXT: ret i1 [[CMP]]
2264 %sqrt = call half @llvm.sqrt.f16(half %x)
2265 %cmp = fcmp ueq half %sqrt, 0.0
2269 define i1 @fcmp_sqrt_zero_one(half %x) {
2270 ; CHECK-LABEL: @fcmp_sqrt_zero_one(
2271 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
2272 ; CHECK-NEXT: ret i1 [[CMP]]
2274 %sqrt = call half @llvm.sqrt.f16(half %x)
2275 %cmp = fcmp one half %sqrt, 0.0
2279 define i1 @fcmp_sqrt_zero_une(half %x) {
2280 ; CHECK-LABEL: @fcmp_sqrt_zero_une(
2281 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000
2282 ; CHECK-NEXT: ret i1 [[CMP]]
2284 %sqrt = call half @llvm.sqrt.f16(half %x)
2285 %cmp = fcmp une half %sqrt, 0.0
2289 define i1 @fcmp_sqrt_zero_ord(half %x) {
2290 ; CHECK-LABEL: @fcmp_sqrt_zero_ord(
2291 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
2292 ; CHECK-NEXT: ret i1 [[CMP]]
2294 %sqrt = call half @llvm.sqrt.f16(half %x)
2295 %cmp = fcmp ord half %sqrt, 0.0
2299 define i1 @fcmp_sqrt_zero_uno(half %x) {
2300 ; CHECK-LABEL: @fcmp_sqrt_zero_uno(
2301 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2302 ; CHECK-NEXT: ret i1 [[CMP]]
2304 %sqrt = call half @llvm.sqrt.f16(half %x)
2305 %cmp = fcmp uno half %sqrt, 0.0
2309 ; Make sure that ninf is cleared.
2310 define i1 @fcmp_sqrt_zero_uno_fmf(half %x) {
2311 ; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf(
2312 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2313 ; CHECK-NEXT: ret i1 [[CMP]]
2315 %sqrt = call half @llvm.sqrt.f16(half %x)
2316 %cmp = fcmp ninf uno half %sqrt, 0.0
2320 define i1 @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(half %x) {
2321 ; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(
2322 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ult half [[X:%.*]], 0xH0000
2323 ; CHECK-NEXT: ret i1 [[CMP]]
2325 %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2326 %cmp = fcmp ninf uno half %sqrt, 0.0
2332 define i1 @fcmp_sqrt_zero_ult_var(half %x, half %y) {
2333 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_var(
2334 ; CHECK-NEXT: [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])
2335 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[SQRT]], [[Y:%.*]]
2336 ; CHECK-NEXT: ret i1 [[CMP]]
2338 %sqrt = call half @llvm.sqrt.f16(half %x)
2339 %cmp = fcmp ult half %sqrt, %y
2343 define i1 @fcmp_sqrt_zero_ult_nonzero(half %x) {
2344 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_nonzero(
2345 ; CHECK-NEXT: [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])
2346 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[SQRT]], 0xH3C00
2347 ; CHECK-NEXT: ret i1 [[CMP]]
2349 %sqrt = call half @llvm.sqrt.f16(half %x)
2350 %cmp = fcmp ult half %sqrt, 1.000000e+00