[RISCV] Rename a lambda to have plural nouns to reflect that it contains a loop. NFC
[llvm-project.git] / llvm / test / Transforms / Reassociate / fast-basictest.ll
blobc1842d0cde456c88589020b052581b795429d356
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
3 ; Test numbering remains continuous across:
4 ; - InstCombine/fast-basictest.ll
5 ; - PhaseOrdering/fast-basictest.ll
6 ; - PhaseOrdering/fast-reassociate-gvn.ll
7 ; - Reassociate/fast-basictest.ll
9 ; RUN: opt < %s -passes=reassociate -S | FileCheck %s
11 ; ((a + (-3)) + b) + 3 -> a + b
12 ; That only works with both instcombine and reassociate passes enabled.
13 ; Check that reassociate is not enough.
15 ; TODO: check if we can eliminate zero add.
16 define float @test2(float %reg109, float %reg1111) {
17 ; CHECK-LABEL: @test2(
18 ; CHECK-NEXT:    [[REG116:%.*]] = fadd fast float [[REG109:%.*]], 0.000000e+00
19 ; CHECK-NEXT:    [[REG117:%.*]] = fadd fast float [[REG116]], [[REG1111:%.*]]
20 ; CHECK-NEXT:    ret float [[REG117]]
22   %reg115 = fadd fast float %reg109, -3.000000e+01
23   %reg116 = fadd fast float %reg115, %reg1111
24   %reg117 = fadd fast float %reg116, 3.000000e+01
25   ret float %reg117
28 define float @test2_no_FMF(float %reg109, float %reg1111) {
29 ; CHECK-LABEL: @test2_no_FMF(
30 ; CHECK-NEXT:    [[REG115:%.*]] = fadd float [[REG109:%.*]], -3.000000e+01
31 ; CHECK-NEXT:    [[REG116:%.*]] = fadd float [[REG115]], [[REG1111:%.*]]
32 ; CHECK-NEXT:    [[REG117:%.*]] = fadd float [[REG116]], 3.000000e+01
33 ; CHECK-NEXT:    ret float [[REG117]]
35   %reg115 = fadd float %reg109, -3.000000e+01
36   %reg116 = fadd float %reg115, %reg1111
37   %reg117 = fadd float %reg116, 3.000000e+01
38   ret float %reg117
41 define float @test2_reassoc(float %reg109, float %reg1111) {
42 ; CHECK-LABEL: @test2_reassoc(
43 ; CHECK-NEXT:    [[REG115:%.*]] = fadd reassoc float [[REG109:%.*]], -3.000000e+01
44 ; CHECK-NEXT:    [[REG116:%.*]] = fadd reassoc float [[REG115]], [[REG1111:%.*]]
45 ; CHECK-NEXT:    [[REG117:%.*]] = fadd reassoc float [[REG116]], 3.000000e+01
46 ; CHECK-NEXT:    ret float [[REG117]]
48   %reg115 = fadd reassoc float %reg109, -3.000000e+01
49   %reg116 = fadd reassoc float %reg115, %reg1111
50   %reg117 = fadd reassoc float %reg116, 3.000000e+01
51   ret float %reg117
54 @fe = external global float
55 @fa = external global float
56 @fb = external global float
57 @fc = external global float
58 @ff = external global float
60 ; If two sums of the same operands in different order are counted with 'fast'
61 ; flag and then stored to global variables, we can reuse the same value twice.
62 ; Sums:
63 ; - test3: (a+b)+c and (a+c)+b
64 ; - test4: c+(a+b) and (c+a)+b
65 ; - test5: c+(b+a) and (c+a)+b
67 ; That only works with both gvn and reassociate passes enabled.
68 ; Check that reassociate is not enough.
70 define void @test3() {
71 ; CHECK-LABEL: @test3(
72 ; CHECK-NEXT:    [[A:%.*]] = load float, ptr @fa, align 4
73 ; CHECK-NEXT:    [[B:%.*]] = load float, ptr @fb, align 4
74 ; CHECK-NEXT:    [[C:%.*]] = load float, ptr @fc, align 4
75 ; CHECK-NEXT:    [[T1:%.*]] = fadd fast float [[B]], [[A]]
76 ; CHECK-NEXT:    [[T2:%.*]] = fadd fast float [[T1]], [[C]]
77 ; CHECK-NEXT:    [[T3:%.*]] = fadd fast float [[B]], [[A]]
78 ; CHECK-NEXT:    [[T4:%.*]] = fadd fast float [[T3]], [[C]]
79 ; CHECK-NEXT:    store float [[T2]], ptr @fe, align 4
80 ; CHECK-NEXT:    store float [[T4]], ptr @ff, align 4
81 ; CHECK-NEXT:    ret void
83   %A = load float, ptr @fa
84   %B = load float, ptr @fb
85   %C = load float, ptr @fc
86   %t1 = fadd fast float %A, %B
87   %t2 = fadd fast float %t1, %C
88   %t3 = fadd fast float %A, %C
89   %t4 = fadd fast float %t3, %B
90   ; e = (a+b)+c;
91   store float %t2, ptr @fe
92   ; f = (a+c)+b
93   store float %t4, ptr @ff
94   ret void
97 define void @test4() {
98 ; CHECK-LABEL: @test4(
99 ; CHECK-NEXT:    [[A:%.*]] = load float, ptr @fa, align 4
100 ; CHECK-NEXT:    [[B:%.*]] = load float, ptr @fb, align 4
101 ; CHECK-NEXT:    [[C:%.*]] = load float, ptr @fc, align 4
102 ; CHECK-NEXT:    [[T1:%.*]] = fadd fast float [[B]], [[A]]
103 ; CHECK-NEXT:    [[T2:%.*]] = fadd fast float [[T1]], [[C]]
104 ; CHECK-NEXT:    [[T3:%.*]] = fadd fast float [[B]], [[A]]
105 ; CHECK-NEXT:    [[T4:%.*]] = fadd fast float [[T3]], [[C]]
106 ; CHECK-NEXT:    store float [[T2]], ptr @fe, align 4
107 ; CHECK-NEXT:    store float [[T4]], ptr @ff, align 4
108 ; CHECK-NEXT:    ret void
110   %A = load float, ptr @fa
111   %B = load float, ptr @fb
112   %C = load float, ptr @fc
113   %t1 = fadd fast float %A, %B
114   %t2 = fadd fast float %C, %t1
115   %t3 = fadd fast float %C, %A
116   %t4 = fadd fast float %t3, %B
117   ; e = c+(a+b)
118   store float %t2, ptr @fe
119   ; f = (c+a)+b
120   store float %t4, ptr @ff
121   ret void
124 define void @test5() {
125 ; CHECK-LABEL: @test5(
126 ; CHECK-NEXT:    [[A:%.*]] = load float, ptr @fa, align 4
127 ; CHECK-NEXT:    [[B:%.*]] = load float, ptr @fb, align 4
128 ; CHECK-NEXT:    [[C:%.*]] = load float, ptr @fc, align 4
129 ; CHECK-NEXT:    [[T1:%.*]] = fadd fast float [[B]], [[A]]
130 ; CHECK-NEXT:    [[T2:%.*]] = fadd fast float [[T1]], [[C]]
131 ; CHECK-NEXT:    [[T3:%.*]] = fadd fast float [[B]], [[A]]
132 ; CHECK-NEXT:    [[T4:%.*]] = fadd fast float [[T3]], [[C]]
133 ; CHECK-NEXT:    store float [[T2]], ptr @fe, align 4
134 ; CHECK-NEXT:    store float [[T4]], ptr @ff, align 4
135 ; CHECK-NEXT:    ret void
137   %A = load float, ptr @fa
138   %B = load float, ptr @fb
139   %C = load float, ptr @fc
140   %t1 = fadd fast float %B, %A
141   %t2 = fadd fast float %C, %t1
142   %t3 = fadd fast float %C, %A
143   %t4 = fadd fast float %t3, %B
144   ; e = c+(b+a)
145   store float %t2, ptr @fe
146   ; f = (c+a)+b
147   store float %t4, ptr @ff
148   ret void
151 define float @test6(float %A, float %B, float %C) {
152 ; CHECK-LABEL: @test6(
153 ; CHECK-NEXT:    [[REASS_ADD1:%.*]] = fadd fast float [[C:%.*]], [[B:%.*]]
154 ; CHECK-NEXT:    [[REASS_MUL2:%.*]] = fmul fast float [[A:%.*]], [[A]]
155 ; CHECK-NEXT:    [[REASS_MUL:%.*]] = fmul fast float [[REASS_MUL2]], [[REASS_ADD1]]
156 ; CHECK-NEXT:    ret float [[REASS_MUL]]
158   %aa = fmul fast float %A, %A
159   %aab = fmul fast float %aa, %B
160   %ac = fmul fast float %A, %C
161   %aac = fmul fast float %ac, %A
162   %r = fadd fast float %aab, %aac
163   ret float %r
166 define float @test6_reassoc(float %A, float %B, float %C) {
167 ; CHECK-LABEL: @test6_reassoc(
168 ; CHECK-NEXT:    [[AA:%.*]] = fmul reassoc float [[A:%.*]], [[A]]
169 ; CHECK-NEXT:    [[AAB:%.*]] = fmul reassoc float [[AA]], [[B:%.*]]
170 ; CHECK-NEXT:    [[AC:%.*]] = fmul reassoc float [[A]], [[C:%.*]]
171 ; CHECK-NEXT:    [[AAC:%.*]] = fmul reassoc float [[A]], [[AC]]
172 ; CHECK-NEXT:    [[R:%.*]] = fadd reassoc float [[AAB]], [[AAC]]
173 ; CHECK-NEXT:    ret float [[R]]
175   %aa = fmul reassoc float %A, %A
176   %aab = fmul reassoc float %aa, %B
177   %ac = fmul reassoc float %A, %C
178   %aac = fmul reassoc float %ac, %A
179   %r = fadd reassoc float %aab, %aac
180   ret float %r
183 ; (-X)*Y + Z -> Z-X*Y
184 define float @test7(float %X, float %Y, float %Z) {
185 ; CHECK-LABEL: @test7(
186 ; CHECK-NEXT:    [[B:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]]
187 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[Z:%.*]], [[B]]
188 ; CHECK-NEXT:    ret float [[TMP1]]
190   %A = fsub fast float 0.0, %X
191   %B = fmul fast float %A, %Y
192   %C = fadd fast float %B, %Z
193   ret float %C
196 define float @test7_unary_fneg(float %X, float %Y, float %Z) {
197 ; CHECK-LABEL: @test7_unary_fneg(
198 ; CHECK-NEXT:    [[B:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]]
199 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[Z:%.*]], [[B]]
200 ; CHECK-NEXT:    ret float [[TMP1]]
202   %A = fneg fast float %X
203   %B = fmul fast float %A, %Y
204   %C = fadd fast float %B, %Z
205   ret float %C
208 define float @test7_reassoc_nsz(float %X, float %Y, float %Z) {
209 ; CHECK-LABEL: @test7_reassoc_nsz(
210 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc nsz float [[Y:%.*]], [[X:%.*]]
211 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[B]]
212 ; CHECK-NEXT:    ret float [[TMP1]]
214   %A = fsub reassoc nsz float 0.0, %X
215   %B = fmul reassoc nsz float %A, %Y
216   %C = fadd reassoc nsz float %B, %Z
217   ret float %C
220 ; Verify that fold is not done only with 'reassoc' ('nsz' is required)
221 define float @test7_reassoc(float %X, float %Y, float %Z) {
222 ; CHECK-LABEL: @test7_reassoc(
223 ; CHECK-NEXT:    [[A:%.*]] = fsub reassoc float 0.000000e+00, [[X:%.*]]
224 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc float [[A]], [[Y:%.*]]
225 ; CHECK-NEXT:    [[C:%.*]] = fadd reassoc float [[B]], [[Z:%.*]]
226 ; CHECK-NEXT:    ret float [[C]]
228   %A = fsub reassoc float 0.0, %X
229   %B = fmul reassoc float %A, %Y
230   %C = fadd reassoc float %B, %Z
231   ret float %C
234 ; Integer version of:
235 ;   (-X)*Y + Z -> Z-X*Y
236 ; TODO: check if we can change the mul of -1 and the add to a sub.
237 define i32 @test7_int(i32 %X, i32 %Y, i32 %Z) {
238 ; CHECK-LABEL: @test7_int(
239 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]
240 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[A]], -1
241 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[B]], [[Z:%.*]]
242 ; CHECK-NEXT:    ret i32 [[C]]
244   %A = sub i32 0, %X
245   %B = mul i32 %A, %Y
246   %C = add i32 %B, %Z
247   ret i32 %C
250 define float @test8(float %X) {
251 ; CHECK-LABEL: @test8(
252 ; CHECK-NEXT:    [[FACTOR:%.*]] = fmul fast float [[X:%.*]], 9.400000e+01
253 ; CHECK-NEXT:    ret float [[FACTOR]]
255   %Y = fmul fast float %X, 4.700000e+01
256   %Z = fadd fast float %Y, %Y
257   ret float %Z
260 ; Side note: (x + x + x) and (3*x) each have only a single rounding.  So
261 ; transforming x+x+x to 3*x is always safe, even without any FMF.
262 ; To avoid that special-case, we have the addition of 'x' four times, here.
263 define float @test9(float %X) {
264 ; CHECK-LABEL: @test9(
265 ; CHECK-NEXT:    [[FACTOR:%.*]] = fmul fast float [[X:%.*]], 4.000000e+00
266 ; CHECK-NEXT:    ret float [[FACTOR]]
268   %Y = fadd fast float %X ,%X
269   %Z = fadd fast float %Y, %X
270   %W = fadd fast float %Z, %X
271   ret float %W
274 define float @test10(float %W) {
275 ; CHECK-LABEL: @test10(
276 ; CHECK-NEXT:    [[FACTOR:%.*]] = fmul fast float [[W:%.*]], 3.810000e+02
277 ; CHECK-NEXT:    ret float [[FACTOR]]
279   %X = fmul fast float %W, 127.0
280   %Y = fadd fast float %X ,%X
281   %Z = fadd fast float %Y, %X
282   ret float %Z
285 define float @test11(float %X) {
286 ; CHECK-LABEL: @test11(
287 ; CHECK-NEXT:    [[FACTOR:%.*]] = fmul fast float [[X:%.*]], -3.000000e+00
288 ; CHECK-NEXT:    [[Z:%.*]] = fadd fast float [[FACTOR]], 6.000000e+00
289 ; CHECK-NEXT:    ret float [[Z]]
291   %A = fsub fast float 1.000000e+00, %X
292   %B = fsub fast float 2.000000e+00, %X
293   %C = fsub fast float 3.000000e+00, %X
294   %Y = fadd fast float %A ,%B
295   %Z = fadd fast float %Y, %C
296   ret float %Z
299 define float @test12(float %X1, float %X2, float %X3) {
300 ; CHECK-LABEL: @test12(
301 ; CHECK-NEXT:    [[B:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]]
302 ; CHECK-NEXT:    [[C:%.*]] = fmul fast float [[X3:%.*]], [[X1]]
303 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[C]], [[B]]
304 ; CHECK-NEXT:    ret float [[TMP1]]
306   %A = fsub fast float 0.000000e+00, %X1
307   %B = fmul fast float %A, %X2   ; -X1*X2
308   %C = fmul fast float %X1, %X3  ; X1*X3
309   %D = fadd fast float %B, %C    ; -X1*X2 + X1*X3 -> X1*(X3-X2)
310   ret float %D
313 define float @test12_unary_fneg(float %X1, float %X2, float %X3) {
314 ; CHECK-LABEL: @test12_unary_fneg(
315 ; CHECK-NEXT:    [[B:%.*]] = fmul fast float [[X2:%.*]], [[X1:%.*]]
316 ; CHECK-NEXT:    [[C:%.*]] = fmul fast float [[X3:%.*]], [[X1]]
317 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[C]], [[B]]
318 ; CHECK-NEXT:    ret float [[TMP1]]
320   %A = fneg fast float %X1
321   %B = fmul fast float %A, %X2   ; -X1*X2
322   %C = fmul fast float %X1, %X3  ; X1*X3
323   %D = fadd fast float %B, %C    ; -X1*X2 + X1*X3 -> X1*(X3-X2)
324   ret float %D
327 define float @test12_reassoc_nsz(float %X1, float %X2, float %X3) {
328 ; CHECK-LABEL: @test12_reassoc_nsz(
329 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc nsz float [[X2:%.*]], [[X1:%.*]]
330 ; CHECK-NEXT:    [[C:%.*]] = fmul reassoc nsz float [[X3:%.*]], [[X1]]
331 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[C]], [[B]]
332 ; CHECK-NEXT:    ret float [[TMP1]]
334   %A = fsub reassoc nsz float 0.000000e+00, %X1
335   %B = fmul reassoc nsz float %A, %X2   ; -X1*X2
336   %C = fmul reassoc nsz float %X1, %X3  ; X1*X3
337   %D = fadd reassoc nsz float %B, %C    ; -X1*X2 + X1*X3 -> X1*(X3-X2)
338   ret float %D
341 ; TODO: check if 'nsz' is technically required. Currently the optimization
342 ; is not done with only 'reassoc' without 'nsz'.
343 define float @test12_reassoc(float %X1, float %X2, float %X3) {
344 ; CHECK-LABEL: @test12_reassoc(
345 ; CHECK-NEXT:    [[A:%.*]] = fsub reassoc float 0.000000e+00, [[X1:%.*]]
346 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc float [[A]], [[X2:%.*]]
347 ; CHECK-NEXT:    [[C:%.*]] = fmul reassoc float [[X1]], [[X3:%.*]]
348 ; CHECK-NEXT:    [[D:%.*]] = fadd reassoc float [[B]], [[C]]
349 ; CHECK-NEXT:    ret float [[D]]
351   %A = fsub reassoc float 0.000000e+00, %X1
352   %B = fmul reassoc float %A, %X2   ; -X1*X2
353   %C = fmul reassoc float %X1, %X3  ; X1*X3
354   %D = fadd reassoc float %B, %C    ; -X1*X2 + X1*X3 -> X1*(X3-X2)
355   ret float %D
358 ; (x1 * 47) + (x2 * -47) => (x1 - x2) * 47
359 ; That only works with both instcombine and reassociate passes enabled.
360 ; Check that reassociate is not enough.
362 define float @test13(float %X1, float %X2) {
363 ; CHECK-LABEL: @test13(
364 ; CHECK-NEXT:    [[B:%.*]] = fmul fast float [[X1:%.*]], 4.700000e+01
365 ; CHECK-NEXT:    [[C:%.*]] = fmul fast float [[X2:%.*]], 4.700000e+01
366 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[B]], [[C]]
367 ; CHECK-NEXT:    ret float [[TMP1]]
369   %B = fmul fast float %X1, 47.   ; X1*47
370   %C = fmul fast float %X2, -47.  ; X2*-47
371   %D = fadd fast float %B, %C     ; X1*47 + X2*-47 -> 47*(X1-X2)
372   ret float %D
375 define float @test13_reassoc_nsz(float %X1, float %X2) {
376 ; CHECK-LABEL: @test13_reassoc_nsz(
377 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc nsz float [[X1:%.*]], 4.700000e+01
378 ; CHECK-NEXT:    [[C:%.*]] = fmul reassoc nsz float [[X2:%.*]], 4.700000e+01
379 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[B]], [[C]]
380 ; CHECK-NEXT:    ret float [[TMP1]]
382   %B = fmul reassoc nsz float %X1, 47.   ; X1*47
383   %C = fmul reassoc nsz float %X2, -47.  ; X2*-47
384   %D = fadd reassoc nsz float %B, %C     ; X1*47 + X2*-47 -> 47*(X1-X2)
385   ret float %D
388 define float @test13_reassoc(float %X1, float %X2) {
389 ; CHECK-LABEL: @test13_reassoc(
390 ; CHECK-NEXT:    [[B:%.*]] = fmul reassoc float [[X1:%.*]], 4.700000e+01
391 ; CHECK-NEXT:    [[C:%.*]] = fmul reassoc float [[X2:%.*]], 4.700000e+01
392 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc float [[B]], [[C]]
393 ; CHECK-NEXT:    ret float [[TMP1]]
395   %B = fmul reassoc float %X1, 47.   ; X1*47
396   %C = fmul reassoc float %X2, -47.  ; X2*-47
397   %D = fadd reassoc float %B, %C     ; X1*47 + X2*-47 -> 47*(X1-X2)
398   ret float %D
401 define float @test14(float %arg) {
402 ; CHECK-LABEL: @test14(
403 ; CHECK-NEXT:    [[T2:%.*]] = fmul fast float [[ARG:%.*]], 1.440000e+02
404 ; CHECK-NEXT:    ret float [[T2]]
406   %t1 = fmul fast float 1.200000e+01, %arg
407   %t2 = fmul fast float %t1, 1.200000e+01
408   ret float %t2
411 ; TODO: check if we can transform the code with 'reassoc' only.
412 ; The same IR is transformed to one fmul in instcombine pass.
413 define float @test14_reassoc(float %arg) {
414 ; CHECK-LABEL: @test14_reassoc(
415 ; CHECK-NEXT:    [[T1:%.*]] = fmul reassoc float [[ARG:%.*]], 1.200000e+01
416 ; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc float [[T1]], 1.200000e+01
417 ; CHECK-NEXT:    ret float [[T2]]
419   %t1 = fmul reassoc float 1.200000e+01, %arg
420   %t2 = fmul reassoc float %t1, 1.200000e+01
421   ret float %t2
424 ; (b+(a+1234))+-a -> b+1234
425 ; That only works with both instcombine and reassociate passes enabled.
426 ; Check that reassociate is not enough.
428 ; TODO: check if we can remove dead fsub.
429 define float @test15(float %b, float %a) {
430 ; CHECK-LABEL: @test15(
431 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float 0.000000e+00, [[A:%.*]]
432 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd fast float [[B:%.*]], 1.234000e+03
433 ; CHECK-NEXT:    ret float [[TMP2]]
435   %1 = fadd fast float %a, 1234.0
436   %2 = fadd fast float %b, %1
437   %3 = fsub fast float 0.0, %a
438   %4 = fadd fast float %2, %3
439   ret float %4
442 ; TODO: check if we can remove dead fneg.
443 define float @test15_unary_fneg(float %b, float %a) {
444 ; CHECK-LABEL: @test15_unary_fneg(
445 ; CHECK-NEXT:    [[TMP1:%.*]] = fneg fast float [[A:%.*]]
446 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd fast float [[B:%.*]], 1.234000e+03
447 ; CHECK-NEXT:    ret float [[TMP2]]
449   %1 = fadd fast float %a, 1234.0
450   %2 = fadd fast float %b, %1
451   %3 = fneg fast float %a
452   %4 = fadd fast float %2, %3
453   ret float %4
456 ; TODO: check if we can remove dead fsub.
457 define float @test15_reassoc_nsz(float %b, float %a) {
458 ; CHECK-LABEL: @test15_reassoc_nsz(
459 ; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float 0.000000e+00, [[A:%.*]]
460 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc nsz float [[B:%.*]], 1.234000e+03
461 ; CHECK-NEXT:    ret float [[TMP2]]
463   %1 = fadd reassoc nsz float %a, 1234.0
464   %2 = fadd reassoc nsz float %b, %1
465   %3 = fsub reassoc nsz float 0.0, %a
466   %4 = fadd reassoc nsz float %2, %3
467   ret float %4
470 define float @test15_reassoc(float %b, float %a) {
471 ; CHECK-LABEL: @test15_reassoc(
472 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc float [[A:%.*]], 1.234000e+03
473 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc float [[B:%.*]], [[TMP1]]
474 ; CHECK-NEXT:    [[TMP3:%.*]] = fsub reassoc float 0.000000e+00, [[A]]
475 ; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc float [[TMP3]], [[TMP2]]
476 ; CHECK-NEXT:    ret float [[TMP4]]
478   %1 = fadd reassoc float %a, 1234.0
479   %2 = fadd reassoc float %b, %1
480   %3 = fsub reassoc float 0.0, %a
481   %4 = fadd reassoc float %2, %3
482   ret float %4
485 ; Test that we can turn things like X*-(Y*Z) -> X*-1*Y*Z.
486 ; That only works with both instcombine and reassociate passes enabled.
487 ; Check that reassociate is not enough.
489 define float @test16(float %a, float %b, float %z) {
490 ; CHECK-LABEL: @test16(
491 ; CHECK-NEXT:    [[C:%.*]] = fmul fast float [[A:%.*]], 1.234500e+04
492 ; CHECK-NEXT:    [[E:%.*]] = fmul fast float [[C]], [[B:%.*]]
493 ; CHECK-NEXT:    [[F:%.*]] = fmul fast float [[E]], [[Z:%.*]]
494 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast float [[F]], 0.000000e+00
495 ; CHECK-NEXT:    ret float [[TMP1]]
497   %c = fsub fast float 0.000000e+00, %z
498   %d = fmul fast float %a, %b
499   %e = fmul fast float %c, %d
500   %f = fmul fast float %e, 1.234500e+04
501   %g = fsub fast float 0.000000e+00, %f
502   ret float %g
505 define float @test16_unary_fneg(float %a, float %b, float %z) {
506 ; CHECK-LABEL: @test16_unary_fneg(
507 ; CHECK-NEXT:    [[E:%.*]] = fmul fast float [[A:%.*]], 1.234500e+04
508 ; CHECK-NEXT:    [[F:%.*]] = fmul fast float [[E]], [[B:%.*]]
509 ; CHECK-NEXT:    [[G:%.*]] = fmul fast float [[F]], [[Z:%.*]]
510 ; CHECK-NEXT:    ret float [[G]]
512   %c = fneg fast float %z
513   %d = fmul fast float %a, %b
514   %e = fmul fast float %c, %d
515   %f = fmul fast float %e, 1.234500e+04
516   %g = fneg fast float %f
517   ret float %g
520 define float @test16_reassoc(float %a, float %b, float %z) {
521 ; CHECK-LABEL: @test16_reassoc(
522 ; CHECK-NEXT:    [[C:%.*]] = fsub reassoc float 0.000000e+00, [[Z:%.*]]
523 ; CHECK-NEXT:    [[D:%.*]] = fmul reassoc float [[A:%.*]], [[B:%.*]]
524 ; CHECK-NEXT:    [[E:%.*]] = fmul reassoc float [[D]], [[C]]
525 ; CHECK-NEXT:    [[F:%.*]] = fmul reassoc float [[E]], 1.234500e+04
526 ; CHECK-NEXT:    [[G:%.*]] = fsub reassoc float 0.000000e+00, [[F]]
527 ; CHECK-NEXT:    ret float [[G]]
529   %c = fsub reassoc float 0.000000e+00, %z
530   %d = fmul reassoc float %a, %b
531   %e = fmul reassoc float %c, %d
532   %f = fmul reassoc float %e, 1.234500e+04
533   %g = fsub reassoc float 0.000000e+00, %f
534   ret float %g
537 ; TODO: check if we can remove:
538 ; - fadd fast x, 0
539 ; ... as 'fast' implies 'nsz'
540 define float @test17(float %a, float %b, float %z) {
541 ; CHECK-LABEL: @test17(
542 ; CHECK-NEXT:    [[C:%.*]] = fmul fast float [[A:%.*]], 4.000000e+01
543 ; CHECK-NEXT:    [[E:%.*]] = fmul fast float [[C]], [[Z:%.*]]
544 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast float [[E]], 0.000000e+00
545 ; CHECK-NEXT:    ret float [[TMP1]]
547   %d = fmul fast float %z, 4.000000e+01
548   %c = fsub fast float 0.000000e+00, %d
549   %e = fmul fast float %a, %c
550   %f = fsub fast float 0.000000e+00, %e
551   ret float %f
554 define float @test17_unary_fneg(float %a, float %b, float %z) {
555 ; CHECK-LABEL: @test17_unary_fneg(
556 ; CHECK-NEXT:    [[E:%.*]] = fmul fast float [[A:%.*]], 4.000000e+01
557 ; CHECK-NEXT:    [[F:%.*]] = fmul fast float [[E]], [[Z:%.*]]
558 ; CHECK-NEXT:    ret float [[F]]
560   %d = fmul fast float %z, 4.000000e+01
561   %c = fneg fast float %d
562   %e = fmul fast float %a, %c
563   %f = fneg fast float %e
564   ret float %f
567 ; With sub reassociation, constant folding can eliminate the 12 and -12 constants.
568 ; TODO: check if we can remove fadd fast x, 0 as 'fast' implies 'nsz'
569 define float @test18(float %A, float %B) {
570 ; CHECK-LABEL: @test18(
571 ; CHECK-NEXT:    [[B_NEG:%.*]] = fneg fast float [[B:%.*]]
572 ; CHECK-NEXT:    [[Y:%.*]] = fadd fast float [[A:%.*]], 0.000000e+00
573 ; CHECK-NEXT:    [[Z:%.*]] = fadd fast float [[Y]], [[B_NEG]]
574 ; CHECK-NEXT:    ret float [[Z]]
576   %X = fadd fast float -1.200000e+01, %A
577   %Y = fsub fast float %X, %B
578   %Z = fadd fast float %Y, 1.200000e+01
579   ret float %Z