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)
226 declare float @llvm.maxnum.f32(float, float)
228 define float @fabs_select_positive_constants(i32 %c) {
229 ; CHECK-LABEL: @fabs_select_positive_constants(
230 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
231 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float 2.000000e+00
232 ; CHECK-NEXT: ret float [[SELECT]]
234 %cmp = icmp eq i32 %c, 0
235 %select = select i1 %cmp, float 1.0, float 2.0
236 %fabs = call float @llvm.fabs.f32(float %select)
240 define <2 x float> @fabs_select_positive_constants_vector(i32 %c) {
241 ; CHECK-LABEL: @fabs_select_positive_constants_vector(
242 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
243 ; 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>
244 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
246 %cmp = icmp eq i32 %c, 0
247 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
248 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
249 ret <2 x float> %fabs
252 define float @fabs_select_constant_variable(i32 %c, float %x) {
253 ; CHECK-LABEL: @fabs_select_constant_variable(
254 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
255 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 1.000000e+00, float [[X:%.*]]
256 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
257 ; CHECK-NEXT: ret float [[FABS]]
259 %cmp = icmp eq i32 %c, 0
260 %select = select i1 %cmp, float 1.0, float %x
261 %fabs = call float @llvm.fabs.f32(float %select)
265 define <2 x float> @fabs_select_constant_variable_vector(i32 %c, <2 x float> %x) {
266 ; CHECK-LABEL: @fabs_select_constant_variable_vector(
267 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
268 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]]
269 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
270 ; CHECK-NEXT: ret <2 x float> [[FABS]]
272 %cmp = icmp eq i32 %c, 0
273 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %x
274 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
275 ret <2 x float> %fabs
278 define float @fabs_select_neg0_pos0(i32 %c) {
279 ; CHECK-LABEL: @fabs_select_neg0_pos0(
280 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
281 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float 0.000000e+00
282 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
283 ; CHECK-NEXT: ret float [[FABS]]
285 %cmp = icmp eq i32 %c, 0
286 %select = select i1 %cmp, float -0.0, float 0.0
287 %fabs = call float @llvm.fabs.f32(float %select)
291 define <2 x float> @fabs_select_neg0_pos0_vector(i32 %c) {
292 ; CHECK-LABEL: @fabs_select_neg0_pos0_vector(
293 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
294 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float -0.000000e+00, float -0.000000e+00>, <2 x float> zeroinitializer
295 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
296 ; CHECK-NEXT: ret <2 x float> [[FABS]]
298 %cmp = icmp eq i32 %c, 0
299 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float 0.0, float 0.0>
300 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
301 ret <2 x float> %fabs
304 define float @fabs_select_neg0_neg1(i32 %c) {
305 ; CHECK-LABEL: @fabs_select_neg0_neg1(
306 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
307 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float -0.000000e+00, float -1.000000e+00
308 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
309 ; CHECK-NEXT: ret float [[FABS]]
311 %cmp = icmp eq i32 %c, 0
312 %select = select i1 %cmp, float -0.0, float -1.0
313 %fabs = call float @llvm.fabs.f32(float %select)
317 define <2 x float> @fabs_select_neg0_neg1_vector(i32 %c) {
318 ; CHECK-LABEL: @fabs_select_neg0_neg1_vector(
319 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
320 ; 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>
321 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
322 ; CHECK-NEXT: ret <2 x float> [[FABS]]
324 %cmp = icmp eq i32 %c, 0
325 %select = select i1 %cmp, <2 x float> <float -0.0, float -0.0>, <2 x float> <float -1.0, float -1.0>
326 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
327 ret <2 x float> %fabs
330 define float @fabs_select_nan_nan(i32 %c) {
331 ; CHECK-LABEL: @fabs_select_nan_nan(
332 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
333 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0x7FF8000000000000, float 0x7FF8000100000000
334 ; CHECK-NEXT: ret float [[SELECT]]
336 %cmp = icmp eq i32 %c, 0
337 %select = select i1 %cmp, float 0x7FF8000000000000, float 0x7FF8000100000000
338 %fabs = call float @llvm.fabs.f32(float %select)
342 define <2 x float> @fabs_select_nan_nan_vector(i32 %c) {
343 ; CHECK-LABEL: @fabs_select_nan_nan_vector(
344 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
345 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
346 ; CHECK-NEXT: ret <2 x float> [[SELECT]]
348 %cmp = icmp eq i32 %c, 0
349 %select = select i1 %cmp, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
350 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
351 ret <2 x float> %fabs
354 define float @fabs_select_negnan_nan(i32 %c) {
355 ; CHECK-LABEL: @fabs_select_negnan_nan(
356 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
357 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000000000000
358 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
359 ; CHECK-NEXT: ret float [[FABS]]
361 %cmp = icmp eq i32 %c, 0
362 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000000000000
363 %fabs = call float @llvm.fabs.f32(float %select)
367 define <2 x float> @fabs_select_negnan_nan_vector(i32 %c) {
368 ; CHECK-LABEL: @fabs_select_negnan_nan_vector(
369 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
370 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
371 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
372 ; CHECK-NEXT: ret <2 x float> [[FABS]]
374 %cmp = icmp eq i32 %c, 0
375 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>
376 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
377 ret <2 x float> %fabs
380 define float @fabs_select_negnan_negnan(i32 %c) {
381 ; CHECK-LABEL: @fabs_select_negnan_negnan(
382 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
383 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0x7FF8000100000000
384 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
385 ; CHECK-NEXT: ret float [[FABS]]
387 %cmp = icmp eq i32 %c, 0
388 %select = select i1 %cmp, float 0xFFF8000000000000, float 0x7FF8000100000000
389 %fabs = call float @llvm.fabs.f32(float %select)
393 define <2 x float> @fabs_select_negnan_negnan_vector(i32 %c) {
394 ; CHECK-LABEL: @fabs_select_negnan_negnan_vector(
395 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
396 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
397 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
398 ; CHECK-NEXT: ret <2 x float> [[FABS]]
400 %cmp = icmp eq i32 %c, 0
401 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0x7FF8000100000000, float 0x7FF8000100000000>
402 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
403 ret <2 x float> %fabs
406 define float @fabs_select_negnan_negzero(i32 %c) {
407 ; CHECK-LABEL: @fabs_select_negnan_negzero(
408 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
409 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float -0.000000e+00
410 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
411 ; CHECK-NEXT: ret float [[FABS]]
413 %cmp = icmp eq i32 %c, 0
414 %select = select i1 %cmp, float 0xFFF8000000000000, float -0.0
415 %fabs = call float @llvm.fabs.f32(float %select)
419 define <2 x float> @fabs_select_negnan_negzero_vector(i32 %c) {
420 ; CHECK-LABEL: @fabs_select_negnan_negzero_vector(
421 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
422 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.000000e+00, float -0.000000e+00>
423 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
424 ; CHECK-NEXT: ret <2 x float> [[FABS]]
426 %cmp = icmp eq i32 %c, 0
427 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float -0.0, float -0.0>
428 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
429 ret <2 x float> %fabs
432 define float @fabs_select_negnan_zero(i32 %c) {
433 ; CHECK-LABEL: @fabs_select_negnan_zero(
434 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
435 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float 0xFFF8000000000000, float 0.000000e+00
436 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
437 ; CHECK-NEXT: ret float [[FABS]]
439 %cmp = icmp eq i32 %c, 0
440 %select = select i1 %cmp, float 0xFFF8000000000000, float 0.0
441 %fabs = call float @llvm.fabs.f32(float %select)
445 define <2 x float> @fabs_select_negnan_zero_vector(i32 %c) {
446 ; CHECK-LABEL: @fabs_select_negnan_zero_vector(
447 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
448 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> zeroinitializer
449 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[SELECT]])
450 ; CHECK-NEXT: ret <2 x float> [[FABS]]
452 %cmp = icmp eq i32 %c, 0
453 %select = select i1 %cmp, <2 x float> <float 0xFFF8000000000000, float 0xFFF8000000000000>, <2 x float> <float 0.0, float 0.0>
454 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %select)
455 ret <2 x float> %fabs
458 ; The fabs can't be eliminated because llvm.sqrt.f32 may return -0 or NaN with
459 ; an arbitrary sign bit.
460 define float @fabs_sqrt(float %a) {
461 ; CHECK-LABEL: @fabs_sqrt(
462 ; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
463 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
464 ; CHECK-NEXT: ret float [[FABS]]
466 %sqrt = call float @llvm.sqrt.f32(float %a)
467 %fabs = call float @llvm.fabs.f32(float %sqrt)
471 ; The fabs can't be eliminated because the nnan sqrt may still return -0.
472 define float @fabs_sqrt_nnan(float %a) {
473 ; CHECK-LABEL: @fabs_sqrt_nnan(
474 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
475 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
476 ; CHECK-NEXT: ret float [[FABS]]
478 %sqrt = call nnan float @llvm.sqrt.f32(float %a)
479 %fabs = call float @llvm.fabs.f32(float %sqrt)
483 ; The fabs can't be eliminated because the nsz sqrt may still return NaN.
484 define float @fabs_sqrt_nsz(float %a) {
485 ; CHECK-LABEL: @fabs_sqrt_nsz(
486 ; CHECK-NEXT: [[SQRT:%.*]] = call nsz float @llvm.sqrt.f32(float [[A:%.*]])
487 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
488 ; CHECK-NEXT: ret float [[FABS]]
490 %sqrt = call nsz float @llvm.sqrt.f32(float %a)
491 %fabs = call float @llvm.fabs.f32(float %sqrt)
495 ; The fabs can be eliminated because we're nsz and nnan.
496 define float @fabs_sqrt_nnan_nsz(float %a) {
497 ; CHECK-LABEL: @fabs_sqrt_nnan_nsz(
498 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[A:%.*]])
499 ; CHECK-NEXT: ret float [[SQRT]]
501 %sqrt = call nnan nsz float @llvm.sqrt.f32(float %a)
502 %fabs = call float @llvm.fabs.f32(float %sqrt)
506 ; The second fabs can be eliminated because the operand to sqrt cannot be -0.
507 define float @fabs_sqrt_nnan_fabs(float %a) {
508 ; CHECK-LABEL: @fabs_sqrt_nnan_fabs(
509 ; CHECK-NEXT: [[B:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
510 ; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float [[B]])
511 ; CHECK-NEXT: ret float [[SQRT]]
513 %b = call float @llvm.fabs.f32(float %a)
514 %sqrt = call nnan float @llvm.sqrt.f32(float %b)
515 %fabs = call float @llvm.fabs.f32(float %sqrt)
519 define float @fabs_select_positive_constants_vector_extract(i32 %c) {
520 ; CHECK-LABEL: @fabs_select_positive_constants_vector_extract(
521 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
522 ; 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>
523 ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <2 x float> [[SELECT]], i32 0
524 ; CHECK-NEXT: ret float [[EXTRACT]]
526 %cmp = icmp eq i32 %c, 0
527 %select = select i1 %cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> <float 2.0, float 2.0>
528 %extract = extractelement <2 x float> %select, i32 0
529 %fabs = call float @llvm.fabs.f32(float %extract)
535 define float @fsub_fsub_common_op(float %x, float %y) {
536 ; CHECK-LABEL: @fsub_fsub_common_op(
537 ; CHECK-NEXT: ret float [[X:%.*]]
539 %s = fsub float %y, %x
540 %r = fsub reassoc nsz float %y, %s
544 define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
545 ; CHECK-LABEL: @fsub_fsub_common_op_vec(
546 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
548 %s = fsub <2 x float> %y, %x
549 %r = fsub reassoc nsz <2 x float> %y, %s
553 ; Negative test - fsub is not commutative.
554 ; Y - (X - Y) --> (Y - X) + Y (canonicalized)
556 define float @fsub_fsub_wrong_common_op(float %x, float %y) {
557 ; CHECK-LABEL: @fsub_fsub_wrong_common_op(
558 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
559 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
560 ; CHECK-NEXT: ret float [[R]]
562 %s = fsub float %x, %y
563 %r = fsub reassoc nsz float %y, %s
567 ; Negative test - negated operand needed.
570 define float @fsub_fsub_common_op_wrong_commute(float %x, float %y) {
571 ; CHECK-LABEL: @fsub_fsub_common_op_wrong_commute(
572 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
573 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
574 ; CHECK-NEXT: ret float [[R]]
576 %s = fsub float %y, %x
577 %r = fsub reassoc nsz float %s, %y
581 ; Negative test - fsub is not commutative.
584 define float @fsub_fsub_wrong_common_op_wrong_commute(float %x, float %y) {
585 ; CHECK-LABEL: @fsub_fsub_wrong_common_op_wrong_commute(
586 ; CHECK-NEXT: [[S:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
587 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[S]], [[Y]]
588 ; CHECK-NEXT: ret float [[R]]
590 %s = fsub float %x, %y
591 %r = fsub reassoc nsz float %s, %y
597 define float @fadd_fsub_common_op(float %x, float %y) {
598 ; CHECK-LABEL: @fadd_fsub_common_op(
599 ; CHECK-NEXT: ret float [[X:%.*]]
601 %a = fadd float %y, %x
602 %r = fsub reassoc nsz float %a, %y
608 define <2 x float> @fadd_fsub_common_op_commute_vec(<2 x float> %x, <2 x float> %y) {
609 ; CHECK-LABEL: @fadd_fsub_common_op_commute_vec(
610 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
612 %a = fadd <2 x float> %x, %y
613 %r = fsub reassoc nsz <2 x float> %a, %y
617 ; Negative test - negated operand needed.
620 define float @fadd_fsub_common_op_wrong_commute(float %x, float %y) {
621 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute(
622 ; CHECK-NEXT: [[A:%.*]] = fadd float [[Y:%.*]], [[X:%.*]]
623 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
624 ; CHECK-NEXT: ret float [[R]]
626 %a = fadd float %y, %x
627 %r = fsub reassoc nsz float %y, %a
631 ; Negative test - negated operand needed.
634 define float @fadd_fsub_common_op_wrong_commute_commute(float %x, float %y) {
635 ; CHECK-LABEL: @fadd_fsub_common_op_wrong_commute_commute(
636 ; CHECK-NEXT: [[A:%.*]] = fadd float [[X:%.*]], [[Y:%.*]]
637 ; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[A]]
638 ; CHECK-NEXT: ret float [[R]]
640 %a = fadd float %x, %y
641 %r = fsub reassoc nsz float %y, %a
647 define <2 x float> @fsub_fadd_common_op_vec(<2 x float> %x, <2 x float> %y) {
648 ; CHECK-LABEL: @fsub_fadd_common_op_vec(
649 ; CHECK-NEXT: ret <2 x float> [[X:%.*]]
651 %s = fsub <2 x float> %x, %y
652 %r = fadd reassoc nsz <2 x float> %y, %s
658 define float @fsub_fadd_common_op_commute(float %x, float %y) {
659 ; CHECK-LABEL: @fsub_fadd_common_op_commute(
660 ; CHECK-NEXT: ret float [[X:%.*]]
662 %s = fsub float %x, %y
663 %r = fadd reassoc nsz float %s, %y
670 define float @fsub_fadd_common_op_wrong_commute(float %x, float %y) {
671 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute(
672 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
673 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[Y]], [[S]]
674 ; CHECK-NEXT: ret float [[R]]
676 %s = fsub float %y, %x
677 %r = fadd reassoc nsz float %y, %s
684 define float @fsub_fadd_common_op_wrong_commute_commute(float %x, float %y) {
685 ; CHECK-LABEL: @fsub_fadd_common_op_wrong_commute_commute(
686 ; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
687 ; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[S]], [[Y]]
688 ; CHECK-NEXT: ret float [[R]]
690 %s = fsub float %y, %x
691 %r = fadd reassoc nsz float %s, %y
695 ; PR46627 - https://bugs.llvm.org/show_bug.cgi?id=46627
697 define float @maxnum_with_poszero_op(float %a) {
698 ; CHECK-LABEL: @maxnum_with_poszero_op(
699 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 0.000000e+00)
700 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
701 ; CHECK-NEXT: ret float [[FABS]]
703 %max = call float @llvm.maxnum.f32(float %a, float 0.0)
704 %fabs = call float @llvm.fabs.f32(float %max)
708 define float @maxnum_with_poszero_op_commute(float %a) {
709 ; CHECK-LABEL: @maxnum_with_poszero_op_commute(
710 ; CHECK-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
711 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float 0.000000e+00, float [[SQRT]])
712 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
713 ; CHECK-NEXT: ret float [[FABS]]
715 %sqrt = call float @llvm.sqrt.f32(float %a)
716 %max = call float @llvm.maxnum.f32(float 0.0, float %sqrt)
717 %fabs = call float @llvm.fabs.f32(float %max)
721 define float @maxnum_with_negzero_op(float %a) {
722 ; CHECK-LABEL: @maxnum_with_negzero_op(
723 ; CHECK-NEXT: [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
724 ; CHECK-NEXT: [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
725 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float -0.000000e+00, float [[FABSA]])
726 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
727 ; CHECK-NEXT: ret float [[FABS]]
729 %nnan = call nnan float @llvm.sqrt.f32(float %a)
730 %fabsa = call float @llvm.fabs.f32(float %nnan)
731 %max = call float @llvm.maxnum.f32(float -0.0, float %fabsa)
732 %fabs = call float @llvm.fabs.f32(float %max)
736 define float @maxnum_with_negzero_op_commute(float %a) {
737 ; CHECK-LABEL: @maxnum_with_negzero_op_commute(
738 ; CHECK-NEXT: [[NNAN:%.*]] = call nnan float @llvm.sqrt.f32(float [[A:%.*]])
739 ; CHECK-NEXT: [[FABSA:%.*]] = call float @llvm.fabs.f32(float [[NNAN]])
740 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[FABSA]], float -0.000000e+00)
741 ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MAX]])
742 ; CHECK-NEXT: ret float [[FABS]]
744 %nnan = call nnan float @llvm.sqrt.f32(float %a)
745 %fabsa = call float @llvm.fabs.f32(float %nnan)
746 %max = call float @llvm.maxnum.f32(float %fabsa, float -0.0)
747 %fabs = call float @llvm.fabs.f32(float %max)
751 ; If an operand is strictly greater than 0.0, we know the sign of the result of maxnum.
753 define float @maxnum_with_pos_one_op(float %a) {
754 ; CHECK-LABEL: @maxnum_with_pos_one_op(
755 ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[A:%.*]], float 1.000000e+00)
756 ; CHECK-NEXT: ret float [[MAX]]
758 %max = call float @llvm.maxnum.f32(float %a, float 1.0)
759 %fabs = call float @llvm.fabs.f32(float %max)