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
26 %fneg1 = fneg double %c
27 %mul = fmul double %fneg1, %b
28 %add = fsub double %mul, %a
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
50 %fneg1 = fneg double %c
51 %mul = fmul double %b, %fneg1
52 %add = fsub double %mul, %a
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
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
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
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
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:
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
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
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:
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
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)
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
259 %1 = call reassoc nnan double @llvm.fma.f64(double %0, double 1.0, double %a)
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
280 %0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a)
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
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)
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
339 %0 = fmul double %a, 1.1
340 %1 = call contract double @llvm.fma.f64(double %0, double 2.1, double %b)
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