1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare float @llvm.fabs.f32(float) nounwind readnone
5 declare float @llvm.pow.f32(float, float) nounwind readnone
6 declare <2 x half> @llvm.pow.v2f16(<2 x half>, <2 x half>) nounwind readnone
7 declare float @llvm.exp.f32(float) nounwind readnone
8 declare <2 x half> @llvm.exp.v2f16(<2 x half>) nounwind readnone
9 declare float @llvm.exp2.f32(float) nounwind readnone
10 declare <2 x half> @llvm.exp2.v2f16(<2 x half>) nounwind readnone
11 declare float @llvm.powi.f32.i32(float, i32) nounwind readnone
12 declare <2 x half> @llvm.powi.v2f16.i32(<2 x half>, i32) nounwind readnone
14 define float @exact_inverse(float %x) {
15 ; CHECK-LABEL: @exact_inverse(
16 ; CHECK-NEXT: [[DIV:%.*]] = fmul float [[X:%.*]], 1.250000e-01
17 ; CHECK-NEXT: ret float [[DIV]]
19 %div = fdiv float %x, 8.0
23 ; Min normal float = 1.17549435E-38
25 define float @exact_inverse2(float %x) {
26 ; CHECK-LABEL: @exact_inverse2(
27 ; CHECK-NEXT: [[DIV:%.*]] = fmul float [[X:%.*]], 0x47D0000000000000
28 ; CHECK-NEXT: ret float [[DIV]]
30 %div = fdiv float %x, 0x3810000000000000
34 ; Max exponent = 1.70141183E+38; don't transform to multiply with denormal.
36 define float @exact_inverse_but_denorm(float %x) {
37 ; CHECK-LABEL: @exact_inverse_but_denorm(
38 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], 0x47E0000000000000
39 ; CHECK-NEXT: ret float [[DIV]]
41 %div = fdiv float %x, 0x47E0000000000000
45 ; Denormal = float 1.40129846E-45; inverse can't be represented.
47 define float @not_exact_inverse2(float %x) {
48 ; CHECK-LABEL: @not_exact_inverse2(
49 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], 0x36A0000000000000
50 ; CHECK-NEXT: ret float [[DIV]]
52 %div = fdiv float %x, 0x36A0000000000000
56 ; Fast math allows us to replace this fdiv.
58 define float @not_exact_but_allow_recip(float %x) {
59 ; CHECK-LABEL: @not_exact_but_allow_recip(
60 ; CHECK-NEXT: [[DIV:%.*]] = fmul arcp float [[X:%.*]], 0x3FD5555560000000
61 ; CHECK-NEXT: ret float [[DIV]]
63 %div = fdiv arcp float %x, 3.0
67 ; Fast math allows us to replace this fdiv, but we don't to avoid a denormal.
68 ; TODO: What if the function attributes tell us that denormals are flushed?
70 define float @not_exact_but_allow_recip_but_denorm(float %x) {
71 ; CHECK-LABEL: @not_exact_but_allow_recip_but_denorm(
72 ; CHECK-NEXT: [[DIV:%.*]] = fdiv arcp float [[X:%.*]], 0x47E0000100000000
73 ; CHECK-NEXT: ret float [[DIV]]
75 %div = fdiv arcp float %x, 0x47E0000100000000
79 define <2 x float> @exact_inverse_splat(<2 x float> %x) {
80 ; CHECK-LABEL: @exact_inverse_splat(
81 ; CHECK-NEXT: [[DIV:%.*]] = fmul <2 x float> [[X:%.*]], <float 2.500000e-01, float 2.500000e-01>
82 ; CHECK-NEXT: ret <2 x float> [[DIV]]
84 %div = fdiv <2 x float> %x, <float 4.0, float 4.0>
88 define <vscale x 2 x float> @exact_inverse_scalable_splat(<vscale x 2 x float> %x) {
89 ; CHECK-LABEL: @exact_inverse_scalable_splat(
90 ; CHECK-NEXT: [[DIV:%.*]] = fmul <vscale x 2 x float> [[X:%.*]], shufflevector (<vscale x 2 x float> insertelement (<vscale x 2 x float> poison, float 2.500000e-01, i64 0), <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer)
91 ; CHECK-NEXT: ret <vscale x 2 x float> [[DIV]]
93 %div = fdiv <vscale x 2 x float> %x, shufflevector (<vscale x 2 x float> insertelement (<vscale x 2 x float> undef, float 4.0, i64 0), <vscale x 2 x float> undef, <vscale x 2 x i32> zeroinitializer)
94 ret <vscale x 2 x float> %div
97 ; Fast math allows us to replace this fdiv.
99 define <2 x float> @not_exact_but_allow_recip_splat(<2 x float> %x) {
100 ; CHECK-LABEL: @not_exact_but_allow_recip_splat(
101 ; CHECK-NEXT: [[DIV:%.*]] = fmul arcp <2 x float> [[X:%.*]], <float 0x3FD5555560000000, float 0x3FD5555560000000>
102 ; CHECK-NEXT: ret <2 x float> [[DIV]]
104 %div = fdiv arcp <2 x float> %x, <float 3.0, float 3.0>
108 define <2 x float> @exact_inverse_vec(<2 x float> %x) {
109 ; CHECK-LABEL: @exact_inverse_vec(
110 ; CHECK-NEXT: [[DIV:%.*]] = fmul <2 x float> [[X:%.*]], <float 2.500000e-01, float 1.250000e-01>
111 ; CHECK-NEXT: ret <2 x float> [[DIV]]
113 %div = fdiv <2 x float> %x, <float 4.0, float 8.0>
117 define <2 x float> @not_exact_inverse_splat(<2 x float> %x) {
118 ; CHECK-LABEL: @not_exact_inverse_splat(
119 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], <float 3.000000e+00, float 3.000000e+00>
120 ; CHECK-NEXT: ret <2 x float> [[DIV]]
122 %div = fdiv <2 x float> %x, <float 3.0, float 3.0>
126 define <2 x float> @not_exact_inverse_vec(<2 x float> %x) {
127 ; CHECK-LABEL: @not_exact_inverse_vec(
128 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.000000e+00, float 3.000000e+00>
129 ; CHECK-NEXT: ret <2 x float> [[DIV]]
131 %div = fdiv <2 x float> %x, <float 4.0, float 3.0>
135 define <2 x float> @not_exact_inverse_vec_arcp(<2 x float> %x) {
136 ; CHECK-LABEL: @not_exact_inverse_vec_arcp(
137 ; CHECK-NEXT: [[DIV:%.*]] = fmul arcp <2 x float> [[X:%.*]], <float 2.500000e-01, float 0x3FD5555560000000>
138 ; CHECK-NEXT: ret <2 x float> [[DIV]]
140 %div = fdiv arcp <2 x float> %x, <float 4.0, float 3.0>
144 define <2 x float> @not_exact_inverse_vec_arcp_with_undef_elt(<2 x float> %x) {
145 ; CHECK-LABEL: @not_exact_inverse_vec_arcp_with_undef_elt(
146 ; CHECK-NEXT: [[DIV:%.*]] = fdiv arcp <2 x float> [[X:%.*]], <float undef, float 3.000000e+00>
147 ; CHECK-NEXT: ret <2 x float> [[DIV]]
149 %div = fdiv arcp <2 x float> %x, <float undef, float 3.0>
153 ; (X / Y) / Z --> X / (Y * Z)
155 define float @div_with_div_numerator(float %x, float %y, float %z) {
156 ; CHECK-LABEL: @div_with_div_numerator(
157 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp float [[Y:%.*]], [[Z:%.*]]
158 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp float [[X:%.*]], [[TMP1]]
159 ; CHECK-NEXT: ret float [[DIV2]]
161 %div1 = fdiv ninf float %x, %y
162 %div2 = fdiv arcp reassoc float %div1, %z
166 ; Z / (X / Y) --> (Z * Y) / X
168 define <2 x float> @div_with_div_denominator(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
169 ; CHECK-LABEL: @div_with_div_denominator(
170 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[Y:%.*]], [[Z:%.*]]
171 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp <2 x float> [[TMP1]], [[X:%.*]]
172 ; CHECK-NEXT: ret <2 x float> [[DIV2]]
174 %div1 = fdiv nnan <2 x float> %x, %y
175 %div2 = fdiv arcp reassoc <2 x float> %z, %div1
176 ret <2 x float> %div2
179 ; Don't create an extra multiply if we can't eliminate the first div.
181 declare void @use_f32(float)
183 define float @div_with_div_numerator_extra_use(float %x, float %y, float %z) {
184 ; CHECK-LABEL: @div_with_div_numerator_extra_use(
185 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
186 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[DIV1]], [[Z:%.*]]
187 ; CHECK-NEXT: call void @use_f32(float [[DIV1]])
188 ; CHECK-NEXT: ret float [[DIV2]]
190 %div1 = fdiv float %x, %y
191 %div2 = fdiv fast float %div1, %z
192 call void @use_f32(float %div1)
196 define float @div_with_div_denominator_extra_use(float %x, float %y, float %z) {
197 ; CHECK-LABEL: @div_with_div_denominator_extra_use(
198 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
199 ; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[Z:%.*]], [[DIV1]]
200 ; CHECK-NEXT: call void @use_f32(float [[DIV1]])
201 ; CHECK-NEXT: ret float [[DIV2]]
203 %div1 = fdiv float %x, %y
204 %div2 = fdiv fast float %z, %div1
205 call void @use_f32(float %div1)
209 ; Z / (1.0 / Y) ==> Y * Z
211 define float @div_with_div_denominator_with_one_as_numerator_extra_use(float %x, float %y, float %z) {
212 ; CHECK-LABEL: @div_with_div_denominator_with_one_as_numerator_extra_use(
213 ; CHECK-NEXT: [[DIV1:%.*]] = fdiv float 1.000000e+00, [[Y:%.*]]
214 ; CHECK-NEXT: [[DIV2:%.*]] = fmul reassoc arcp float [[Y]], [[Z:%.*]]
215 ; CHECK-NEXT: call void @use_f32(float [[DIV1]])
216 ; CHECK-NEXT: ret float [[DIV2]]
218 %div1 = fdiv float 1.0, %y
219 %div2 = fdiv reassoc arcp float %z, %div1
220 call void @use_f32(float %div1)
224 define float @fneg_fneg(float %x, float %y) {
225 ; CHECK-LABEL: @fneg_fneg(
226 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
227 ; CHECK-NEXT: ret float [[DIV]]
229 %x.fneg = fsub float -0.0, %x
230 %y.fneg = fsub float -0.0, %y
231 %div = fdiv float %x.fneg, %y.fneg
235 define float @unary_fneg_unary_fneg(float %x, float %y) {
236 ; CHECK-LABEL: @unary_fneg_unary_fneg(
237 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
238 ; CHECK-NEXT: ret float [[DIV]]
240 %x.fneg = fneg float %x
241 %y.fneg = fneg float %y
242 %div = fdiv float %x.fneg, %y.fneg
246 define float @unary_fneg_fneg(float %x, float %y) {
247 ; CHECK-LABEL: @unary_fneg_fneg(
248 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
249 ; CHECK-NEXT: ret float [[DIV]]
251 %x.fneg = fneg float %x
252 %y.fneg = fsub float -0.0, %y
253 %div = fdiv float %x.fneg, %y.fneg
257 define float @fneg_unary_fneg(float %x, float %y) {
258 ; CHECK-LABEL: @fneg_unary_fneg(
259 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
260 ; CHECK-NEXT: ret float [[DIV]]
262 %x.fneg = fsub float -0.0, %x
263 %y.fneg = fneg float %y
264 %div = fdiv float %x.fneg, %y.fneg
268 ; The test above shows that no FMF are needed, but show that we are not dropping FMF.
270 define float @fneg_fneg_fast(float %x, float %y) {
271 ; CHECK-LABEL: @fneg_fneg_fast(
272 ; CHECK-NEXT: [[DIV:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]
273 ; CHECK-NEXT: ret float [[DIV]]
275 %x.fneg = fsub float -0.0, %x
276 %y.fneg = fsub float -0.0, %y
277 %div = fdiv fast float %x.fneg, %y.fneg
281 define float @unary_fneg_unary_fneg_fast(float %x, float %y) {
282 ; CHECK-LABEL: @unary_fneg_unary_fneg_fast(
283 ; CHECK-NEXT: [[DIV:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]
284 ; CHECK-NEXT: ret float [[DIV]]
286 %x.fneg = fneg float %x
287 %y.fneg = fneg float %y
288 %div = fdiv fast float %x.fneg, %y.fneg
292 define <2 x float> @fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {
293 ; CHECK-LABEL: @fneg_fneg_vec(
294 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
295 ; CHECK-NEXT: ret <2 x float> [[DIV]]
297 %xneg = fsub <2 x float> <float -0.0, float -0.0>, %x
298 %yneg = fsub <2 x float> <float -0.0, float -0.0>, %y
299 %div = fdiv <2 x float> %xneg, %yneg
303 define <2 x float> @unary_fneg_unary_fneg_vec(<2 x float> %x, <2 x float> %y) {
304 ; CHECK-LABEL: @unary_fneg_unary_fneg_vec(
305 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
306 ; CHECK-NEXT: ret <2 x float> [[DIV]]
308 %xneg = fneg <2 x float> %x
309 %yneg = fneg <2 x float> %y
310 %div = fdiv <2 x float> %xneg, %yneg
314 define <2 x float> @fneg_unary_fneg_vec(<2 x float> %x, <2 x float> %y) {
315 ; CHECK-LABEL: @fneg_unary_fneg_vec(
316 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
317 ; CHECK-NEXT: ret <2 x float> [[DIV]]
319 %xneg = fsub <2 x float> <float -0.0, float -0.0>, %x
320 %yneg = fneg <2 x float> %y
321 %div = fdiv <2 x float> %xneg, %yneg
325 define <2 x float> @unary_fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {
326 ; CHECK-LABEL: @unary_fneg_fneg_vec(
327 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
328 ; CHECK-NEXT: ret <2 x float> [[DIV]]
330 %xneg = fneg <2 x float> %x
331 %yneg = fsub <2 x float> <float -0.0, float -0.0>, %y
332 %div = fdiv <2 x float> %xneg, %yneg
336 define <2 x float> @fneg_fneg_vec_undef_elts(<2 x float> %x, <2 x float> %y) {
337 ; CHECK-LABEL: @fneg_fneg_vec_undef_elts(
338 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]
339 ; CHECK-NEXT: ret <2 x float> [[DIV]]
341 %xneg = fsub <2 x float> <float undef, float -0.0>, %x
342 %yneg = fsub <2 x float> <float -0.0, float undef>, %y
343 %div = fdiv <2 x float> %xneg, %yneg
347 define float @fneg_dividend_constant_divisor(float %x) {
348 ; CHECK-LABEL: @fneg_dividend_constant_divisor(
349 ; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00
350 ; CHECK-NEXT: ret float [[DIV]]
352 %neg = fsub float -0.0, %x
353 %div = fdiv nsz float %neg, 3.0
357 define float @unary_fneg_dividend_constant_divisor(float %x) {
358 ; CHECK-LABEL: @unary_fneg_dividend_constant_divisor(
359 ; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00
360 ; CHECK-NEXT: ret float [[DIV]]
363 %div = fdiv nsz float %neg, 3.0
367 define float @fneg_divisor_constant_dividend(float %x) {
368 ; CHECK-LABEL: @fneg_divisor_constant_dividend(
369 ; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float 3.000000e+00, [[X:%.*]]
370 ; CHECK-NEXT: ret float [[DIV]]
372 %neg = fsub float -0.0, %x
373 %div = fdiv nnan float -3.0, %neg
377 define float @unary_fneg_divisor_constant_dividend(float %x) {
378 ; CHECK-LABEL: @unary_fneg_divisor_constant_dividend(
379 ; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float 3.000000e+00, [[X:%.*]]
380 ; CHECK-NEXT: ret float [[DIV]]
383 %div = fdiv nnan float -3.0, %neg
387 define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {
388 ; CHECK-LABEL: @fneg_dividend_constant_divisor_vec(
389 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
390 ; CHECK-NEXT: ret <2 x float> [[DIV]]
392 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
393 %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>
397 define <2 x float> @unary_fneg_dividend_constant_divisor_vec(<2 x float> %x) {
398 ; CHECK-LABEL: @unary_fneg_dividend_constant_divisor_vec(
399 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
400 ; CHECK-NEXT: ret <2 x float> [[DIV]]
402 %neg = fneg <2 x float> %x
403 %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>
407 define <2 x float> @fneg_dividend_constant_divisor_vec_undef_elt(<2 x float> %x) {
408 ; CHECK-LABEL: @fneg_dividend_constant_divisor_vec_undef_elt(
409 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
410 ; CHECK-NEXT: ret <2 x float> [[DIV]]
412 %neg = fsub <2 x float> <float undef, float -0.0>, %x
413 %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>
417 define <2 x float> @fneg_divisor_constant_dividend_vec(<2 x float> %x) {
418 ; CHECK-LABEL: @fneg_divisor_constant_dividend_vec(
419 ; CHECK-NEXT: [[DIV:%.*]] = fdiv afn <2 x float> <float 3.000000e+00, float -5.000000e+00>, [[X:%.*]]
420 ; CHECK-NEXT: ret <2 x float> [[DIV]]
422 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
423 %div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg
427 define <2 x float> @unary_fneg_divisor_constant_dividend_vec(<2 x float> %x) {
428 ; CHECK-LABEL: @unary_fneg_divisor_constant_dividend_vec(
429 ; CHECK-NEXT: [[DIV:%.*]] = fdiv afn <2 x float> <float 3.000000e+00, float -5.000000e+00>, [[X:%.*]]
430 ; CHECK-NEXT: ret <2 x float> [[DIV]]
432 %neg = fneg <2 x float> %x
433 %div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg
438 ; X / (X * Y) --> 1.0 / Y
440 define float @div_factor(float %x, float %y) {
441 ; CHECK-LABEL: @div_factor(
442 ; CHECK-NEXT: [[D:%.*]] = fdiv reassoc nnan float 1.000000e+00, [[Y:%.*]]
443 ; CHECK-NEXT: ret float [[D]]
445 %m = fmul float %x, %y
446 %d = fdiv nnan reassoc float %x, %m
450 ; We can't do the transform without 'nnan' because if x is NAN and y is a number, this should return NAN.
452 define float @div_factor_too_strict(float %x, float %y) {
453 ; CHECK-LABEL: @div_factor_too_strict(
454 ; CHECK-NEXT: [[M:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
455 ; CHECK-NEXT: [[D:%.*]] = fdiv reassoc float [[X]], [[M]]
456 ; CHECK-NEXT: ret float [[D]]
458 %m = fmul float %x, %y
459 %d = fdiv reassoc float %x, %m
463 ; Commute, verify vector types, and show that we are not dropping extra FMF.
464 ; X / (Y * X) --> 1.0 / Y
466 define <2 x float> @div_factor_commute(<2 x float> %x, <2 x float> %y) {
467 ; CHECK-LABEL: @div_factor_commute(
468 ; CHECK-NEXT: [[D:%.*]] = fdiv reassoc nnan ninf nsz <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[Y:%.*]]
469 ; CHECK-NEXT: ret <2 x float> [[D]]
471 %m = fmul <2 x float> %y, %x
472 %d = fdiv nnan ninf nsz reassoc <2 x float> %x, %m
476 ; C1/(X*C2) => (C1/C2) / X
478 define <2 x float> @div_constant_dividend1(<2 x float> %x) {
479 ; CHECK-LABEL: @div_constant_dividend1(
480 ; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 5.000000e+00, float 1.000000e+00>, [[X:%.*]]
481 ; CHECK-NEXT: ret <2 x float> [[T2]]
483 %t1 = fmul <2 x float> %x, <float 3.0e0, float 7.0e0>
484 %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float 7.0e0>, %t1
488 define <2 x float> @div_constant_dividend1_arcp_only(<2 x float> %x) {
489 ; CHECK-LABEL: @div_constant_dividend1_arcp_only(
490 ; CHECK-NEXT: [[T1:%.*]] = fmul <2 x float> [[X:%.*]], <float 3.000000e+00, float 7.000000e+00>
491 ; CHECK-NEXT: [[T2:%.*]] = fdiv arcp <2 x float> <float 1.500000e+01, float 7.000000e+00>, [[T1]]
492 ; CHECK-NEXT: ret <2 x float> [[T2]]
494 %t1 = fmul <2 x float> %x, <float 3.0e0, float 7.0e0>
495 %t2 = fdiv arcp <2 x float> <float 15.0e0, float 7.0e0>, %t1
499 ; C1/(X/C2) => (C1*C2) / X
501 define <2 x float> @div_constant_dividend2(<2 x float> %x) {
502 ; CHECK-LABEL: @div_constant_dividend2(
503 ; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 4.500000e+01, float 4.900000e+01>, [[X:%.*]]
504 ; CHECK-NEXT: ret <2 x float> [[T2]]
506 %t1 = fdiv <2 x float> %x, <float 3.0e0, float -7.0e0>
507 %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1
511 define <2 x float> @div_constant_dividend2_reassoc_only(<2 x float> %x) {
512 ; CHECK-LABEL: @div_constant_dividend2_reassoc_only(
513 ; CHECK-NEXT: [[T1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 3.000000e+00, float -7.000000e+00>
514 ; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc <2 x float> <float 1.500000e+01, float -7.000000e+00>, [[T1]]
515 ; CHECK-NEXT: ret <2 x float> [[T2]]
517 %t1 = fdiv <2 x float> %x, <float 3.0e0, float -7.0e0>
518 %t2 = fdiv reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1
522 ; C1/(C2/X) => (C1/C2) * X
523 ; This tests the combination of 2 folds: (C1 * X) / C2 --> (C1 / C2) * X
525 define <2 x float> @div_constant_dividend3(<2 x float> %x) {
526 ; CHECK-LABEL: @div_constant_dividend3(
527 ; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>
528 ; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>
529 ; CHECK-NEXT: ret <2 x float> [[T2]]
531 %t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x
532 %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1
536 define double @fdiv_fneg1(double %x, double %y) {
537 ; CHECK-LABEL: @fdiv_fneg1(
538 ; CHECK-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
539 ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]]
540 ; CHECK-NEXT: ret double [[DIV]]
542 %neg = fsub double -0.0, %x
543 %div = fdiv double %neg, %y
547 define double @fdiv_unary_fneg1(double %x, double %y) {
548 ; CHECK-LABEL: @fdiv_unary_fneg1(
549 ; CHECK-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]
550 ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]]
551 ; CHECK-NEXT: ret double [[DIV]]
553 %neg = fneg double %x
554 %div = fdiv double %neg, %y
558 define <2 x float> @fdiv_fneg2(<2 x float> %x, <2 x float> %y) {
559 ; CHECK-LABEL: @fdiv_fneg2(
560 ; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
561 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]]
562 ; CHECK-NEXT: ret <2 x float> [[DIV]]
564 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
565 %div = fdiv <2 x float> %y, %neg
569 define <2 x float> @fdiv_unary_fneg2(<2 x float> %x, <2 x float> %y) {
570 ; CHECK-LABEL: @fdiv_unary_fneg2(
571 ; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
572 ; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]]
573 ; CHECK-NEXT: ret <2 x float> [[DIV]]
575 %neg = fneg <2 x float> %x
576 %div = fdiv <2 x float> %y, %neg
580 define float @fdiv_fneg1_extra_use(float %x, float %y) {
581 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
582 ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]
583 ; CHECK-NEXT: call void @use_f32(float [[NEG]])
584 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
585 ; CHECK-NEXT: ret float [[DIV]]
587 %neg = fsub float -0.0, %x
588 call void @use_f32(float %neg)
589 %div = fdiv float %neg, %y
593 define float @fabs_same_op(float %x) {
594 ; CHECK-LABEL: @fabs_same_op(
595 ; CHECK-NEXT: [[R:%.*]] = fdiv float [[X:%.*]], [[X]]
596 ; CHECK-NEXT: ret float [[R]]
598 %a = call float @llvm.fabs.f32(float %x)
599 %r = fdiv float %a, %a
603 define float @fabs_same_op_extra_use(float %x) {
604 ; CHECK-LABEL: @fabs_same_op_extra_use(
605 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
606 ; CHECK-NEXT: call void @use_f32(float [[A]])
607 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf float [[X]], [[X]]
608 ; CHECK-NEXT: ret float [[R]]
610 %a = call float @llvm.fabs.f32(float %x)
611 call void @use_f32(float %a)
612 %r = fdiv ninf reassoc float %a, %a
616 define float @fabs_fabs(float %x, float %y) {
617 ; CHECK-LABEL: @fabs_fabs(
618 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
619 ; CHECK-NEXT: [[R:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])
620 ; CHECK-NEXT: ret float [[R]]
622 %x.fabs = call float @llvm.fabs.f32(float %x)
623 %y.fabs = call float @llvm.fabs.f32(float %y)
624 %r = fdiv float %x.fabs, %y.fabs
628 define float @fabs_fabs_extra_use1(float %x, float %y) {
629 ; CHECK-LABEL: @fabs_fabs_extra_use1(
630 ; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
631 ; CHECK-NEXT: call void @use_f32(float [[X_FABS]])
632 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv ninf float [[X]], [[Y:%.*]]
633 ; CHECK-NEXT: [[R:%.*]] = call ninf float @llvm.fabs.f32(float [[TMP1]])
634 ; CHECK-NEXT: ret float [[R]]
636 %x.fabs = call float @llvm.fabs.f32(float %x)
637 call void @use_f32(float %x.fabs)
638 %y.fabs = call float @llvm.fabs.f32(float %y)
639 %r = fdiv ninf float %x.fabs, %y.fabs
643 define float @fabs_fabs_extra_use2(float %x, float %y) {
644 ; CHECK-LABEL: @fabs_fabs_extra_use2(
645 ; CHECK-NEXT: [[Y_FABS:%.*]] = call fast float @llvm.fabs.f32(float [[Y:%.*]])
646 ; CHECK-NEXT: call void @use_f32(float [[Y_FABS]])
647 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv reassoc ninf float [[X:%.*]], [[Y]]
648 ; CHECK-NEXT: [[R:%.*]] = call reassoc ninf float @llvm.fabs.f32(float [[TMP1]])
649 ; CHECK-NEXT: ret float [[R]]
651 %x.fabs = call fast float @llvm.fabs.f32(float %x)
652 %y.fabs = call fast float @llvm.fabs.f32(float %y)
653 call void @use_f32(float %y.fabs)
654 %r = fdiv reassoc ninf float %x.fabs, %y.fabs
658 ; negative test - don't create an extra instruction
660 define float @fabs_fabs_extra_use3(float %x, float %y) {
661 ; CHECK-LABEL: @fabs_fabs_extra_use3(
662 ; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
663 ; CHECK-NEXT: call void @use_f32(float [[X_FABS]])
664 ; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])
665 ; CHECK-NEXT: call void @use_f32(float [[Y_FABS]])
666 ; CHECK-NEXT: [[R:%.*]] = fdiv float [[X_FABS]], [[Y_FABS]]
667 ; CHECK-NEXT: ret float [[R]]
669 %x.fabs = call float @llvm.fabs.f32(float %x)
670 call void @use_f32(float %x.fabs)
671 %y.fabs = call float @llvm.fabs.f32(float %y)
672 call void @use_f32(float %y.fabs)
673 %r = fdiv float %x.fabs, %y.fabs
677 define float @pow_divisor(float %x, float %y, float %z) {
678 ; CHECK-LABEL: @pow_divisor(
679 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]
680 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc arcp float @llvm.pow.f32(float [[X:%.*]], float [[TMP1]])
681 ; CHECK-NEXT: [[R:%.*]] = fmul reassoc arcp float [[TMP2]], [[Z:%.*]]
682 ; CHECK-NEXT: ret float [[R]]
684 %p = call float @llvm.pow.f32(float %x, float %y)
685 %r = fdiv reassoc arcp float %z, %p
689 ; Negative test - don't create an extra pow
691 define float @pow_divisor_extra_use(float %x, float %y, float %z) {
692 ; CHECK-LABEL: @pow_divisor_extra_use(
693 ; CHECK-NEXT: [[P:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])
694 ; CHECK-NEXT: call void @use_f32(float [[P]])
695 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]
696 ; CHECK-NEXT: ret float [[R]]
698 %p = call float @llvm.pow.f32(float %x, float %y)
699 call void @use_f32(float %p)
700 %r = fdiv reassoc arcp float %z, %p
704 ; Negative test - must have reassoc+arcp
706 define float @pow_divisor_not_enough_fmf(float %x, float %y, float %z) {
707 ; CHECK-LABEL: @pow_divisor_not_enough_fmf(
708 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])
709 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]
710 ; CHECK-NEXT: ret float [[R]]
712 %p = call fast float @llvm.pow.f32(float %x, float %y)
713 %r = fdiv reassoc float %z, %p
717 ; Negative test - must have reassoc+arcp
719 define float @pow_divisor_not_enough_fmf2(float %x, float %y, float %z) {
720 ; CHECK-LABEL: @pow_divisor_not_enough_fmf2(
721 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])
722 ; CHECK-NEXT: [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]
723 ; CHECK-NEXT: ret float [[R]]
725 %p = call fast float @llvm.pow.f32(float %x, float %y)
726 %r = fdiv arcp float %z, %p
730 ; Special-case - reciprocal does not require extra fmul
732 define <2 x half> @pow_recip(<2 x half> %x, <2 x half> %y) {
733 ; CHECK-LABEL: @pow_recip(
734 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]
735 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.pow.v2f16(<2 x half> [[X:%.*]], <2 x half> [[TMP1]])
736 ; CHECK-NEXT: ret <2 x half> [[TMP2]]
738 %p = call <2 x half> @llvm.pow.v2f16(<2 x half> %x, <2 x half> %y)
739 %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p
743 define float @exp_divisor(float %y, float %z) {
744 ; CHECK-LABEL: @exp_divisor(
745 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]
746 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc arcp float @llvm.exp.f32(float [[TMP1]])
747 ; CHECK-NEXT: [[R:%.*]] = fmul reassoc arcp float [[TMP2]], [[Z:%.*]]
748 ; CHECK-NEXT: ret float [[R]]
750 %p = call float @llvm.exp.f32(float %y)
751 %r = fdiv reassoc arcp float %z, %p
755 ; Negative test - don't create an extra exp
757 define float @exp_divisor_extra_use(float %y, float %z) {
758 ; CHECK-LABEL: @exp_divisor_extra_use(
759 ; CHECK-NEXT: [[P:%.*]] = call float @llvm.exp.f32(float [[Y:%.*]])
760 ; CHECK-NEXT: call void @use_f32(float [[P]])
761 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]
762 ; CHECK-NEXT: ret float [[R]]
764 %p = call float @llvm.exp.f32(float %y)
765 call void @use_f32(float %p)
766 %r = fdiv reassoc arcp float %z, %p
770 ; Negative test - must have reassoc+arcp
772 define float @exp_divisor_not_enough_fmf(float %y, float %z) {
773 ; CHECK-LABEL: @exp_divisor_not_enough_fmf(
774 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.exp.f32(float [[Y:%.*]])
775 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]
776 ; CHECK-NEXT: ret float [[R]]
778 %p = call fast float @llvm.exp.f32(float %y)
779 %r = fdiv reassoc float %z, %p
783 ; Negative test - must have reassoc+arcp
785 define float @exp_divisor_not_enough_fmf2(float %y, float %z) {
786 ; CHECK-LABEL: @exp_divisor_not_enough_fmf2(
787 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.exp.f32(float [[Y:%.*]])
788 ; CHECK-NEXT: [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]
789 ; CHECK-NEXT: ret float [[R]]
791 %p = call fast float @llvm.exp.f32(float %y)
792 %r = fdiv arcp float %z, %p
796 ; Special-case - reciprocal does not require extra fmul
798 define <2 x half> @exp_recip(<2 x half> %x, <2 x half> %y) {
799 ; CHECK-LABEL: @exp_recip(
800 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]
801 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.exp.v2f16(<2 x half> [[TMP1]])
802 ; CHECK-NEXT: ret <2 x half> [[TMP2]]
804 %p = call <2 x half> @llvm.exp.v2f16(<2 x half> %y)
805 %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p
809 define float @exp2_divisor(float %y, float %z) {
810 ; CHECK-LABEL: @exp2_divisor(
811 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]
812 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc arcp float @llvm.exp2.f32(float [[TMP1]])
813 ; CHECK-NEXT: [[R:%.*]] = fmul reassoc arcp float [[TMP2]], [[Z:%.*]]
814 ; CHECK-NEXT: ret float [[R]]
816 %p = call float @llvm.exp2.f32(float %y)
817 %r = fdiv reassoc arcp float %z, %p
821 ; Negative test - don't create an extra exp
823 define float @exp2_divisor_extra_use(float %y, float %z) {
824 ; CHECK-LABEL: @exp2_divisor_extra_use(
825 ; CHECK-NEXT: [[P:%.*]] = call float @llvm.exp2.f32(float [[Y:%.*]])
826 ; CHECK-NEXT: call void @use_f32(float [[P]])
827 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]
828 ; CHECK-NEXT: ret float [[R]]
830 %p = call float @llvm.exp2.f32(float %y)
831 call void @use_f32(float %p)
832 %r = fdiv reassoc arcp float %z, %p
836 ; Negative test - must have reassoc+arcp
838 define float @exp2_divisor_not_enough_fmf(float %y, float %z) {
839 ; CHECK-LABEL: @exp2_divisor_not_enough_fmf(
840 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.exp2.f32(float [[Y:%.*]])
841 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]
842 ; CHECK-NEXT: ret float [[R]]
844 %p = call fast float @llvm.exp2.f32(float %y)
845 %r = fdiv reassoc float %z, %p
849 ; Negative test - must have reassoc+arcp
851 define float @exp2_divisor_not_enough_fmf2(float %y, float %z) {
852 ; CHECK-LABEL: @exp2_divisor_not_enough_fmf2(
853 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.exp2.f32(float [[Y:%.*]])
854 ; CHECK-NEXT: [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]
855 ; CHECK-NEXT: ret float [[R]]
857 %p = call fast float @llvm.exp2.f32(float %y)
858 %r = fdiv arcp float %z, %p
862 ; Special-case - reciprocal does not require extra fmul
864 define <2 x half> @exp2_recip(<2 x half> %x, <2 x half> %y) {
865 ; CHECK-LABEL: @exp2_recip(
866 ; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]
867 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.exp2.v2f16(<2 x half> [[TMP1]])
868 ; CHECK-NEXT: ret <2 x half> [[TMP2]]
870 %p = call <2 x half> @llvm.exp2.v2f16(<2 x half> %y)
871 %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p
875 define float @powi_divisor(float %x, i32 %y, float %z) {
876 ; CHECK-LABEL: @powi_divisor(
877 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
878 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc ninf arcp float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[TMP1]])
879 ; CHECK-NEXT: [[R:%.*]] = fmul reassoc ninf arcp float [[TMP2]], [[Z:%.*]]
880 ; CHECK-NEXT: ret float [[R]]
882 %p = call float @llvm.powi.f32.i32(float %x, i32 %y)
883 %r = fdiv reassoc arcp ninf float %z, %p
887 ; Negative test - don't create an extra pow
889 define float @powi_divisor_extra_use(float %x, i32 %y, float %z) {
890 ; CHECK-LABEL: @powi_divisor_extra_use(
891 ; CHECK-NEXT: [[P:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])
892 ; CHECK-NEXT: call void @use_f32(float [[P]])
893 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf arcp float [[Z:%.*]], [[P]]
894 ; CHECK-NEXT: ret float [[R]]
896 %p = call float @llvm.powi.f32.i32(float %x, i32 %y)
897 call void @use_f32(float %p)
898 %r = fdiv reassoc arcp ninf float %z, %p
902 ; Negative test - must have reassoc+arcp+ninf
904 define float @powi_divisor_not_enough_fmf(float %x, i32 %y, float %z) {
905 ; CHECK-LABEL: @powi_divisor_not_enough_fmf(
906 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])
907 ; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf float [[Z:%.*]], [[P]]
908 ; CHECK-NEXT: ret float [[R]]
910 %p = call fast float @llvm.powi.f32.i32(float %x, i32 %y)
911 %r = fdiv reassoc ninf float %z, %p
915 ; Negative test - must have reassoc+arcp+ninf
917 define float @powi_divisor_not_enough_fmf2(float %x, i32 %y, float %z) {
918 ; CHECK-LABEL: @powi_divisor_not_enough_fmf2(
919 ; CHECK-NEXT: [[P:%.*]] = call fast float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])
920 ; CHECK-NEXT: [[R:%.*]] = fdiv ninf arcp float [[Z:%.*]], [[P]]
921 ; CHECK-NEXT: ret float [[R]]
923 %p = call fast float @llvm.powi.f32.i32(float %x, i32 %y)
924 %r = fdiv arcp ninf float %z, %p
928 ; Special-case - reciprocal does not require extra fmul
930 define <2 x half> @powi_recip(<2 x half> %x, i32 %y) {
931 ; CHECK-LABEL: @powi_recip(
932 ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
933 ; CHECK-NEXT: [[TMP2:%.*]] = call reassoc nnan ninf arcp <2 x half> @llvm.powi.v2f16.i32(<2 x half> [[X:%.*]], i32 [[TMP1]])
934 ; CHECK-NEXT: ret <2 x half> [[TMP2]]
936 %p = call <2 x half> @llvm.powi.v2f16.i32(<2 x half> %x, i32 %y)
937 %r = fdiv reassoc arcp nnan ninf <2 x half> <half 1.0, half 1.0>, %p
941 define float @fdiv_zero_f32(float %x) {
942 ; CHECK-LABEL: @fdiv_zero_f32(
943 ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[X:%.*]], 0.000000e+00
944 ; CHECK-NEXT: ret float [[FDIV]]
946 %fdiv = fdiv float %x, 0.0
950 ; https://alive2.llvm.org/ce/z/gLBFKB
951 define float @fdiv_nnan_zero_f32(float %x) {
952 ; CHECK-LABEL: @fdiv_nnan_zero_f32(
953 ; CHECK-NEXT: [[FDIV:%.*]] = call nnan float @llvm.copysign.f32(float 0x7FF0000000000000, float [[X:%.*]])
954 ; CHECK-NEXT: ret float [[FDIV]]
956 %fdiv = fdiv nnan float %x, 0.0
960 define <2 x float> @fdiv_nnan_zero_v2f32(<2 x float> %x) {
961 ; CHECK-LABEL: @fdiv_nnan_zero_v2f32(
962 ; CHECK-NEXT: [[FDIV:%.*]] = call nnan <2 x float> @llvm.copysign.v2f32(<2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, <2 x float> [[X:%.*]])
963 ; CHECK-NEXT: ret <2 x float> [[FDIV]]
965 %fdiv = fdiv nnan <2 x float> %x, zeroinitializer
966 ret <2 x float> %fdiv
969 define float @fdiv_nnan_zero_f32_fmf(float %x) {
970 ; CHECK-LABEL: @fdiv_nnan_zero_f32_fmf(
971 ; CHECK-NEXT: [[FDIV:%.*]] = call nnan nsz float @llvm.copysign.f32(float 0x7FF0000000000000, float [[X:%.*]])
972 ; CHECK-NEXT: ret float [[FDIV]]
974 %fdiv = fdiv nnan nsz float %x, 0.0
978 define <2 x float> @fdiv_nnan_zero_v2f32_fmf(<2 x float> %x) {
979 ; CHECK-LABEL: @fdiv_nnan_zero_v2f32_fmf(
980 ; CHECK-NEXT: [[FDIV:%.*]] = call nnan nsz <2 x float> @llvm.copysign.v2f32(<2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, <2 x float> [[X:%.*]])
981 ; CHECK-NEXT: ret <2 x float> [[FDIV]]
983 %fdiv = fdiv nnan nsz <2 x float> %x, zeroinitializer
984 ret <2 x float> %fdiv
987 define float @fdiv_nnan_neg_zero_f32(float %x) {
988 ; CHECK-LABEL: @fdiv_nnan_neg_zero_f32(
989 ; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan float [[X:%.*]], -0.000000e+00
990 ; CHECK-NEXT: ret float [[FDIV]]
992 %fdiv = fdiv nnan float %x, -0.0