[X86] X86DAGToDAGISel - attempt to merge XMM/YMM loads with YMM/ZMM loads of the...
[llvm-project.git] / llvm / test / CodeGen / PowerPC / fma-combine.ll
blobb39c9327bc8ab2c8f61c4599cc7e86275edad8af
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -enable-no-signed-zeros-fp-math \
3 ; RUN:     -enable-unsafe-fp-math  < %s | FileCheck -check-prefix=CHECK-FAST %s
4 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -enable-no-signed-zeros-fp-math \
5 ; RUN:     -enable-unsafe-fp-math -mattr=-vsx < %s | FileCheck -check-prefix=CHECK-FAST-NOVSX %s
6 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
8 define dso_local double @fma_combine1(double %a, double %b, double %c) {
9 ; CHECK-FAST-LABEL: fma_combine1:
10 ; CHECK-FAST:       # %bb.0: # %entry
11 ; CHECK-FAST-NEXT:    xsnmaddadp 1, 3, 2
12 ; CHECK-FAST-NEXT:    blr
14 ; CHECK-FAST-NOVSX-LABEL: fma_combine1:
15 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
16 ; CHECK-FAST-NOVSX-NEXT:    fnmadd 1, 3, 2, 1
17 ; CHECK-FAST-NOVSX-NEXT:    blr
19 ; CHECK-LABEL: fma_combine1:
20 ; CHECK:       # %bb.0: # %entry
21 ; CHECK-NEXT:    xsnegdp 0, 3
22 ; CHECK-NEXT:    xsmuldp 0, 0, 2
23 ; CHECK-NEXT:    xssubdp 1, 0, 1
24 ; CHECK-NEXT:    blr
25 entry:
26   %fneg1 = fneg double %c
27   %mul = fmul double %fneg1, %b
28   %add = fsub double %mul, %a
29   ret double %add
32 define dso_local double @fma_combine2(double %a, double %b, double %c) {
33 ; CHECK-FAST-LABEL: fma_combine2:
34 ; CHECK-FAST:       # %bb.0: # %entry
35 ; CHECK-FAST-NEXT:    xsnmaddadp 1, 2, 3
36 ; CHECK-FAST-NEXT:    blr
38 ; CHECK-FAST-NOVSX-LABEL: fma_combine2:
39 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
40 ; CHECK-FAST-NOVSX-NEXT:    fnmadd 1, 2, 3, 1
41 ; CHECK-FAST-NOVSX-NEXT:    blr
43 ; CHECK-LABEL: fma_combine2:
44 ; CHECK:       # %bb.0: # %entry
45 ; CHECK-NEXT:    xsnegdp 0, 3
46 ; CHECK-NEXT:    xsmuldp 0, 2, 0
47 ; CHECK-NEXT:    xssubdp 1, 0, 1
48 ; CHECK-NEXT:    blr
49 entry:
50   %fneg1 = fneg double %c
51   %mul = fmul double %b, %fneg1
52   %add = fsub double %mul, %a
53   ret double %add
56 @v = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
57 @z = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
58 define dso_local double @fma_combine_two_uses(double %a, double %b, double %c) {
59 ; CHECK-FAST-LABEL: fma_combine_two_uses:
60 ; CHECK-FAST:       # %bb.0: # %entry
61 ; CHECK-FAST-NEXT:    xsnegdp 0, 1
62 ; CHECK-FAST-NEXT:    addis 3, 2, v@toc@ha
63 ; CHECK-FAST-NEXT:    xsnmaddadp 1, 3, 2
64 ; CHECK-FAST-NEXT:    stfd 0, v@toc@l(3)
65 ; CHECK-FAST-NEXT:    xsnegdp 0, 3
66 ; CHECK-FAST-NEXT:    addis 3, 2, z@toc@ha
67 ; CHECK-FAST-NEXT:    stfd 0, z@toc@l(3)
68 ; CHECK-FAST-NEXT:    blr
70 ; CHECK-FAST-NOVSX-LABEL: fma_combine_two_uses:
71 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
72 ; CHECK-FAST-NOVSX-NEXT:    fneg 0, 1
73 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, v@toc@ha
74 ; CHECK-FAST-NOVSX-NEXT:    fnmadd 1, 3, 2, 1
75 ; CHECK-FAST-NOVSX-NEXT:    stfd 0, v@toc@l(3)
76 ; CHECK-FAST-NOVSX-NEXT:    fneg 0, 3
77 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, z@toc@ha
78 ; CHECK-FAST-NOVSX-NEXT:    stfd 0, z@toc@l(3)
79 ; CHECK-FAST-NOVSX-NEXT:    blr
81 ; CHECK-LABEL: fma_combine_two_uses:
82 ; CHECK:       # %bb.0: # %entry
83 ; CHECK-NEXT:    xsnegdp 0, 1
84 ; CHECK-NEXT:    addis 3, 2, v@toc@ha
85 ; CHECK-NEXT:    stfd 0, v@toc@l(3)
86 ; CHECK-NEXT:    xsnegdp 0, 3
87 ; CHECK-NEXT:    addis 3, 2, z@toc@ha
88 ; CHECK-NEXT:    stfd 0, z@toc@l(3)
89 ; CHECK-NEXT:    xsmuldp 0, 0, 2
90 ; CHECK-NEXT:    xssubdp 1, 0, 1
91 ; CHECK-NEXT:    blr
92 entry:
93   %fneg = fneg double %a
94   store double %fneg, ptr @v, align 8
95   %fneg1 = fneg double %c
96   store double %fneg1, ptr @z, align 8
97   %mul = fmul double %fneg1, %b
98   %add = fsub double %mul, %a
99   ret double %add
102 define dso_local double @fma_combine_one_use(double %a, double %b, double %c) {
103 ; CHECK-FAST-LABEL: fma_combine_one_use:
104 ; CHECK-FAST:       # %bb.0: # %entry
105 ; CHECK-FAST-NEXT:    xsnegdp 0, 1
106 ; CHECK-FAST-NEXT:    xsnmaddadp 1, 3, 2
107 ; CHECK-FAST-NEXT:    addis 3, 2, v@toc@ha
108 ; CHECK-FAST-NEXT:    stfd 0, v@toc@l(3)
109 ; CHECK-FAST-NEXT:    blr
111 ; CHECK-FAST-NOVSX-LABEL: fma_combine_one_use:
112 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
113 ; CHECK-FAST-NOVSX-NEXT:    fneg 0, 1
114 ; CHECK-FAST-NOVSX-NEXT:    fnmadd 1, 3, 2, 1
115 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, v@toc@ha
116 ; CHECK-FAST-NOVSX-NEXT:    stfd 0, v@toc@l(3)
117 ; CHECK-FAST-NOVSX-NEXT:    blr
119 ; CHECK-LABEL: fma_combine_one_use:
120 ; CHECK:       # %bb.0: # %entry
121 ; CHECK-NEXT:    xsnegdp 0, 1
122 ; CHECK-NEXT:    addis 3, 2, v@toc@ha
123 ; CHECK-NEXT:    stfd 0, v@toc@l(3)
124 ; CHECK-NEXT:    xsnegdp 0, 3
125 ; CHECK-NEXT:    xsmuldp 0, 0, 2
126 ; CHECK-NEXT:    xssubdp 1, 0, 1
127 ; CHECK-NEXT:    blr
128 entry:
129   %fneg = fneg double %a
130   store double %fneg, ptr @v, align 8
131   %fneg1 = fneg double %c
132   %mul = fmul double %fneg1, %b
133   %add = fsub double %mul, %a
134   ret double %add
137 define dso_local float @fma_combine_no_ice() {
138 ; CHECK-FAST-LABEL: fma_combine_no_ice:
139 ; CHECK-FAST:       # %bb.0:
140 ; CHECK-FAST-NEXT:    vspltisw 2, 1
141 ; CHECK-FAST-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
142 ; CHECK-FAST-NEXT:    xvcvsxwdp 3, 34
143 ; CHECK-FAST-NEXT:    lfs 0, .LCPI4_0@toc@l(3)
144 ; CHECK-FAST-NEXT:    lfs 2, 0(3)
145 ; CHECK-FAST-NEXT:    addis 3, 2, .LCPI4_1@toc@ha
146 ; CHECK-FAST-NEXT:    lfs 1, .LCPI4_1@toc@l(3)
147 ; CHECK-FAST-NEXT:    xsmaddasp 3, 2, 0
148 ; CHECK-FAST-NEXT:    xsmaddasp 1, 2, 3
149 ; CHECK-FAST-NEXT:    xsnmsubasp 1, 3, 2
150 ; CHECK-FAST-NEXT:    blr
152 ; CHECK-FAST-NOVSX-LABEL: fma_combine_no_ice:
153 ; CHECK-FAST-NOVSX:       # %bb.0:
154 ; CHECK-FAST-NOVSX-NEXT:    lfs 0, 0(3)
155 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
156 ; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI4_0@toc@l(3)
157 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_1@toc@ha
158 ; CHECK-FAST-NOVSX-NEXT:    lfs 2, .LCPI4_1@toc@l(3)
159 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_2@toc@ha
160 ; CHECK-FAST-NOVSX-NEXT:    fmadds 1, 0, 2, 1
161 ; CHECK-FAST-NOVSX-NEXT:    lfs 2, .LCPI4_2@toc@l(3)
162 ; CHECK-FAST-NOVSX-NEXT:    fmadds 2, 0, 1, 2
163 ; CHECK-FAST-NOVSX-NEXT:    fnmsubs 1, 1, 0, 2
164 ; CHECK-FAST-NOVSX-NEXT:    blr
166 ; CHECK-LABEL: fma_combine_no_ice:
167 ; CHECK:       # %bb.0:
168 ; CHECK-NEXT:    vspltisw 2, 1
169 ; CHECK-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
170 ; CHECK-NEXT:    xvcvsxwdp 3, 34
171 ; CHECK-NEXT:    lfs 0, .LCPI4_0@toc@l(3)
172 ; CHECK-NEXT:    lfs 2, 0(3)
173 ; CHECK-NEXT:    addis 3, 2, .LCPI4_1@toc@ha
174 ; CHECK-NEXT:    lfs 1, .LCPI4_1@toc@l(3)
175 ; CHECK-NEXT:    fmr 4, 3
176 ; CHECK-NEXT:    xsmaddasp 3, 2, 0
177 ; CHECK-NEXT:    xsnmaddasp 4, 2, 0
178 ; CHECK-NEXT:    xsmaddasp 1, 2, 3
179 ; CHECK-NEXT:    xsmaddasp 1, 4, 2
180 ; CHECK-NEXT:    blr
181   %tmp = load float, ptr undef, align 4
182   %tmp2 = load float, ptr undef, align 4
183   %tmp3 = fmul contract reassoc float %tmp, 0x3FE372D780000000
184   %tmp4 = fadd contract reassoc float %tmp3, 1.000000e+00
185   %tmp5 = fmul contract reassoc float %tmp2, %tmp4
186   %tmp6 = load float, ptr undef, align 4
187   %tmp7 = load float, ptr undef, align 4
188   %tmp8 = fmul contract reassoc float %tmp7, 0x3FE372D780000000
189   %tmp9 = fsub contract reassoc nsz float -1.000000e+00, %tmp8
190   %tmp10 = fmul contract reassoc float %tmp9, %tmp6
191   %tmp11 = fadd contract reassoc float %tmp5, 5.000000e-01
192   %tmp12 = fadd contract reassoc float %tmp11, %tmp10
193   ret float %tmp12
196 ; This would crash while trying getNegatedExpression().
197 define dso_local double @getNegatedExpression_crash(double %x, double %y) {
198 ; CHECK-FAST-LABEL: getNegatedExpression_crash:
199 ; CHECK-FAST:       # %bb.0:
200 ; CHECK-FAST-NEXT:    vspltisw 2, -1
201 ; CHECK-FAST-NEXT:    addis 3, 2, .LCPI5_0@toc@ha
202 ; CHECK-FAST-NEXT:    xvcvsxwdp 4, 34
203 ; CHECK-FAST-NEXT:    lfs 3, .LCPI5_0@toc@l(3)
204 ; CHECK-FAST-NEXT:    xssubdp 0, 1, 4
205 ; CHECK-FAST-NEXT:    # kill: def $f4 killed $f4 killed $vsl4
206 ; CHECK-FAST-NEXT:    xsmaddadp 4, 1, 3
207 ; CHECK-FAST-NEXT:    xsmaddadp 0, 4, 2
208 ; CHECK-FAST-NEXT:    fmr 1, 0
209 ; CHECK-FAST-NEXT:    blr
211 ; CHECK-FAST-NOVSX-LABEL: getNegatedExpression_crash:
212 ; CHECK-FAST-NOVSX:       # %bb.0:
213 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI5_0@toc@ha
214 ; CHECK-FAST-NOVSX-NEXT:    lfs 0, .LCPI5_0@toc@l(3)
215 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI5_1@toc@ha
216 ; CHECK-FAST-NOVSX-NEXT:    lfs 3, .LCPI5_1@toc@l(3)
217 ; CHECK-FAST-NOVSX-NEXT:    fmadd 3, 1, 3, 0
218 ; CHECK-FAST-NOVSX-NEXT:    fsub 0, 1, 0
219 ; CHECK-FAST-NOVSX-NEXT:    fmadd 1, 3, 2, 0
220 ; CHECK-FAST-NOVSX-NEXT:    blr
222 ; CHECK-LABEL: getNegatedExpression_crash:
223 ; CHECK:       # %bb.0:
224 ; CHECK-NEXT:    vspltisw 2, -1
225 ; CHECK-NEXT:    addis 3, 2, .LCPI5_0@toc@ha
226 ; CHECK-NEXT:    xvcvsxwdp 4, 34
227 ; CHECK-NEXT:    lfs 3, .LCPI5_0@toc@l(3)
228 ; CHECK-NEXT:    xssubdp 0, 1, 4
229 ; CHECK-NEXT:    # kill: def $f4 killed $f4 killed $vsl4
230 ; CHECK-NEXT:    xsmaddadp 4, 1, 3
231 ; CHECK-NEXT:    xsmaddadp 0, 4, 2
232 ; CHECK-NEXT:    fmr 1, 0
233 ; CHECK-NEXT:    blr
234   %neg = fneg reassoc double %x
235   %fma = call reassoc nsz double @llvm.fma.f64(double %neg, double 42.0, double -1.0)
236   %add = fadd reassoc nsz double %x, 1.0
237   %fma1 = call reassoc nsz double @llvm.fma.f64(double %fma, double %y, double %add)
238   ret double %fma1
241 define dso_local double @fma_flag_propagation(double %a) {
242 ; CHECK-FAST-LABEL: fma_flag_propagation:
243 ; CHECK-FAST:       # %bb.0: # %entry
244 ; CHECK-FAST-NEXT:    xxlxor 1, 1, 1
245 ; CHECK-FAST-NEXT:    blr
247 ; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
248 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
249 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI6_0@toc@ha
250 ; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI6_0@toc@l(3)
251 ; CHECK-FAST-NOVSX-NEXT:    blr
253 ; CHECK-LABEL: fma_flag_propagation:
254 ; CHECK:       # %bb.0: # %entry
255 ; CHECK-NEXT:    xxlxor 1, 1, 1
256 ; CHECK-NEXT:    blr
257 entry:
258   %0 = fneg double %a
259   %1 = call reassoc nnan double @llvm.fma.f64(double %0, double 1.0, double %a)
260   ret double %1
263 define dso_local double @neg_fma_flag_propagation(double %a) {
264 ; CHECK-FAST-LABEL: neg_fma_flag_propagation:
265 ; CHECK-FAST:       # %bb.0: # %entry
266 ; CHECK-FAST-NEXT:    xxlxor 1, 1, 1
267 ; CHECK-FAST-NEXT:    blr
269 ; CHECK-FAST-NOVSX-LABEL: neg_fma_flag_propagation:
270 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
271 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI7_0@toc@ha
272 ; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI7_0@toc@l(3)
273 ; CHECK-FAST-NOVSX-NEXT:    blr
275 ; CHECK-LABEL: neg_fma_flag_propagation:
276 ; CHECK:       # %bb.0: # %entry
277 ; CHECK-NEXT:    xxlxor 1, 1, 1
278 ; CHECK-NEXT:    blr
279 entry:
280   %0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a)
281   ret double %0
284 define <2 x double> @vec_neg_fma_flag_propagation(<2 x double> %a) {
285 ; CHECK-FAST-LABEL: vec_neg_fma_flag_propagation:
286 ; CHECK-FAST:       # %bb.0: # %entry
287 ; CHECK-FAST-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
288 ; CHECK-FAST-NEXT:    addi 3, 3, .LCPI8_0@toc@l
289 ; CHECK-FAST-NEXT:    lxvd2x 0, 0, 3
290 ; CHECK-FAST-NEXT:    xvmaddadp 34, 34, 0
291 ; CHECK-FAST-NEXT:    blr
293 ; CHECK-FAST-NOVSX-LABEL: vec_neg_fma_flag_propagation:
294 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
295 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
296 ; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI8_0@toc@l(3)
297 ; CHECK-FAST-NOVSX-NEXT:    fmr 2, 1
298 ; CHECK-FAST-NOVSX-NEXT:    blr
300 ; CHECK-LABEL: vec_neg_fma_flag_propagation:
301 ; CHECK:       # %bb.0: # %entry
302 ; CHECK-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
303 ; CHECK-NEXT:    addi 3, 3, .LCPI8_0@toc@l
304 ; CHECK-NEXT:    lxvd2x 0, 0, 3
305 ; CHECK-NEXT:    xvmaddadp 34, 34, 0
306 ; CHECK-NEXT:    blr
307 entry:
308   %0 = call reassoc nnan <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> <double -1.0, double -1.0>, <2 x double> %a)
309   ret <2 x double> %0
312 define dso_local double @fma_combine_const(double %a, double %b) {
313 ; CHECK-FAST-LABEL: fma_combine_const:
314 ; CHECK-FAST:       # %bb.0: # %entry
315 ; CHECK-FAST-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
316 ; CHECK-FAST-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
317 ; CHECK-FAST-NEXT:    xsmaddadp 2, 1, 0
318 ; CHECK-FAST-NEXT:    fmr 1, 2
319 ; CHECK-FAST-NEXT:    blr
321 ; CHECK-FAST-NOVSX-LABEL: fma_combine_const:
322 ; CHECK-FAST-NOVSX:       # %bb.0: # %entry
323 ; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
324 ; CHECK-FAST-NOVSX-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
325 ; CHECK-FAST-NOVSX-NEXT:    fmadd 1, 1, 0, 2
326 ; CHECK-FAST-NOVSX-NEXT:    blr
328 ; CHECK-LABEL: fma_combine_const:
329 ; CHECK:       # %bb.0: # %entry
330 ; CHECK-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
331 ; CHECK-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
332 ; CHECK-NEXT:    addis 3, 2, .LCPI9_1@toc@ha
333 ; CHECK-NEXT:    xsmuldp 0, 1, 0
334 ; CHECK-NEXT:    lfd 1, .LCPI9_1@toc@l(3)
335 ; CHECK-NEXT:    xsmaddadp 2, 0, 1
336 ; CHECK-NEXT:    fmr 1, 2
337 ; CHECK-NEXT:    blr
338 entry:
339   %0 = fmul double %a, 1.1
340   %1 = call contract double @llvm.fma.f64(double %0, double 2.1, double %b)
341   ret double %1
344 declare double @llvm.fma.f64(double, double, double) nounwind readnone
345 declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone