1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
5 define float @fneg_fneg_var(float %a) {
6 ; CHECK-LABEL: @fneg_fneg_var(
7 ; CHECK-NEXT: ret float [[A:%.*]]
14 ; fneg (fsub -0.0, X) ==> X
15 define float @fsub_-0_x(float %a) {
16 ; CHECK-LABEL: @fsub_-0_x(
17 ; CHECK-NEXT: ret float [[A:%.*]]
19 %t1 = fsub float -0.0, %a
24 define <2 x float> @fsub_-0_x_vec(<2 x float> %a) {
25 ; CHECK-LABEL: @fsub_-0_x_vec(
26 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
28 %t1 = fsub <2 x float> <float -0.0, float -0.0>, %a
29 %ret = fneg <2 x float> %t1
33 define <2 x float> @fsub_-0_x_vec_undef_elts(<2 x float> %a) {
34 ; CHECK-LABEL: @fsub_-0_x_vec_undef_elts(
35 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
37 %t1 = fsub <2 x float> <float -0.0, float undef>, %a
38 %ret = fneg <2 x float> %t1
42 define <2 x float> @fsub_negzero_vec_undef_elts(<2 x float> %x) {
43 ; CHECK-LABEL: @fsub_negzero_vec_undef_elts(
44 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
46 %r = fsub nsz <2 x float> %x, <float undef, float -0.0>
50 ; fsub -0.0, (fsub -0.0, X) ==> X
51 define float @fsub_-0_-0_x(float %a) {
52 ; CHECK-LABEL: @fsub_-0_-0_x(
53 ; CHECK-NEXT: ret float [[A:%.*]]
55 %t1 = fsub float -0.0, %a
56 %ret = fsub float -0.0, %t1
60 ; fsub -0.0, (fneg X) ==> X
61 define float @fneg_x(float %a) {
62 ; CHECK-LABEL: @fneg_x(
63 ; CHECK-NEXT: ret float [[A:%.*]]
66 %ret = fsub float -0.0, %t1
70 define <2 x float> @fsub_-0_-0_x_vec(<2 x float> %a) {
71 ; CHECK-LABEL: @fsub_-0_-0_x_vec(
72 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
74 %t1 = fsub <2 x float> <float -0.0, float -0.0>, %a
75 %ret = fsub <2 x float> <float -0.0, float -0.0>, %t1
79 define <2 x float> @fneg_x_vec(<2 x float> %a) {
80 ; CHECK-LABEL: @fneg_x_vec(
81 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
83 %t1 = fneg <2 x float> %a
84 %ret = fsub <2 x float> <float -0.0, float -0.0>, %t1
88 define <2 x float> @fsub_-0_-0_x_vec_undef_elts(<2 x float> %a) {
89 ; CHECK-LABEL: @fsub_-0_-0_x_vec_undef_elts(
90 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
92 %t1 = fsub <2 x float> <float undef, float -0.0>, %a
93 %ret = fsub <2 x float> <float -0.0, float undef>, %t1
97 define <2 x float> @fneg_x_vec_undef_elts(<2 x float> %a) {
98 ; CHECK-LABEL: @fneg_x_vec_undef_elts(
99 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
101 %t1 = fneg <2 x float> %a
102 %ret = fsub <2 x float> <float -0.0, float undef>, %t1
106 ; fsub -0.0, (fsub 0.0, X) != X
107 define float @fsub_-0_0_x(float %a) {
108 ; CHECK-LABEL: @fsub_-0_0_x(
109 ; CHECK-NEXT: [[T1:%.*]] = fsub float 0.000000e+00, [[A:%.*]]
110 ; CHECK-NEXT: [[RET:%.*]] = fsub float -0.000000e+00, [[T1]]
111 ; CHECK-NEXT: ret float [[RET]]
113 %t1 = fsub float 0.0, %a
114 %ret = fsub float -0.0, %t1
118 ; fsub 0.0, (fsub -0.0, X) != X
119 define float @fsub_0_-0_x(float %a) {
120 ; CHECK-LABEL: @fsub_0_-0_x(
121 ; CHECK-NEXT: [[T1:%.*]] = fsub float -0.000000e+00, [[A:%.*]]
122 ; CHECK-NEXT: [[RET:%.*]] = fsub float 0.000000e+00, [[T1]]
123 ; CHECK-NEXT: ret float [[RET]]
125 %t1 = fsub float -0.0, %a
126 %ret = fsub float 0.0, %t1
131 define float @fsub_x_0(float %x) {
132 ; CHECK-LABEL: @fsub_x_0(
133 ; CHECK-NEXT: ret float [[X:%.*]]
135 %r = fsub float %x, 0.0
139 define <2 x float> @fsub_x_0_vec_undef(<2 x float> %x) {
140 ; CHECK-LABEL: @fsub_x_0_vec_undef(
141 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
143 %r = fsub <2 x float> %x, <float undef, float 0.0>
148 define float @fadd_x_n0(float %a) {
149 ; CHECK-LABEL: @fadd_x_n0(
150 ; CHECK-NEXT: ret float [[A:%.*]]
152 %ret = fadd float %a, -0.0
156 define <2 x float> @fadd_x_n0_vec_undef_elt(<2 x float> %a) {
157 ; CHECK-LABEL: @fadd_x_n0_vec_undef_elt(
158 ; CHECK-NEXT: ret <2 x float> [[A:%.*]]
160 %ret = fadd <2 x float> %a, <float -0.0, float undef>
165 define double @fmul_X_1(double %a) {
166 ; CHECK-LABEL: @fmul_X_1(
167 ; CHECK-NEXT: ret double [[A:%.*]]
169 %b = fmul double 1.0, %a
173 define half @fmul_nnan_ninf_nneg_0.0(i15 %x) {
174 ; CHECK-LABEL: @fmul_nnan_ninf_nneg_0.0(
175 ; CHECK-NEXT: ret half 0xH0000
177 %f = uitofp i15 %x to half
178 %r = fmul half %f, 0.0
182 define half @fmul_nnan_ninf_nneg_n0.0(i15 %x) {
183 ; CHECK-LABEL: @fmul_nnan_ninf_nneg_n0.0(
184 ; CHECK-NEXT: ret half 0xH8000
186 %f = uitofp i15 %x to half
187 %r = fmul half %f, -0.0
191 ; negative test - the int could be big enough to round to INF
193 define half @fmul_nnan_nneg_0.0(i16 %x) {
194 ; CHECK-LABEL: @fmul_nnan_nneg_0.0(
195 ; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[X:%.*]] to half
196 ; CHECK-NEXT: [[R:%.*]] = fmul half [[F]], 0xH0000
197 ; CHECK-NEXT: ret half [[R]]
199 %f = uitofp i16 %x to half
200 %r = fmul half %f, 0.0
204 define double @fmul_nnan_ninf_nneg_n0.0_commute(i127 %x) {
205 ; CHECK-LABEL: @fmul_nnan_ninf_nneg_n0.0_commute(
206 ; CHECK-NEXT: ret double -0.000000e+00
208 %f = uitofp i127 %x to float
209 %e = fpext float %f to double
210 %r = fmul double -0.0, %e
214 ; Make sure we can infer %x can't be 0 based on assumes.
215 define { float, float } @test_fmul_0_assumed_finite(float %x) {
216 ; CHECK-LABEL: @test_fmul_0_assumed_finite(
217 ; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
218 ; CHECK-NEXT: [[IS_FINITE_X:%.*]] = fcmp one float [[FABS_X]], 0x7FF0000000000000
219 ; CHECK-NEXT: call void @llvm.assume(i1 [[IS_FINITE_X]])
220 ; CHECK-NEXT: ret { float, float } { float 0.000000e+00, float -0.000000e+00 }
222 %fabs.x = call float @llvm.fabs.f32(float %x)
223 %is.finite.x = fcmp one float %fabs.x, 0x7FF0000000000000
224 call void @llvm.assume(i1 %is.finite.x)
225 %mul.0 = fmul float %fabs.x, 0.0
226 %mul.neg0 = fmul float %fabs.x, -0.0
227 %ins.0 = insertvalue { float, float } poison, float %mul.0, 0
228 %ins.1 = insertvalue { float, float } %ins.0, float %mul.neg0, 1
229 ret { float, float } %ins.1
232 ; negative test - the int could be big enough to round to INF
234 define double @fmul_nnan_ninf_nneg_0.0_commute(i128 %x) {
235 ; CHECK-LABEL: @fmul_nnan_ninf_nneg_0.0_commute(
236 ; CHECK-NEXT: [[F:%.*]] = uitofp i128 [[X:%.*]] to float
237 ; CHECK-NEXT: [[E:%.*]] = fpext float [[F]] to double
238 ; CHECK-NEXT: [[R:%.*]] = fmul double 0.000000e+00, [[E]]
239 ; CHECK-NEXT: ret double [[R]]
241 %f = uitofp i128 %x to float
242 %e = fpext float %f to double
243 %r = fmul double 0.0, %e
248 define <4 x float> @fmul_X_1_vec(<4 x float> %x) {
249 ; CHECK-LABEL: @fmul_X_1_vec(
250 ; CHECK-NEXT: ret <4 x float> [[X:%.*]]
252 %m = fmul <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>
257 define float @fdiv_x_1(float %a) {
258 ; CHECK-LABEL: @fdiv_x_1(
259 ; CHECK-NEXT: ret float [[A:%.*]]
261 %ret = fdiv float %a, 1.0
265 ; We can't optimize away the fadd in this test because the input
266 ; value to the function and subsequently to the fadd may be -0.0.
267 ; In that one special case, the result of the fadd should be +0.0
268 ; rather than the first parameter of the fadd.
270 ; Fragile test warning: We need 6 sqrt calls to trigger the bug
271 ; because the internal logic has a magic recursion limit of 6.
272 ; This is presented without any explanation or ability to customize.
274 declare float @sqrtf(float)
276 define float @PR22688(float %x) {
277 ; CHECK-LABEL: @PR22688(
278 ; CHECK-NEXT: [[TMP1:%.*]] = call float @sqrtf(float [[X:%.*]])
279 ; CHECK-NEXT: [[TMP2:%.*]] = call float @sqrtf(float [[TMP1]])
280 ; CHECK-NEXT: [[TMP3:%.*]] = call float @sqrtf(float [[TMP2]])
281 ; CHECK-NEXT: [[TMP4:%.*]] = call float @sqrtf(float [[TMP3]])
282 ; CHECK-NEXT: [[TMP5:%.*]] = call float @sqrtf(float [[TMP4]])
283 ; CHECK-NEXT: [[TMP6:%.*]] = call float @sqrtf(float [[TMP5]])
284 ; CHECK-NEXT: [[TMP7:%.*]] = fadd float [[TMP6]], 0.000000e+00
285 ; CHECK-NEXT: ret float [[TMP7]]
287 %1 = call float @sqrtf(float %x)
288 %2 = call float @sqrtf(float %1)
289 %3 = call float @sqrtf(float %2)
290 %4 = call float @sqrtf(float %3)
291 %5 = call float @sqrtf(float %4)
292 %6 = call float @sqrtf(float %5)
293 %7 = fadd float %6, 0.0
297 declare float @llvm.fabs.f32(float)
298 declare double @llvm.fabs.f64(double)
299 declare float @llvm.canonicalize.f32(float)
300 declare float @llvm.floor.f32(float)
301 declare float @llvm.ceil.f32(float)
302 declare float @llvm.trunc.f32(float)
303 declare float @llvm.rint.f32(float)
304 declare float @llvm.nearbyint.f32(float)
305 declare float @llvm.round.f32(float)
306 declare float @llvm.roundeven.f32(float)
307 declare float @llvm.fptrunc.round.f32.f64(double, metadata)
308 declare float @llvm.arithmetic.fence.f32(float)
309 declare float @llvm.copysign.f32(float, float)
310 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
311 declare float @llvm.sqrt.f32(float)
312 declare float @llvm.maxnum.f32(float, float)
313 declare void @llvm.assume(i1 noundef)
316 define float @fabs_select_positive_constants(i32 %c) {
317 ; CHECK-LABEL: @fabs_select_positive_constants(
318 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
319 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
320 ; CHECK-NEXT: ret float [[SELECT]]
322 %cmp = icmp eq i32 %c, 0
323 %select = select i1 %cmp, float 1.0, float 2.0
324 %fabs = call float @llvm.fabs.f32(float %select)
328 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
329 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
330 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
331 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
332 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
334 %cmp = icmp eq i32 %c, 0
335 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
336 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
337 ret <2 x float> %fabs
340 define float @fabs_select_constant_variable(i32 %c, float %x) {
341 ; CHECK-LABEL: @fabs_select_constant_variable(
342 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
343 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
344 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
345 ; CHECK-NEXT: ret float [[FABS]]
347 %cmp = icmp eq i32 %c, 0
348 %select = select i1 %cmp, float 1.0, float %x
349 %fabs = call float @llvm.fabs.f32(float %select)
353 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
354 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
355 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
356 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
357 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
358 ; CHECK-NEXT: ret <2 x float> [[FABS]]
360 %cmp = icmp eq i32 %c, 0
361 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
362 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
363 ret <2 x float> %fabs
366 define float @fabs_select_neg0_pos0(i32 %c) {
367 ; CHECK-LABEL: @fabs_select_neg0_pos0(
368 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
369 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
370 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
371 ; CHECK-NEXT: ret float [[FABS]]
373 %cmp = icmp eq i32 %c, 0
374 %select = select i1 %cmp, float -0.0, float 0.0
375 %fabs = call float @llvm.fabs.f32(float %select)
379 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
380 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
381 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
382 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
383 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
384 ; CHECK-NEXT: ret <2 x float> [[FABS]]
386 %cmp = icmp eq i32 %c, 0
387 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
388 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
389 ret <2 x float> %fabs
392 define float @fabs_select_neg0_neg1(i32 %c) {
393 ; CHECK-LABEL: @fabs_select_neg0_neg1(
394 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
395 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
396 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
397 ; CHECK-NEXT: ret float [[FABS]]
399 %cmp = icmp eq i32 %c, 0
400 %select = select i1 %cmp, float -0.0, float -1.0
401 %fabs = call float @llvm.fabs.f32(float %select)
405 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
406 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
407 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
408 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> <float -1.000000e+00, float -1.000000e+00>
409 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
410 ; CHECK-NEXT: ret <2 x float> [[FABS]]
412 %cmp = icmp eq i32 %c, 0
413 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
414 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
415 ret <2 x float> %fabs
418 define float @fabs_select_nan_nan(i32 %c) {
419 ; CHECK-LABEL: @fabs_select_nan_nan(
420 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
421 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
422 ; CHECK-NEXT: ret float [[SELECT]]
424 %cmp = icmp eq i32 %c, 0
425 %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
426 %fabs = call float @llvm.fabs.f32(float %select)
430 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
431 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
432 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
433 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
434 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
436 %cmp = icmp eq i32 %c, 0
437 %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
438 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
439 ret <2 x float> %fabs
442 define float @fabs_select_negnan_nan(i32 %c) {
443 ; CHECK-LABEL: @fabs_select_negnan_nan(
444 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
445 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
446 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
447 ; CHECK-NEXT: ret float [[FABS]]
449 %cmp = icmp eq i32 %c, 0
450 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
451 %fabs = call float @llvm.fabs.f32(float %select)
455 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
456 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
457 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
458 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
459 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
460 ; CHECK-NEXT: ret <2 x float> [[FABS]]
462 %cmp = icmp eq i32 %c, 0
463 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
464 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
465 ret <2 x float> %fabs
468 define float @fabs_select_negnan_negnan(i32 %c) {
469 ; CHECK-LABEL: @fabs_select_negnan_negnan(
470 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
471 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
472 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
473 ; CHECK-NEXT: ret float [[FABS]]
475 %cmp = icmp eq i32 %c, 0
476 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
477 %fabs = call float @llvm.fabs.f32(float %select)
481 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
482 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
483 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
484 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
485 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
486 ; CHECK-NEXT: ret <2 x float> [[FABS]]
488 %cmp = icmp eq i32 %c, 0
489 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
490 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
491 ret <2 x float> %fabs
494 define float @fabs_select_negnan_negzero(i32 %c) {
495 ; CHECK-LABEL: @fabs_select_negnan_negzero(
496 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
497 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
498 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
499 ; CHECK-NEXT: ret float [[FABS]]
501 %cmp = icmp eq i32 %c, 0
502 %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
503 %fabs = call float @llvm.fabs.f32(float %select)
507 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
508 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
509 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
510 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
511 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
512 ; CHECK-NEXT: ret <2 x float> [[FABS]]
514 %cmp = icmp eq i32 %c, 0
515 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
516 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
517 ret <2 x float> %fabs
520 define float @fabs_select_negnan_zero(i32 %c) {
521 ; CHECK-LABEL: @fabs_select_negnan_zero(
522 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
523 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
524 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
525 ; CHECK-NEXT: ret float [[FABS]]
527 %cmp = icmp eq i32 %c, 0
528 %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
529 %fabs = call float @llvm.fabs.f32(float %select)
533 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
534 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
535 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
536 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
537 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
538 ; CHECK-NEXT: ret <2 x float> [[FABS]]
540 %cmp = icmp eq i32 %c, 0
541 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
542 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
543 ret <2 x float> %fabs
546 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
547 ; an arbitrary sign bit.
548 define float @fabs_sqrt(float %a) {
549 ; CHECK-LABEL: @fabs_sqrt(
550 ; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
551 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
552 ; CHECK-NEXT: ret float [[FABS]]
554 %sqrt = call float @llvm.sqrt.f32(float %a)
555 %fabs = call float @llvm.fabs.f32(float %sqrt)
559 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
560 define float @fabs_sqrt_nnan(float %a) {
561 ; CHECK-LABEL: @fabs_sqrt_nnan(
562 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
563 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
564 ; CHECK-NEXT: ret float [[FABS]]
566 %sqrt = call nnan float @llvm.sqrt.f32(float %a)
567 %fabs = call float @llvm.fabs.f32(float %sqrt)
571 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
572 define float @fabs_sqrt_nsz(float %a) {
573 ; CHECK-LABEL: @fabs_sqrt_nsz(
574 ; CHECK-NEXT: [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
575 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
576 ; CHECK-NEXT: ret float [[FABS]]
578 %sqrt = call nsz float @llvm.sqrt.f32(float %a)
579 %fabs = call float @llvm.fabs.f32(float %sqrt)
583 ; The fabs can be eliminated because we're nsz and nnan.
584 define float @fabs_sqrt_nnan_nsz(float %a) {
585 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
586 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
587 ; CHECK-NEXT: ret float [[SQRT]]
589 %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
590 %fabs = call float @llvm.fabs.f32(float %sqrt)
594 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
595 define float @fabs_sqrt_nnan_fabs(float %a) {
596 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
597 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
598 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
599 ; CHECK-NEXT: ret float [[SQRT]]
601 %b = call float @llvm.fabs.f32(float %a)
602 %sqrt = call nnan float @llvm.sqrt.f32(float %b)
603 %fabs = call float @llvm.fabs.f32(float %sqrt)
607 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
608 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
609 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
610 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 2.000000e+00>
611 ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
612 ; CHECK-NEXT: ret float [[EXTRACT]]
614 %cmp = icmp eq i32 %c, 0
615 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
616 %extract = extractelement <2 x float> %select, i32 0
617 %fabs = call float @llvm.fabs.f32(float %extract)
623 define float @fsub_fsub_common_op(float %x, float %y) {
624 ; CHECK-LABEL: @fsub_fsub_common_op(
625 ; CHECK-NEXT: ret float [[X:%.*]]
627 %s = fsub float %y, %x
628 %r = fsub reassoc nsz float %y, %s
632 define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
633 ; CHECK-LABEL: @fsub_fsub_common_op_vec(
634 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
636 %s = fsub <2 x float> %y, %x
637 %r = fsub reassoc nsz <2 x float> %y, %s
641 ; Negative test - fsub is not commutative.
642 ; Y - (X - Y) --> (Y - X) + Y (canonicalized)
644 define float @fsub_fsub_wrong_common_op(float %x, float %y) {
645 ; CHECK-LABEL: @fsub_fsub_wrong_common_op(
646 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
647 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
648 ; CHECK-NEXT: ret float [[R]]
650 %s = fsub float %x, %y
651 %r = fsub reassoc nsz float %y, %s
655 ; Negative test - negated operand needed.
658 define float @fsub_fsub_common_op_wrong_commute(float %x, float %y) {
659 ; CHECK-LABEL: @fsub_fsub_common_op_wrong_commute(
660 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
661 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
662 ; CHECK-NEXT: ret float [[R]]
664 %s = fsub float %y, %x
665 %r = fsub reassoc nsz float %s, %y
669 ; Negative test - fsub is not commutative.
672 define float @fsub_fsub_wrong_common_op_wrong_commute(float %x, float %y) {
673 ; CHECK-LABEL: @fsub_fsub_wrong_common_op_wrong_commute(
674 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
675 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
676 ; CHECK-NEXT: ret float [[R]]
678 %s = fsub float %x, %y
679 %r = fsub reassoc nsz float %s, %y
685 define float @fadd_fsub_common_op(float %x, float %y) {
686 ; CHECK-LABEL: @fadd_fsub_common_op(
687 ; CHECK-NEXT: ret float [[X:%.*]]
689 %a = fadd float %y, %x
690 %r = fsub reassoc nsz float %a, %y
696 define <2 x float> @fadd_fsub_common_op_commute_vec(<2 x float> %x, <2 x float> %y) {
697 ; CHECK-LABEL: @fadd_fsub_common_op_commute_vec(
698 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
700 %a = fadd <2 x float> %x, %y
701 %r = fsub reassoc nsz <2 x float> %a, %y
705 ; Negative test - negated operand needed.
708 define float @fadd_fsub_common_op_wrong_commute(float %x, float %y) {
709 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute(
710 ; CHECK-NEXT: [[A:%.*]] = fadd float [[Y:%.*]], [[X:%.*]]
711 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
712 ; CHECK-NEXT: ret float [[R]]
714 %a = fadd float %y, %x
715 %r = fsub reassoc nsz float %y, %a
719 ; Negative test - negated operand needed.
722 define float @fadd_fsub_common_op_wrong_commute_commute(float %x, float %y) {
723 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute_commute(
724 ; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], [[Y:%.*]]
725 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
726 ; CHECK-NEXT: ret float [[R]]
728 %a = fadd float %x, %y
729 %r = fsub reassoc nsz float %y, %a
735 define <2 x float> @fsub_fadd_common_op_vec(<2 x float> %x, <2 x float> %y) {
736 ; CHECK-LABEL: @fsub_fadd_common_op_vec(
737 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
739 %s = fsub <2 x float> %x, %y
740 %r = fadd reassoc nsz <2 x float> %y, %s
746 define float @fsub_fadd_common_op_commute(float %x, float %y) {
747 ; CHECK-LABEL: @fsub_fadd_common_op_commute(
748 ; CHECK-NEXT: ret float [[X:%.*]]
750 %s = fsub float %x, %y
751 %r = fadd reassoc nsz float %s, %y
758 define float @fsub_fadd_common_op_wrong_commute(float %x, float %y) {
759 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute(
760 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
761 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[Y]], [[S]]
762 ; CHECK-NEXT: ret float [[R]]
764 %s = fsub float %y, %x
765 %r = fadd reassoc nsz float %y, %s
772 define float @fsub_fadd_common_op_wrong_commute_commute(float %x, float %y) {
773 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute_commute(
774 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
775 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[S]], [[Y]]
776 ; CHECK-NEXT: ret float [[R]]
778 %s = fsub float %y, %x
779 %r = fadd reassoc nsz float %s, %y
783 ; PR46627 - https://bugs.llvm.org/show_bug.cgi?id=46627
785 define float @maxnum_with_poszero_op(float %a) {
786 ; CHECK-LABEL: @maxnum_with_poszero_op(
787 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 0.000000e+00)
788 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
789 ; CHECK-NEXT: ret float [[FABS]]
791 %max = call float @llvm.maxnum.f32(float %a, float 0.0)
792 %fabs = call float @llvm.fabs.f32(float %max)
796 define float @maxnum_with_poszero_op_commute(float %a) {
797 ; CHECK-LABEL: @maxnum_with_poszero_op_commute(
798 ; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
799 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float 0.000000e+00, float [[SQRT]])
800 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
801 ; CHECK-NEXT: ret float [[FABS]]
803 %sqrt = call float @llvm.sqrt.f32(float %a)
804 %max = call float @llvm.maxnum.f32(float 0.0, float %sqrt)
805 %fabs = call float @llvm.fabs.f32(float %max)
809 define float @maxnum_with_negzero_op(float %a) {
810 ; CHECK-LABEL: @maxnum_with_negzero_op(
811 ; CHECK-NEXT: [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
812 ; CHECK-NEXT: [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
813 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float -0.000000e+00, float [[FABSA]])
814 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
815 ; CHECK-NEXT: ret float [[FABS]]
817 %nnan = call nnan float @llvm.sqrt.f32(float %a)
818 %fabsa = call float @llvm.fabs.f32(float %nnan)
819 %max = call float @llvm.maxnum.f32(float -0.0, float %fabsa)
820 %fabs = call float @llvm.fabs.f32(float %max)
824 define float @maxnum_with_negzero_op_commute(float %a) {
825 ; CHECK-LABEL: @maxnum_with_negzero_op_commute(
826 ; CHECK-NEXT: [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
827 ; CHECK-NEXT: [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
828 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[FABSA]], float -0.000000e+00)
829 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
830 ; CHECK-NEXT: ret float [[FABS]]
832 %nnan = call nnan float @llvm.sqrt.f32(float %a)
833 %fabsa = call float @llvm.fabs.f32(float %nnan)
834 %max = call float @llvm.maxnum.f32(float %fabsa, float -0.0)
835 %fabs = call float @llvm.fabs.f32(float %max)
839 ; If an operand is strictly greater than 0.0, we know the sign of the result of maxnum.
841 define float @maxnum_with_pos_one_op(float %a) {
842 ; CHECK-LABEL: @maxnum_with_pos_one_op(
843 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 1.000000e+00)
844 ; CHECK-NEXT: ret float [[MAX]]
846 %max = call float @llvm.maxnum.f32(float %a, float 1.0)
847 %fabs = call float @llvm.fabs.f32(float %max)
851 define double @fadd_nnan_inf_op0(double %x) {
852 ; CHECK-LABEL: @fadd_nnan_inf_op0(
853 ; CHECK-NEXT: ret double 0x7FF0000000000000
855 %r = fadd nnan double 0x7ff0000000000000, %x
859 define double @fadd_nnan_inf_op1(double %x) {
860 ; CHECK-LABEL: @fadd_nnan_inf_op1(
861 ; CHECK-NEXT: ret double 0x7FF0000000000000
863 %r = fadd nnan double %x, 0x7ff0000000000000
867 define <2 x double> @fadd_nnan_neginf_op1(<2 x double> %x) {
868 ; CHECK-LABEL: @fadd_nnan_neginf_op1(
869 ; CHECK-NEXT: ret <2 x double> <double 0xFFF0000000000000, double poison>
871 %r = fadd nnan <2 x double> %x, <double 0xfff0000000000000, double poison>
875 define double @fadd_nnan_neginf_op0(double %x) {
876 ; CHECK-LABEL: @fadd_nnan_neginf_op0(
877 ; CHECK-NEXT: ret double 0xFFF0000000000000
879 %r = fadd nnan double 0xfff0000000000000, %x
883 ; negative test - requires nnan
885 define double @fadd_inf_op0(double %x) {
886 ; CHECK-LABEL: @fadd_inf_op0(
887 ; CHECK-NEXT: [[R:%.*]] = fadd double 0x7FF0000000000000, [[X:%.*]]
888 ; CHECK-NEXT: ret double [[R]]
890 %r = fadd double 0x7ff0000000000000, %x
894 define double @fsub_nnan_inf_op0(double %x) {
895 ; CHECK-LABEL: @fsub_nnan_inf_op0(
896 ; CHECK-NEXT: ret double 0x7FF0000000000000
898 %r = fsub nnan double 0x7ff0000000000000, %x
904 define double @fsub_nnan_inf_op1(double %x) {
905 ; CHECK-LABEL: @fsub_nnan_inf_op1(
906 ; CHECK-NEXT: ret double 0xFFF0000000000000
908 %r = fsub nnan double %x, 0x7ff0000000000000
912 define <2 x double> @fsub_nnan_inf_op1_vec(<2 x double> %x) {
913 ; CHECK-LABEL: @fsub_nnan_inf_op1_vec(
914 ; CHECK-NEXT: ret <2 x double> <double 0x7FF0000000000000, double poison>
916 %r = fsub nnan <2 x double> %x, <double 0xfff0000000000000, double poison>
920 define <2 x double> @fsub_nnan_neginf_op0(<2 x double> %x) {
921 ; CHECK-LABEL: @fsub_nnan_neginf_op0(
922 ; CHECK-NEXT: ret <2 x double> <double 0xFFF0000000000000, double poison>
924 %r = fsub nnan <2 x double> <double 0xfff0000000000000, double poison>, %x
930 define double @fsub_nnan_neginf_op1(double %x) {
931 ; CHECK-LABEL: @fsub_nnan_neginf_op1(
932 ; CHECK-NEXT: ret double 0x7FF0000000000000
934 %r = fsub nnan double %x, 0xfff0000000000000
938 ; negative test - requires nnan
940 define double @fsub_inf_op0(double %x) {
941 ; CHECK-LABEL: @fsub_inf_op0(
942 ; CHECK-NEXT: [[R:%.*]] = fsub double 0x7FF0000000000000, [[X:%.*]]
943 ; CHECK-NEXT: ret double [[R]]
945 %r = fsub double 0x7ff0000000000000, %x
949 define i1 @canonicalize_known_positive(float %a) {
950 ; CHECK-LABEL: @canonicalize_known_positive(
951 ; CHECK-NEXT: ret i1 true
953 %fabs = call float @llvm.fabs.f32(float %a)
954 %known.positive = call float @llvm.canonicalize.f32(float %fabs)
955 %cmp = fcmp nnan oge float %known.positive, 0.0
959 define i1 @canonicalize_unknown_positive(float %unknown) {
960 ; CHECK-LABEL: @canonicalize_unknown_positive(
961 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[UNKNOWN:%.*]], 0.000000e+00
962 ; CHECK-NEXT: ret i1 [[CMP]]
964 %cmp = fcmp nnan oge float %unknown, 0.0
968 define i1 @arithmetic_fence_known_positive(float %a) {
969 ; CHECK-LABEL: @arithmetic_fence_known_positive(
970 ; CHECK-NEXT: ret i1 true
972 %fabs = call float @llvm.fabs.f32(float %a)
973 %known.positive = call float @llvm.arithmetic.fence.f32(float %fabs)
974 %cmp = fcmp nnan oge float %known.positive, 0.0
978 define i1 @arithmetic_fence_unknown_positive(float %unknown) {
979 ; CHECK-LABEL: @arithmetic_fence_unknown_positive(
980 ; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[UNKNOWN:%.*]])
981 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[KNOWN_POSITIVE]], 0.000000e+00
982 ; CHECK-NEXT: ret i1 [[CMP]]
984 %known.positive = call float @llvm.arithmetic.fence.f32(float %unknown)
985 %cmp = fcmp nnan oge float %known.positive, 0.0
989 define i1 @copysign_known_positive_maybe_neg0(float %unknown, float %sign) {
990 ; CHECK-LABEL: @copysign_known_positive_maybe_neg0(
991 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float [[SIGN:%.*]])
992 ; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[UNKNOWN:%.*]], float [[SQRT]])
993 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[COPYSIGN]], 0.000000e+00
994 ; CHECK-NEXT: ret i1 [[CMP]]
996 %sqrt = call ninf nnan float @llvm.sqrt.f32(float %sign)
997 %copysign = call float @llvm.copysign.f32(float %unknown, float %sqrt)
998 %cmp = fcmp nnan oge float %copysign, 0.0
1002 define i1 @copysign_known_positive(float %unknown, float %sign) {
1003 ; CHECK-LABEL: @copysign_known_positive(
1004 ; CHECK-NEXT: ret i1 true
1006 %sqrt = call ninf nnan nsz float @llvm.sqrt.f32(float %sign)
1007 %copysign = call float @llvm.copysign.f32(float %unknown, float %sqrt)
1008 %cmp = fcmp nnan oge float %copysign, 0.0
1012 define i1 @copysign_unknown_positive(float %unknown, float %unknown.sign) {
1013 ; CHECK-LABEL: @copysign_unknown_positive(
1014 ; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[UNKNOWN:%.*]], float [[UNKNOWN_SIGN:%.*]])
1015 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[COPYSIGN]], 0.000000e+00
1016 ; CHECK-NEXT: ret i1 [[CMP]]
1018 %copysign = call float @llvm.copysign.f32(float %unknown, float %unknown.sign)
1019 %cmp = fcmp nnan oge float %copysign, 0.0
1023 ; https://alive2.llvm.org/ce/z/Y-EyY3
1024 define i1 @floor_known_positive(float %a) {
1025 ; CHECK-LABEL: @floor_known_positive(
1026 ; CHECK-NEXT: ret i1 true
1028 %fabs = call float @llvm.fabs.f32(float %a)
1029 %known.positive = call float @llvm.floor.f32(float %fabs)
1030 %cmp = fcmp nnan oge float %known.positive, 0.0
1034 define i1 @floor_unknown_positive(float %unknown) {
1035 ; CHECK-LABEL: @floor_unknown_positive(
1036 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN:%.*]])
1037 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1038 ; CHECK-NEXT: ret i1 [[CMP]]
1040 %op = call float @llvm.floor.f32(float %unknown)
1041 %cmp = fcmp nnan oge float %op, 0.0
1045 ; https://alive2.llvm.org/ce/z/3tBUoW
1046 define i1 @ceil_known_positive(float %a) {
1047 ; CHECK-LABEL: @ceil_known_positive(
1048 ; CHECK-NEXT: ret i1 true
1050 %fabs = call float @llvm.fabs.f32(float %a)
1051 %known.positive = call float @llvm.ceil.f32(float %fabs)
1052 %cmp = fcmp nnan oge float %known.positive, 0.0
1056 define i1 @ceil_unknown_positive(float %unknown) {
1057 ; CHECK-LABEL: @ceil_unknown_positive(
1058 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.ceil.f32(float [[UNKNOWN:%.*]])
1059 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1060 ; CHECK-NEXT: ret i1 [[CMP]]
1063 %op = call float @llvm.ceil.f32(float %unknown)
1064 %cmp = fcmp nnan oge float %op, 0.0
1068 ; https://alive2.llvm.org/ce/z/RbyJPX
1069 define i1 @trunc_known_positive(float %a) {
1070 ; CHECK-LABEL: @trunc_known_positive(
1071 ; CHECK-NEXT: ret i1 true
1073 %fabs = call float @llvm.fabs.f32(float %a)
1074 %known.positive = call float @llvm.trunc.f32(float %fabs)
1075 %cmp = fcmp nnan oge float %known.positive, 0.0
1079 define i1 @trunc_unknown_positive(float %unknown) {
1080 ; CHECK-LABEL: @trunc_unknown_positive(
1081 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.trunc.f32(float [[UNKNOWN:%.*]])
1082 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1083 ; CHECK-NEXT: ret i1 [[CMP]]
1085 %op = call float @llvm.trunc.f32(float %unknown)
1086 %cmp = fcmp nnan oge float %op, 0.0
1090 ; https://alive2.llvm.org/ce/z/bjC2Jm
1091 define i1 @rint_known_positive(float %a) {
1092 ; CHECK-LABEL: @rint_known_positive(
1093 ; CHECK-NEXT: ret i1 true
1095 %fabs = call float @llvm.fabs.f32(float %a)
1096 %known.positive = call float @llvm.rint.f32(float %fabs)
1097 %cmp = fcmp nnan oge float %known.positive, 0.0
1101 define i1 @rint_unknown_positive(float %unknown) {
1102 ; CHECK-LABEL: @rint_unknown_positive(
1103 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.rint.f32(float [[UNKNOWN:%.*]])
1104 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1105 ; CHECK-NEXT: ret i1 [[CMP]]
1107 %op = call float @llvm.rint.f32(float %unknown)
1108 %cmp = fcmp nnan oge float %op, 0.0
1112 ; https://alive2.llvm.org/ce/z/dFiL9n
1113 define i1 @nearbyint_known_positive(float %a) {
1114 ; CHECK-LABEL: @nearbyint_known_positive(
1115 ; CHECK-NEXT: ret i1 true
1117 %fabs = call float @llvm.fabs.f32(float %a)
1118 %known.positive = call float @llvm.nearbyint.f32(float %fabs)
1119 %cmp = fcmp nnan oge float %known.positive, 0.0
1123 define i1 @nearbyint_unknown_positive(float %unknown) {
1124 ; CHECK-LABEL: @nearbyint_unknown_positive(
1125 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.nearbyint.f32(float [[UNKNOWN:%.*]])
1126 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1127 ; CHECK-NEXT: ret i1 [[CMP]]
1129 %op = call float @llvm.nearbyint.f32(float %unknown)
1130 %cmp = fcmp nnan oge float %op, 0.0
1134 ; https://alive2.llvm.org/ce/z/kPhS-d
1135 define i1 @round_known_positive(float %a) {
1136 ; CHECK-LABEL: @round_known_positive(
1137 ; CHECK-NEXT: ret i1 true
1139 %fabs = call float @llvm.fabs.f32(float %a)
1140 %known.positive = call float @llvm.round.f32(float %fabs)
1141 %cmp = fcmp nnan oge float %known.positive, 0.0
1145 define i1 @round_unknown_positive(float %unknown) {
1146 ; CHECK-LABEL: @round_unknown_positive(
1147 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.round.f32(float [[UNKNOWN:%.*]])
1148 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1149 ; CHECK-NEXT: ret i1 [[CMP]]
1151 %op = call float @llvm.round.f32(float %unknown)
1152 %cmp = fcmp nnan oge float %op, 0.0
1156 ; https://alive2.llvm.org/ce/z/Z_tfsu
1157 define i1 @roundeven_known_positive(float %a) {
1158 ; CHECK-LABEL: @roundeven_known_positive(
1159 ; CHECK-NEXT: ret i1 true
1161 %fabs = call float @llvm.fabs.f32(float %a)
1162 %known.positive = call float @llvm.roundeven.f32(float %fabs)
1163 %cmp = fcmp nnan oge float %known.positive, 0.0
1167 define i1 @roundeven_unknown_positive(float %unknown) {
1168 ; CHECK-LABEL: @roundeven_unknown_positive(
1169 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.roundeven.f32(float [[UNKNOWN:%.*]])
1170 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1171 ; CHECK-NEXT: ret i1 [[CMP]]
1173 %op = call float @llvm.roundeven.f32(float %unknown)
1174 %cmp = fcmp nnan oge float %op, 0.0
1178 define i1 @fptrunc_round_known_positive(double %a) {
1179 ; CHECK-LABEL: @fptrunc_round_known_positive(
1180 ; CHECK-NEXT: ret i1 true
1182 %fabs = call double @llvm.fabs.f64(double %a)
1183 %known.positive = call float @llvm.fptrunc.round.f32.f64(double %fabs, metadata !"round.downward")
1184 %cmp = fcmp nnan oge float %known.positive, 0.0
1188 define i1 @fptrunc_round_unknown_positive(double %unknown) {
1189 ; CHECK-LABEL: @fptrunc_round_unknown_positive(
1190 ; CHECK-NEXT: [[OP:%.*]] = call float @llvm.fptrunc.round.f32.f64(double [[UNKNOWN:%.*]], metadata !"round.downward")
1191 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
1192 ; CHECK-NEXT: ret i1 [[CMP]]
1194 %op = call float @llvm.fptrunc.round.f32.f64(double %unknown, metadata !"round.downward")
1195 %cmp = fcmp nnan oge float %op, 0.0