1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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
174 define <4 x float> @fmul_X_1_vec(<4 x float> %x) {
175 ; CHECK-LABEL: @fmul_X_1_vec(
176 ; CHECK-NEXT: ret <4 x float> [[X:%.*]]
178 %m = fmul <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>
183 define float @fdiv_x_1(float %a) {
184 ; CHECK-LABEL: @fdiv_x_1(
185 ; CHECK-NEXT: ret float [[A:%.*]]
187 %ret = fdiv float %a, 1.0
191 ; We can't optimize away the fadd in this test because the input
192 ; value to the function and subsequently to the fadd may be -0.0.
193 ; In that one special case, the result of the fadd should be +0.0
194 ; rather than the first parameter of the fadd.
196 ; Fragile test warning: We need 6 sqrt calls to trigger the bug
197 ; because the internal logic has a magic recursion limit of 6.
198 ; This is presented without any explanation or ability to customize.
200 declare float @sqrtf(float)
202 define float @PR22688(float %x) {
203 ; CHECK-LABEL: @PR22688(
204 ; CHECK-NEXT: [[TMP1:%.*]] = call float @sqrtf(float [[X:%.*]])
205 ; CHECK-NEXT: [[TMP2:%.*]] = call float @sqrtf(float [[TMP1]])
206 ; CHECK-NEXT: [[TMP3:%.*]] = call float @sqrtf(float [[TMP2]])
207 ; CHECK-NEXT: [[TMP4:%.*]] = call float @sqrtf(float [[TMP3]])
208 ; CHECK-NEXT: [[TMP5:%.*]] = call float @sqrtf(float [[TMP4]])
209 ; CHECK-NEXT: [[TMP6:%.*]] = call float @sqrtf(float [[TMP5]])
210 ; CHECK-NEXT: [[TMP7:%.*]] = fadd float [[TMP6]], 0.000000e+00
211 ; CHECK-NEXT: ret float [[TMP7]]
213 %1 = call float @sqrtf(float %x)
214 %2 = call float @sqrtf(float %1)
215 %3 = call float @sqrtf(float %2)
216 %4 = call float @sqrtf(float %3)
217 %5 = call float @sqrtf(float %4)
218 %6 = call float @sqrtf(float %5)
219 %7 = fadd float %6, 0.0
223 declare float @llvm.fabs.f32(float)
224 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
225 declare float @llvm.sqrt.f32(float)
227 define float @fabs_select_positive_constants(i32 %c) {
228 ; CHECK-LABEL: @fabs_select_positive_constants(
229 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
230 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
231 ; CHECK-NEXT: ret float [[SELECT]]
233 %cmp = icmp eq i32 %c, 0
234 %select = select i1 %cmp, float 1.0, float 2.0
235 %fabs = call float @llvm.fabs.f32(float %select)
239 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
240 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
241 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
242 ; 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>
243 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
245 %cmp = icmp eq i32 %c, 0
246 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
247 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
248 ret <2 x float> %fabs
251 define float @fabs_select_constant_variable(i32 %c, float %x) {
252 ; CHECK-LABEL: @fabs_select_constant_variable(
253 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
254 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
255 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
256 ; CHECK-NEXT: ret float [[FABS]]
258 %cmp = icmp eq i32 %c, 0
259 %select = select i1 %cmp, float 1.0, float %x
260 %fabs = call float @llvm.fabs.f32(float %select)
264 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
265 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
266 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
267 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
268 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
269 ; CHECK-NEXT: ret <2 x float> [[FABS]]
271 %cmp = icmp eq i32 %c, 0
272 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
273 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
274 ret <2 x float> %fabs
277 define float @fabs_select_neg0_pos0(i32 %c) {
278 ; CHECK-LABEL: @fabs_select_neg0_pos0(
279 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
280 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
281 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
282 ; CHECK-NEXT: ret float [[FABS]]
284 %cmp = icmp eq i32 %c, 0
285 %select = select i1 %cmp, float -0.0, float 0.0
286 %fabs = call float @llvm.fabs.f32(float %select)
290 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
291 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
292 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
293 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
294 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
295 ; CHECK-NEXT: ret <2 x float> [[FABS]]
297 %cmp = icmp eq i32 %c, 0
298 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
299 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
300 ret <2 x float> %fabs
303 define float @fabs_select_neg0_neg1(i32 %c) {
304 ; CHECK-LABEL: @fabs_select_neg0_neg1(
305 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
306 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
307 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
308 ; CHECK-NEXT: ret float [[FABS]]
310 %cmp = icmp eq i32 %c, 0
311 %select = select i1 %cmp, float -0.0, float -1.0
312 %fabs = call float @llvm.fabs.f32(float %select)
316 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
317 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
318 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
319 ; 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>
320 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
321 ; CHECK-NEXT: ret <2 x float> [[FABS]]
323 %cmp = icmp eq i32 %c, 0
324 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
325 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
326 ret <2 x float> %fabs
329 define float @fabs_select_nan_nan(i32 %c) {
330 ; CHECK-LABEL: @fabs_select_nan_nan(
331 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
332 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
333 ; CHECK-NEXT: ret float [[SELECT]]
335 %cmp = icmp eq i32 %c, 0
336 %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
337 %fabs = call float @llvm.fabs.f32(float %select)
341 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
342 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
343 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
344 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
345 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
347 %cmp = icmp eq i32 %c, 0
348 %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
349 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
350 ret <2 x float> %fabs
353 define float @fabs_select_negnan_nan(i32 %c) {
354 ; CHECK-LABEL: @fabs_select_negnan_nan(
355 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
356 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
357 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
358 ; CHECK-NEXT: ret float [[FABS]]
360 %cmp = icmp eq i32 %c, 0
361 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
362 %fabs = call float @llvm.fabs.f32(float %select)
366 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
367 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
368 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
369 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
370 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
371 ; CHECK-NEXT: ret <2 x float> [[FABS]]
373 %cmp = icmp eq i32 %c, 0
374 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
375 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
376 ret <2 x float> %fabs
379 define float @fabs_select_negnan_negnan(i32 %c) {
380 ; CHECK-LABEL: @fabs_select_negnan_negnan(
381 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
382 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
383 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
384 ; CHECK-NEXT: ret float [[FABS]]
386 %cmp = icmp eq i32 %c, 0
387 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
388 %fabs = call float @llvm.fabs.f32(float %select)
392 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
393 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
394 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
395 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
396 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
397 ; CHECK-NEXT: ret <2 x float> [[FABS]]
399 %cmp = icmp eq i32 %c, 0
400 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
401 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
402 ret <2 x float> %fabs
405 define float @fabs_select_negnan_negzero(i32 %c) {
406 ; CHECK-LABEL: @fabs_select_negnan_negzero(
407 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
408 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
409 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
410 ; CHECK-NEXT: ret float [[FABS]]
412 %cmp = icmp eq i32 %c, 0
413 %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
414 %fabs = call float @llvm.fabs.f32(float %select)
418 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
419 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
420 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
421 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
422 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
423 ; CHECK-NEXT: ret <2 x float> [[FABS]]
425 %cmp = icmp eq i32 %c, 0
426 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
427 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
428 ret <2 x float> %fabs
431 define float @fabs_select_negnan_zero(i32 %c) {
432 ; CHECK-LABEL: @fabs_select_negnan_zero(
433 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
434 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
435 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
436 ; CHECK-NEXT: ret float [[FABS]]
438 %cmp = icmp eq i32 %c, 0
439 %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
440 %fabs = call float @llvm.fabs.f32(float %select)
444 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
445 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
446 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
447 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
448 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
449 ; CHECK-NEXT: ret <2 x float> [[FABS]]
451 %cmp = icmp eq i32 %c, 0
452 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
453 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
454 ret <2 x float> %fabs
457 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
458 ; an arbitrary sign bit.
459 define float @fabs_sqrt(float %a) {
460 ; CHECK-LABEL: @fabs_sqrt(
461 ; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
462 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
463 ; CHECK-NEXT: ret float [[FABS]]
465 %sqrt = call float @llvm.sqrt.f32(float %a)
466 %fabs = call float @llvm.fabs.f32(float %sqrt)
470 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
471 define float @fabs_sqrt_nnan(float %a) {
472 ; CHECK-LABEL: @fabs_sqrt_nnan(
473 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
474 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
475 ; CHECK-NEXT: ret float [[FABS]]
477 %sqrt = call nnan float @llvm.sqrt.f32(float %a)
478 %fabs = call float @llvm.fabs.f32(float %sqrt)
482 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
483 define float @fabs_sqrt_nsz(float %a) {
484 ; CHECK-LABEL: @fabs_sqrt_nsz(
485 ; CHECK-NEXT: [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
486 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
487 ; CHECK-NEXT: ret float [[FABS]]
489 %sqrt = call nsz float @llvm.sqrt.f32(float %a)
490 %fabs = call float @llvm.fabs.f32(float %sqrt)
494 ; The fabs can be eliminated because we're nsz and nnan.
495 define float @fabs_sqrt_nnan_nsz(float %a) {
496 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
497 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
498 ; CHECK-NEXT: ret float [[SQRT]]
500 %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
501 %fabs = call float @llvm.fabs.f32(float %sqrt)
505 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
506 define float @fabs_sqrt_nnan_fabs(float %a) {
507 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
508 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
509 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
510 ; CHECK-NEXT: ret float [[SQRT]]
512 %b = call float @llvm.fabs.f32(float %a)
513 %sqrt = call nnan float @llvm.sqrt.f32(float %b)
514 %fabs = call float @llvm.fabs.f32(float %sqrt)
518 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
519 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
520 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
521 ; 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>
522 ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
523 ; CHECK-NEXT: ret float [[EXTRACT]]
525 %cmp = icmp eq i32 %c, 0
526 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
527 %extract = extractelement <2 x float> %select, i32 0
528 %fabs = call float @llvm.fabs.f32(float %extract)
532 declare float @llvm.minnum.f32(float, float)
533 declare float @llvm.maxnum.f32(float, float)
534 declare double @llvm.minnum.f64(double, double)
535 declare double @llvm.maxnum.f64(double, double)
536 declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
537 declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
539 ; From the LangRef for minnum/maxnum:
540 ; "If either operand is a NaN, returns the other non-NaN operand."
542 define double @maxnum_nan_op0(double %x) {
543 ; CHECK-LABEL: @maxnum_nan_op0(
544 ; CHECK-NEXT: ret double [[X:%.*]]
546 %r = call double @llvm.maxnum.f64(double 0x7ff8000000000000, double %x)
550 define double @maxnum_nan_op1(double %x) {
551 ; CHECK-LABEL: @maxnum_nan_op1(
552 ; CHECK-NEXT: ret double [[X:%.*]]
554 %r = call double @llvm.maxnum.f64(double %x, double 0x7ff800000000dead)
558 define double @minnum_nan_op0(double %x) {
559 ; CHECK-LABEL: @minnum_nan_op0(
560 ; CHECK-NEXT: ret double [[X:%.*]]
562 %r = call double @llvm.minnum.f64(double 0x7ff8000dead00000, double %x)
566 define double @minnum_nan_op1(double %x) {
567 ; CHECK-LABEL: @minnum_nan_op1(
568 ; CHECK-NEXT: ret double [[X:%.*]]
570 %r = call double @llvm.minnum.f64(double %x, double 0x7ff800dead00dead)
574 define <2 x double> @maxnum_nan_op0_vec(<2 x double> %x) {
575 ; CHECK-LABEL: @maxnum_nan_op0_vec(
576 ; CHECK-NEXT: ret <2 x double> [[X:%.*]]
578 %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
582 define <2 x double> @maxnum_nan_op1_vec(<2 x double> %x) {
583 ; CHECK-LABEL: @maxnum_nan_op1_vec(
584 ; CHECK-NEXT: ret <2 x double> [[X:%.*]]
586 %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800000000dead, double 0x7ff8ffffffffffff>)
590 define <2 x double> @minnum_nan_op0_vec(<2 x double> %x) {
591 ; CHECK-LABEL: @minnum_nan_op0_vec(
592 ; CHECK-NEXT: ret <2 x double> [[X:%.*]]
594 %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
598 define <2 x double> @minnum_nan_op1_vec(<2 x double> %x) {
599 ; CHECK-LABEL: @minnum_nan_op1_vec(
600 ; CHECK-NEXT: ret <2 x double> [[X:%.*]]
602 %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800dead00dead, double 0x7ff800dead00dead>)
606 define float @maxnum_undef_op1(float %x) {
607 ; CHECK-LABEL: @maxnum_undef_op1(
608 ; CHECK-NEXT: ret float [[X:%.*]]
610 %val = call float @llvm.maxnum.f32(float %x, float undef)
614 define float @maxnum_undef_op0(float %x) {
615 ; CHECK-LABEL: @maxnum_undef_op0(
616 ; CHECK-NEXT: ret float [[X:%.*]]
618 %val = call float @llvm.maxnum.f32(float undef, float %x)
622 define float @minnum_undef_op1(float %x) {
623 ; CHECK-LABEL: @minnum_undef_op1(
624 ; CHECK-NEXT: ret float [[X:%.*]]
626 %val = call float @llvm.minnum.f32(float %x, float undef)
630 define float @minnum_undef_op0(float %x) {
631 ; CHECK-LABEL: @minnum_undef_op0(
632 ; CHECK-NEXT: ret float [[X:%.*]]
634 %val = call float @llvm.minnum.f32(float undef, float %x)
638 define float @minnum_undef_undef(float %x) {
639 ; CHECK-LABEL: @minnum_undef_undef(
640 ; CHECK-NEXT: ret float undef
642 %val = call float @llvm.minnum.f32(float undef, float undef)
646 define float @maxnum_undef_undef(float %x) {
647 ; CHECK-LABEL: @maxnum_undef_undef(
648 ; CHECK-NEXT: ret float undef
650 %val = call float @llvm.maxnum.f32(float undef, float undef)
654 define float @minnum_same_args(float %x) {
655 ; CHECK-LABEL: @minnum_same_args(
656 ; CHECK-NEXT: ret float [[X:%.*]]
658 %y = call float @llvm.minnum.f32(float %x, float %x)
662 define float @maxnum_same_args(float %x) {
663 ; CHECK-LABEL: @maxnum_same_args(
664 ; CHECK-NEXT: ret float [[X:%.*]]
666 %y = call float @llvm.maxnum.f32(float %x, float %x)
670 define float @minnum_x_minnum_x_y(float %x, float %y) {
671 ; CHECK-LABEL: @minnum_x_minnum_x_y(
672 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
673 ; CHECK-NEXT: ret float [[A]]
675 %a = call float @llvm.minnum.f32(float %x, float %y)
676 %b = call float @llvm.minnum.f32(float %x, float %a)
680 define float @minnum_y_minnum_x_y(float %x, float %y) {
681 ; CHECK-LABEL: @minnum_y_minnum_x_y(
682 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
683 ; CHECK-NEXT: ret float [[A]]
685 %a = call float @llvm.minnum.f32(float %x, float %y)
686 %b = call float @llvm.minnum.f32(float %y, float %a)
690 define float @minnum_x_y_minnum_x(float %x, float %y) {
691 ; CHECK-LABEL: @minnum_x_y_minnum_x(
692 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
693 ; CHECK-NEXT: ret float [[A]]
695 %a = call float @llvm.minnum.f32(float %x, float %y)
696 %b = call float @llvm.minnum.f32(float %a, float %x)
700 define float @minnum_x_y_minnum_y(float %x, float %y) {
701 ; CHECK-LABEL: @minnum_x_y_minnum_y(
702 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
703 ; CHECK-NEXT: ret float [[A]]
705 %a = call float @llvm.minnum.f32(float %x, float %y)
706 %b = call float @llvm.minnum.f32(float %a, float %y)
712 define float @minnum_z_minnum_x_y(float %x, float %y, float %z) {
713 ; CHECK-LABEL: @minnum_z_minnum_x_y(
714 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
715 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[A]])
716 ; CHECK-NEXT: ret float [[B]]
718 %a = call float @llvm.minnum.f32(float %x, float %y)
719 %b = call float @llvm.minnum.f32(float %z, float %a)
725 define float @minnum_x_y_minnum_z(float %x, float %y, float %z) {
726 ; CHECK-LABEL: @minnum_x_y_minnum_z(
727 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
728 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[Z:%.*]])
729 ; CHECK-NEXT: ret float [[B]]
731 %a = call float @llvm.minnum.f32(float %x, float %y)
732 %b = call float @llvm.minnum.f32(float %a, float %z)
736 ; minnum(X, -INF) --> -INF
738 define float @minnum_neginf(float %x) {
739 ; CHECK-LABEL: @minnum_neginf(
740 ; CHECK-NEXT: ret float 0xFFF0000000000000
742 %val = call float @llvm.minnum.f32(float %x, float 0xFFF0000000000000)
746 define <2 x double> @minnum_neginf_commute_vec(<2 x double> %x) {
747 ; CHECK-LABEL: @minnum_neginf_commute_vec(
748 ; CHECK-NEXT: ret <2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>
750 %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>, <2 x double> %x)
756 define float @minnum_inf(float %x) {
757 ; CHECK-LABEL: @minnum_inf(
758 ; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.minnum.f32(float 0x7FF0000000000000, float [[X:%.*]])
759 ; CHECK-NEXT: ret float [[VAL]]
761 %val = call float @llvm.minnum.f32(float 0x7FF0000000000000, float %x)
764 define float @maxnum_x_maxnum_x_y(float %x, float %y) {
765 ; CHECK-LABEL: @maxnum_x_maxnum_x_y(
766 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
767 ; CHECK-NEXT: ret float [[A]]
769 %a = call float @llvm.maxnum.f32(float %x, float %y)
770 %b = call float @llvm.maxnum.f32(float %x, float %a)
774 define float @maxnum_y_maxnum_x_y(float %x, float %y) {
775 ; CHECK-LABEL: @maxnum_y_maxnum_x_y(
776 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
777 ; CHECK-NEXT: ret float [[A]]
779 %a = call float @llvm.maxnum.f32(float %x, float %y)
780 %b = call float @llvm.maxnum.f32(float %y, float %a)
784 define float @maxnum_x_y_maxnum_x(float %x, float %y) {
785 ; CHECK-LABEL: @maxnum_x_y_maxnum_x(
786 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
787 ; CHECK-NEXT: ret float [[A]]
789 %a = call float @llvm.maxnum.f32(float %x, float %y)
790 %b = call float @llvm.maxnum.f32(float %a, float %x)
794 define float @maxnum_x_y_maxnum_y(float %x, float %y) {
795 ; CHECK-LABEL: @maxnum_x_y_maxnum_y(
796 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
797 ; CHECK-NEXT: ret float [[A]]
799 %a = call float @llvm.maxnum.f32(float %x, float %y)
800 %b = call float @llvm.maxnum.f32(float %a, float %y)
806 define float @maxnum_z_maxnum_x_y(float %x, float %y, float %z) {
807 ; CHECK-LABEL: @maxnum_z_maxnum_x_y(
808 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
809 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[A]])
810 ; CHECK-NEXT: ret float [[B]]
812 %a = call float @llvm.maxnum.f32(float %x, float %y)
813 %b = call float @llvm.maxnum.f32(float %z, float %a)
819 define float @maxnum_x_y_maxnum_z(float %x, float %y, float %z) {
820 ; CHECK-LABEL: @maxnum_x_y_maxnum_z(
821 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
822 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[Z:%.*]])
823 ; CHECK-NEXT: ret float [[B]]
825 %a = call float @llvm.maxnum.f32(float %x, float %y)
826 %b = call float @llvm.maxnum.f32(float %a, float %z)
830 ; maxnum(X, INF) --> INF
832 define <2 x double> @maxnum_inf(<2 x double> %x) {
833 ; CHECK-LABEL: @maxnum_inf(
834 ; CHECK-NEXT: ret <2 x double> <double 0x7FF0000000000000, double 0x7FF0000000000000>
836 %val = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double><double 0x7FF0000000000000, double 0x7FF0000000000000>)
837 ret <2 x double> %val
840 define float @maxnum_inf_commute(float %x) {
841 ; CHECK-LABEL: @maxnum_inf_commute(
842 ; CHECK-NEXT: ret float 0x7FF0000000000000
844 %val = call float @llvm.maxnum.f32(float 0x7FF0000000000000, float %x)
850 define float @maxnum_neginf(float %x) {
851 ; CHECK-LABEL: @maxnum_neginf(
852 ; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.maxnum.f32(float 0xFFF0000000000000, float [[X:%.*]])
853 ; CHECK-NEXT: ret float [[VAL]]
855 %val = call float @llvm.maxnum.f32(float 0xFFF0000000000000, float %x)
859 declare float @llvm.minimum.f32(float, float)
860 declare float @llvm.maximum.f32(float, float)
861 declare double @llvm.minimum.f64(double, double)
862 declare double @llvm.maximum.f64(double, double)
863 declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
864 declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
866 ; From the LangRef for minimum/maximum:
867 ; "If either operand is a NaN, returns NaN."
869 define double @maximum_nan_op0(double %x) {
870 ; CHECK-LABEL: @maximum_nan_op0(
871 ; CHECK-NEXT: ret double 0x7FF8000000000000
873 %r = call double @llvm.maximum.f64(double 0x7ff8000000000000, double %x)
877 define double @maximum_nan_op1(double %x) {
878 ; CHECK-LABEL: @maximum_nan_op1(
879 ; CHECK-NEXT: ret double 0x7FF800000000DEAD
881 %r = call double @llvm.maximum.f64(double %x, double 0x7ff800000000dead)
885 define double @minimum_nan_op0(double %x) {
886 ; CHECK-LABEL: @minimum_nan_op0(
887 ; CHECK-NEXT: ret double 0x7FF8000DEAD00000
889 %r = call double @llvm.minimum.f64(double 0x7ff8000dead00000, double %x)
893 define double @minimum_nan_op1(double %x) {
894 ; CHECK-LABEL: @minimum_nan_op1(
895 ; CHECK-NEXT: ret double 0x7FF800DEAD00DEAD
897 %r = call double @llvm.minimum.f64(double %x, double 0x7ff800dead00dead)
901 define <2 x double> @maximum_nan_op0_vec(<2 x double> %x) {
902 ; CHECK-LABEL: @maximum_nan_op0_vec(
903 ; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef>
905 %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
909 define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) {
910 ; CHECK-LABEL: @maximum_nan_op1_vec(
911 ; CHECK-NEXT: ret <2 x double> <double 0x7FF800000000DEAD, double 0x7FF8FFFFFFFFFFFF>
913 %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800000000dead, double 0x7ff8ffffffffffff>)
917 define <2 x double> @minimum_nan_op0_vec(<2 x double> %x) {
918 ; CHECK-LABEL: @minimum_nan_op0_vec(
919 ; CHECK-NEXT: ret <2 x double> <double undef, double 0x7FF8000DEAD00000>
921 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
925 define <2 x double> @minimum_nan_op1_vec(<2 x double> %x) {
926 ; CHECK-LABEL: @minimum_nan_op1_vec(
927 ; CHECK-NEXT: ret <2 x double> <double 0x7FF800DEAD00DEAD, double 0x7FF800DEAD00DEAD>
929 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff800dead00dead, double 0x7ff800dead00dead>)
933 define float @maximum_undef_op1(float %x) {
934 ; CHECK-LABEL: @maximum_undef_op1(
935 ; CHECK-NEXT: ret float [[X:%.*]]
937 %val = call float @llvm.maximum.f32(float %x, float undef)
941 define float @maximum_undef_op0(float %x) {
942 ; CHECK-LABEL: @maximum_undef_op0(
943 ; CHECK-NEXT: ret float [[X:%.*]]
945 %val = call float @llvm.maximum.f32(float undef, float %x)
949 define float @minimum_undef_op1(float %x) {
950 ; CHECK-LABEL: @minimum_undef_op1(
951 ; CHECK-NEXT: ret float [[X:%.*]]
953 %val = call float @llvm.minimum.f32(float %x, float undef)
957 define float @minimum_undef_op0(float %x) {
958 ; CHECK-LABEL: @minimum_undef_op0(
959 ; CHECK-NEXT: ret float [[X:%.*]]
961 %val = call float @llvm.minimum.f32(float undef, float %x)
965 define float @minimum_undef_undef(float %x) {
966 ; CHECK-LABEL: @minimum_undef_undef(
967 ; CHECK-NEXT: ret float undef
969 %val = call float @llvm.minimum.f32(float undef, float undef)
973 define float @maximum_undef_undef(float %x) {
974 ; CHECK-LABEL: @maximum_undef_undef(
975 ; CHECK-NEXT: ret float undef
977 %val = call float @llvm.maximum.f32(float undef, float undef)
981 define float @minimum_same_args(float %x) {
982 ; CHECK-LABEL: @minimum_same_args(
983 ; CHECK-NEXT: ret float [[X:%.*]]
985 %y = call float @llvm.minimum.f32(float %x, float %x)
989 define float @maximum_same_args(float %x) {
990 ; CHECK-LABEL: @maximum_same_args(
991 ; CHECK-NEXT: ret float [[X:%.*]]
993 %y = call float @llvm.maximum.f32(float %x, float %x)
997 define float @minimum_x_minimum_x_y(float %x, float %y) {
998 ; CHECK-LABEL: @minimum_x_minimum_x_y(
999 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1000 ; CHECK-NEXT: ret float [[A]]
1002 %a = call float @llvm.minimum.f32(float %x, float %y)
1003 %b = call float @llvm.minimum.f32(float %x, float %a)
1007 define float @minimum_y_minimum_x_y(float %x, float %y) {
1008 ; CHECK-LABEL: @minimum_y_minimum_x_y(
1009 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1010 ; CHECK-NEXT: ret float [[A]]
1012 %a = call float @llvm.minimum.f32(float %x, float %y)
1013 %b = call float @llvm.minimum.f32(float %y, float %a)
1017 define float @minimum_x_y_minimum_x(float %x, float %y) {
1018 ; CHECK-LABEL: @minimum_x_y_minimum_x(
1019 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1020 ; CHECK-NEXT: ret float [[A]]
1022 %a = call float @llvm.minimum.f32(float %x, float %y)
1023 %b = call float @llvm.minimum.f32(float %a, float %x)
1027 define float @minimum_x_y_minimum_y(float %x, float %y) {
1028 ; CHECK-LABEL: @minimum_x_y_minimum_y(
1029 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1030 ; CHECK-NEXT: ret float [[A]]
1032 %a = call float @llvm.minimum.f32(float %x, float %y)
1033 %b = call float @llvm.minimum.f32(float %a, float %y)
1039 define float @minimum_z_minimum_x_y(float %x, float %y, float %z) {
1040 ; CHECK-LABEL: @minimum_z_minimum_x_y(
1041 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1042 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[A]])
1043 ; CHECK-NEXT: ret float [[B]]
1045 %a = call float @llvm.minimum.f32(float %x, float %y)
1046 %b = call float @llvm.minimum.f32(float %z, float %a)
1052 define float @minimum_x_y_minimum_z(float %x, float %y, float %z) {
1053 ; CHECK-LABEL: @minimum_x_y_minimum_z(
1054 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
1055 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[Z:%.*]])
1056 ; CHECK-NEXT: ret float [[B]]
1058 %a = call float @llvm.minimum.f32(float %x, float %y)
1059 %b = call float @llvm.minimum.f32(float %a, float %z)
1063 ; minimum(X, -INF) --> -INF
1065 define float @minimum_neginf(float %x) {
1066 ; CHECK-LABEL: @minimum_neginf(
1067 ; CHECK-NEXT: ret float 0xFFF0000000000000
1069 %val = call float @llvm.minimum.f32(float %x, float 0xFFF0000000000000)
1073 define <2 x double> @minimum_neginf_commute_vec(<2 x double> %x) {
1074 ; CHECK-LABEL: @minimum_neginf_commute_vec(
1075 ; CHECK-NEXT: ret <2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>
1077 %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double 0xFFF0000000000000, double 0xFFF0000000000000>, <2 x double> %x)
1083 define float @minimum_inf(float %x) {
1084 ; CHECK-LABEL: @minimum_inf(
1085 ; CHECK-NEXT: [[VAL:%.*]] = call float @llvm.minimum.f32(float 0x7FF0000000000000, float [[X:%.*]])
1086 ; CHECK-NEXT: ret float [[VAL]]
1088 %val = call float @llvm.minimum.f32(float 0x7FF0000000000000, float %x)
1091 define float @maximum_x_maximum_x_y(float %x, float %y) {
1092 ; CHECK-LABEL: @maximum_x_maximum_x_y(
1093 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1094 ; CHECK-NEXT: ret float [[A]]
1096 %a = call float @llvm.maximum.f32(float %x, float %y)
1097 %b = call float @llvm.maximum.f32(float %x, float %a)
1101 define float @maximum_y_maximum_x_y(float %x, float %y) {
1102 ; CHECK-LABEL: @maximum_y_maximum_x_y(
1103 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1104 ; CHECK-NEXT: ret float [[A]]
1106 %a = call float @llvm.maximum.f32(float %x, float %y)
1107 %b = call float @llvm.maximum.f32(float %y, float %a)
1111 define float @maximum_x_y_maximum_x(float %x, float %y) {
1112 ; CHECK-LABEL: @maximum_x_y_maximum_x(
1113 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1114 ; CHECK-NEXT: ret float [[A]]
1116 %a = call float @llvm.maximum.f32(float %x, float %y)
1117 %b = call float @llvm.maximum.f32(float %a, float %x)
1121 define float @maximum_x_y_maximum_y(float %x, float %y) {
1122 ; CHECK-LABEL: @maximum_x_y_maximum_y(
1123 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1124 ; CHECK-NEXT: ret float [[A]]
1126 %a = call float @llvm.maximum.f32(float %x, float %y)
1127 %b = call float @llvm.maximum.f32(float %a, float %y)
1133 define float @maximum_z_maximum_x_y(float %x, float %y, float %z) {
1134 ; CHECK-LABEL: @maximum_z_maximum_x_y(
1135 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1136 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[A]])
1137 ; CHECK-NEXT: ret float [[B]]
1139 %a = call float @llvm.maximum.f32(float %x, float %y)
1140 %b = call float @llvm.maximum.f32(float %z, float %a)
1146 define float @maximum_x_y_maximum_z(float %x, float %y, float %z) {
1147 ; CHECK-LABEL: @maximum_x_y_maximum_z(
1148 ; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
1149 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[Z:%.*]])
1150 ; CHECK-NEXT: ret float [[B]]
1152 %a = call float @llvm.maximum.f32(float %x, float %y)
1153 %b = call float @llvm.maximum.f32(float %a, float %z)
1157 ; maximum(X, INF) --> INF
1159 define <2 x double> @maximum_inf(<2 x double> %x) {
1160 ; CHECK-LABEL: @maximum_inf(
1161 ; CHECK-NEXT: ret <2 x double> <double 0x7FF0000000000000, double 0x7FF0000000000000>
1163 %val = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double><double 0x7FF0000000000000, double 0x7FF0000000000000>)
1164 ret <2 x double> %val
1167 define float @maximum_inf_commute(float %x) {
1168 ; CHECK-LABEL: @maximum_inf_commute(
1169 ; CHECK-NEXT: ret float 0x7FF0000000000000
1171 %val = call float @llvm.maximum.f32(float 0x7FF0000000000000, float %x)
1177 define float @fsub_fsub_common_op(float %x, float %y) {
1178 ; CHECK-LABEL: @fsub_fsub_common_op(
1179 ; CHECK-NEXT: ret float [[X:%.*]]
1181 %s = fsub float %y, %x
1182 %r = fsub reassoc nsz float %y, %s
1186 define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
1187 ; CHECK-LABEL: @fsub_fsub_common_op_vec(
1188 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
1190 %s = fsub <2 x float> %y, %x
1191 %r = fsub reassoc nsz <2 x float> %y, %s
1195 ; Negative test - fsub is not commutative.
1196 ; Y - (X - Y) --> (Y - X) + Y (canonicalized)
1198 define float @fsub_fsub_wrong_common_op(float %x, float %y) {
1199 ; CHECK-LABEL: @fsub_fsub_wrong_common_op(
1200 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1201 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
1202 ; CHECK-NEXT: ret float [[R]]
1204 %s = fsub float %x, %y
1205 %r = fsub reassoc nsz float %y, %s
1209 ; Negative test - negated operand needed.
1210 ; (Y - X) - Y --> -X
1212 define float @fsub_fsub_common_op_wrong_commute(float %x, float %y) {
1213 ; CHECK-LABEL: @fsub_fsub_common_op_wrong_commute(
1214 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1215 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
1216 ; CHECK-NEXT: ret float [[R]]
1218 %s = fsub float %y, %x
1219 %r = fsub reassoc nsz float %s, %y
1223 ; Negative test - fsub is not commutative.
1226 define float @fsub_fsub_wrong_common_op_wrong_commute(float %x, float %y) {
1227 ; CHECK-LABEL: @fsub_fsub_wrong_common_op_wrong_commute(
1228 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1229 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
1230 ; CHECK-NEXT: ret float [[R]]
1232 %s = fsub float %x, %y
1233 %r = fsub reassoc nsz float %s, %y
1239 define float @fadd_fsub_common_op(float %x, float %y) {
1240 ; CHECK-LABEL: @fadd_fsub_common_op(
1241 ; CHECK-NEXT: ret float [[X:%.*]]
1243 %a = fadd float %y, %x
1244 %r = fsub reassoc nsz float %a, %y
1250 define <2 x float> @fadd_fsub_common_op_commute_vec(<2 x float> %x, <2 x float> %y) {
1251 ; CHECK-LABEL: @fadd_fsub_common_op_commute_vec(
1252 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
1254 %a = fadd <2 x float> %x, %y
1255 %r = fsub reassoc nsz <2 x float> %a, %y
1259 ; Negative test - negated operand needed.
1260 ; Y - (Y + X) --> -X
1262 define float @fadd_fsub_common_op_wrong_commute(float %x, float %y) {
1263 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute(
1264 ; CHECK-NEXT: [[A:%.*]] = fadd float [[Y:%.*]], [[X:%.*]]
1265 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
1266 ; CHECK-NEXT: ret float [[R]]
1268 %a = fadd float %y, %x
1269 %r = fsub reassoc nsz float %y, %a
1273 ; Negative test - negated operand needed.
1274 ; Y - (X + Y) --> -X
1276 define float @fadd_fsub_common_op_wrong_commute_commute(float %x, float %y) {
1277 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute_commute(
1278 ; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], [[Y:%.*]]
1279 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
1280 ; CHECK-NEXT: ret float [[R]]
1282 %a = fadd float %x, %y
1283 %r = fsub reassoc nsz float %y, %a
1289 define <2 x float> @fsub_fadd_common_op_vec(<2 x float> %x, <2 x float> %y) {
1290 ; CHECK-LABEL: @fsub_fadd_common_op_vec(
1291 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
1293 %s = fsub <2 x float> %x, %y
1294 %r = fadd reassoc nsz <2 x float> %y, %s
1300 define float @fsub_fadd_common_op_commute(float %x, float %y) {
1301 ; CHECK-LABEL: @fsub_fadd_common_op_commute(
1302 ; CHECK-NEXT: ret float [[X:%.*]]
1304 %s = fsub float %x, %y
1305 %r = fadd reassoc nsz float %s, %y
1312 define float @fsub_fadd_common_op_wrong_commute(float %x, float %y) {
1313 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute(
1314 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1315 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[Y]], [[S]]
1316 ; CHECK-NEXT: ret float [[R]]
1318 %s = fsub float %y, %x
1319 %r = fadd reassoc nsz float %y, %s
1326 define float @fsub_fadd_common_op_wrong_commute_commute(float %x, float %y) {
1327 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute_commute(
1328 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
1329 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[S]], [[Y]]
1330 ; CHECK-NEXT: ret float [[R]]
1332 %s = fsub float %y, %x
1333 %r = fadd reassoc nsz float %s, %y