• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
7
8define 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
13;
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
18;
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
25entry:
26  %fneg1 = fneg double %c
27  %mul = fmul double %fneg1, %b
28  %add = fsub double %mul, %a
29  ret double %add
30}
31
32define 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
37;
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
42;
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
49entry:
50  %fneg1 = fneg double %c
51  %mul = fmul double %b, %fneg1
52  %add = fsub double %mul, %a
53  ret double %add
54}
55
56@v = common local_unnamed_addr global double 0.000000e+00, align 8
57@z = common local_unnamed_addr global double 0.000000e+00, align 8
58define 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:    addis 4, 2, z@toc@ha
64; CHECK-FAST-NEXT:    xsnmaddadp 1, 3, 2
65; CHECK-FAST-NEXT:    xsnegdp 2, 3
66; CHECK-FAST-NEXT:    stfd 0, v@toc@l(3)
67; CHECK-FAST-NEXT:    stfd 2, z@toc@l(4)
68; CHECK-FAST-NEXT:    blr
69;
70; CHECK-FAST-NOVSX-LABEL: fma_combine_two_uses:
71; CHECK-FAST-NOVSX:       # %bb.0: # %entry
72; CHECK-FAST-NOVSX-NEXT:    fnmadd 0, 3, 2, 1
73; CHECK-FAST-NOVSX-NEXT:    fneg 2, 1
74; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, v@toc@ha
75; CHECK-FAST-NOVSX-NEXT:    addis 4, 2, z@toc@ha
76; CHECK-FAST-NOVSX-NEXT:    fneg 3, 3
77; CHECK-FAST-NOVSX-NEXT:    fmr 1, 0
78; CHECK-FAST-NOVSX-NEXT:    stfd 2, v@toc@l(3)
79; CHECK-FAST-NOVSX-NEXT:    stfd 3, z@toc@l(4)
80; CHECK-FAST-NOVSX-NEXT:    blr
81;
82; CHECK-LABEL: fma_combine_two_uses:
83; CHECK:       # %bb.0: # %entry
84; CHECK-NEXT:    xsnegdp 3, 3
85; CHECK-NEXT:    addis 3, 2, v@toc@ha
86; CHECK-NEXT:    addis 4, 2, z@toc@ha
87; CHECK-NEXT:    xsmuldp 0, 3, 2
88; CHECK-NEXT:    stfd 3, z@toc@l(4)
89; CHECK-NEXT:    xsnegdp 2, 1
90; CHECK-NEXT:    xssubdp 0, 0, 1
91; CHECK-NEXT:    stfd 2, v@toc@l(3)
92; CHECK-NEXT:    fmr 1, 0
93; CHECK-NEXT:    blr
94entry:
95  %fneg = fneg double %a
96  store double %fneg, double* @v, align 8
97  %fneg1 = fneg double %c
98  store double %fneg1, double* @z, align 8
99  %mul = fmul double %fneg1, %b
100  %add = fsub double %mul, %a
101  ret double %add
102}
103
104define double @fma_combine_one_use(double %a, double %b, double %c) {
105; CHECK-FAST-LABEL: fma_combine_one_use:
106; CHECK-FAST:       # %bb.0: # %entry
107; CHECK-FAST-NEXT:    xsnegdp 0, 1
108; CHECK-FAST-NEXT:    addis 3, 2, v@toc@ha
109; CHECK-FAST-NEXT:    xsnmaddadp 1, 3, 2
110; CHECK-FAST-NEXT:    stfd 0, v@toc@l(3)
111; CHECK-FAST-NEXT:    blr
112;
113; CHECK-FAST-NOVSX-LABEL: fma_combine_one_use:
114; CHECK-FAST-NOVSX:       # %bb.0: # %entry
115; CHECK-FAST-NOVSX-NEXT:    fnmadd 0, 3, 2, 1
116; CHECK-FAST-NOVSX-NEXT:    fneg 2, 1
117; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, v@toc@ha
118; CHECK-FAST-NOVSX-NEXT:    fmr 1, 0
119; CHECK-FAST-NOVSX-NEXT:    stfd 2, v@toc@l(3)
120; CHECK-FAST-NOVSX-NEXT:    blr
121;
122; CHECK-LABEL: fma_combine_one_use:
123; CHECK:       # %bb.0: # %entry
124; CHECK-NEXT:    xsnegdp 0, 3
125; CHECK-NEXT:    addis 3, 2, v@toc@ha
126; CHECK-NEXT:    xsmuldp 0, 0, 2
127; CHECK-NEXT:    xsnegdp 2, 1
128; CHECK-NEXT:    xssubdp 0, 0, 1
129; CHECK-NEXT:    stfd 2, v@toc@l(3)
130; CHECK-NEXT:    fmr 1, 0
131; CHECK-NEXT:    blr
132entry:
133  %fneg = fneg double %a
134  store double %fneg, double* @v, align 8
135  %fneg1 = fneg double %c
136  %mul = fmul double %fneg1, %b
137  %add = fsub double %mul, %a
138  ret double %add
139}
140
141define float @fma_combine_no_ice() {
142; CHECK-FAST-LABEL: fma_combine_no_ice:
143; CHECK-FAST:       # %bb.0:
144; CHECK-FAST-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
145; CHECK-FAST-NEXT:    addis 4, 2, .LCPI4_1@toc@ha
146; CHECK-FAST-NEXT:    lfs 0, .LCPI4_0@toc@l(3)
147; CHECK-FAST-NEXT:    lfsx 2, 0, 3
148; CHECK-FAST-NEXT:    addis 3, 2, .LCPI4_2@toc@ha
149; CHECK-FAST-NEXT:    lfs 3, .LCPI4_1@toc@l(4)
150; CHECK-FAST-NEXT:    lfs 1, .LCPI4_2@toc@l(3)
151; CHECK-FAST-NEXT:    xsmaddasp 3, 2, 0
152; CHECK-FAST-NEXT:    xsmaddasp 1, 2, 3
153; CHECK-FAST-NEXT:    xsnmsubasp 1, 3, 2
154; CHECK-FAST-NEXT:    blr
155;
156; CHECK-FAST-NOVSX-LABEL: fma_combine_no_ice:
157; CHECK-FAST-NOVSX:       # %bb.0:
158; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
159; CHECK-FAST-NOVSX-NEXT:    lfs 0, .LCPI4_0@toc@l(3)
160; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_1@toc@ha
161; CHECK-FAST-NOVSX-NEXT:    lfs 1, 0(3)
162; CHECK-FAST-NOVSX-NEXT:    lfs 2, .LCPI4_1@toc@l(3)
163; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI4_2@toc@ha
164; CHECK-FAST-NOVSX-NEXT:    fmadds 0, 1, 2, 0
165; CHECK-FAST-NOVSX-NEXT:    lfs 2, .LCPI4_2@toc@l(3)
166; CHECK-FAST-NOVSX-NEXT:    fmadds 2, 1, 0, 2
167; CHECK-FAST-NOVSX-NEXT:    fnmsubs 1, 0, 1, 2
168; CHECK-FAST-NOVSX-NEXT:    blr
169;
170; CHECK-LABEL: fma_combine_no_ice:
171; CHECK:       # %bb.0:
172; CHECK-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
173; CHECK-NEXT:    addis 4, 2, .LCPI4_1@toc@ha
174; CHECK-NEXT:    lfs 0, .LCPI4_0@toc@l(3)
175; CHECK-NEXT:    lfsx 2, 0, 3
176; CHECK-NEXT:    addis 3, 2, .LCPI4_2@toc@ha
177; CHECK-NEXT:    lfs 3, .LCPI4_1@toc@l(4)
178; CHECK-NEXT:    lfs 1, .LCPI4_2@toc@l(3)
179; CHECK-NEXT:    fmr 4, 3
180; CHECK-NEXT:    xsmaddasp 3, 2, 0
181; CHECK-NEXT:    xsnmaddasp 4, 2, 0
182; CHECK-NEXT:    xsmaddasp 1, 2, 3
183; CHECK-NEXT:    xsmaddasp 1, 4, 2
184; CHECK-NEXT:    blr
185  %tmp = load float, float* undef, align 4
186  %tmp2 = load float, float* undef, align 4
187  %tmp3 = fmul reassoc float %tmp, 0x3FE372D780000000
188  %tmp4 = fadd reassoc float %tmp3, 1.000000e+00
189  %tmp5 = fmul reassoc float %tmp2, %tmp4
190  %tmp6 = load float, float* undef, align 4
191  %tmp7 = load float, float* undef, align 4
192  %tmp8 = fmul reassoc float %tmp7, 0x3FE372D780000000
193  %tmp9 = fsub reassoc nsz float -1.000000e+00, %tmp8
194  %tmp10 = fmul reassoc float %tmp9, %tmp6
195  %tmp11 = fadd reassoc float %tmp5, 5.000000e-01
196  %tmp12 = fadd reassoc float %tmp11, %tmp10
197  ret float %tmp12
198}
199
200; This would crash while trying getNegatedExpression().
201define double @getNegatedExpression_crash(double %x, double %y) {
202; CHECK-FAST-LABEL: getNegatedExpression_crash:
203; CHECK-FAST:       # %bb.0:
204; CHECK-FAST-NEXT:    addis 3, 2, .LCPI5_1@toc@ha
205; CHECK-FAST-NEXT:    addis 4, 2, .LCPI5_0@toc@ha
206; CHECK-FAST-NEXT:    lfs 3, .LCPI5_1@toc@l(3)
207; CHECK-FAST-NEXT:    lfs 4, .LCPI5_0@toc@l(4)
208; CHECK-FAST-NEXT:    xssubdp 0, 1, 3
209; CHECK-FAST-NEXT:    xsmaddadp 3, 1, 4
210; CHECK-FAST-NEXT:    xsmaddadp 0, 3, 2
211; CHECK-FAST-NEXT:    fmr 1, 0
212; CHECK-FAST-NEXT:    blr
213;
214; CHECK-FAST-NOVSX-LABEL: getNegatedExpression_crash:
215; CHECK-FAST-NOVSX:       # %bb.0:
216; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI5_0@toc@ha
217; CHECK-FAST-NOVSX-NEXT:    addis 4, 2, .LCPI5_1@toc@ha
218; CHECK-FAST-NOVSX-NEXT:    lfs 0, .LCPI5_0@toc@l(3)
219; CHECK-FAST-NOVSX-NEXT:    lfs 3, .LCPI5_1@toc@l(4)
220; CHECK-FAST-NOVSX-NEXT:    fmadd 3, 1, 3, 0
221; CHECK-FAST-NOVSX-NEXT:    fsub 0, 1, 0
222; CHECK-FAST-NOVSX-NEXT:    fmadd 1, 3, 2, 0
223; CHECK-FAST-NOVSX-NEXT:    blr
224;
225; CHECK-LABEL: getNegatedExpression_crash:
226; CHECK:       # %bb.0:
227; CHECK-NEXT:    addis 3, 2, .LCPI5_1@toc@ha
228; CHECK-NEXT:    addis 4, 2, .LCPI5_0@toc@ha
229; CHECK-NEXT:    lfs 3, .LCPI5_1@toc@l(3)
230; CHECK-NEXT:    lfs 4, .LCPI5_0@toc@l(4)
231; CHECK-NEXT:    xssubdp 0, 1, 3
232; CHECK-NEXT:    xsmaddadp 3, 1, 4
233; CHECK-NEXT:    xsmaddadp 0, 3, 2
234; CHECK-NEXT:    fmr 1, 0
235; CHECK-NEXT:    blr
236  %neg = fneg reassoc double %x
237  %fma = call reassoc nsz double @llvm.fma.f64(double %neg, double 42.0, double -1.0)
238  %add = fadd reassoc nsz double %x, 1.0
239  %fma1 = call reassoc nsz double @llvm.fma.f64(double %fma, double %y, double %add)
240  ret double %fma1
241}
242
243define double @fma_flag_propagation(double %a) {
244; CHECK-FAST-LABEL: fma_flag_propagation:
245; CHECK-FAST:       # %bb.0: # %entry
246; CHECK-FAST-NEXT:    xxlxor 1, 1, 1
247; CHECK-FAST-NEXT:    blr
248;
249; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
250; CHECK-FAST-NOVSX:       # %bb.0: # %entry
251; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI6_0@toc@ha
252; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI6_0@toc@l(3)
253; CHECK-FAST-NOVSX-NEXT:    blr
254;
255; CHECK-LABEL: fma_flag_propagation:
256; CHECK:       # %bb.0: # %entry
257; CHECK-NEXT:    xxlxor 1, 1, 1
258; CHECK-NEXT:    blr
259entry:
260  %0 = fneg double %a
261  %1 = call reassoc nnan double @llvm.fma.f64(double %0, double 1.0, double %a)
262  ret double %1
263}
264
265define double @neg_fma_flag_propagation(double %a) {
266; CHECK-FAST-LABEL: neg_fma_flag_propagation:
267; CHECK-FAST:       # %bb.0: # %entry
268; CHECK-FAST-NEXT:    xxlxor 1, 1, 1
269; CHECK-FAST-NEXT:    blr
270;
271; CHECK-FAST-NOVSX-LABEL: neg_fma_flag_propagation:
272; CHECK-FAST-NOVSX:       # %bb.0: # %entry
273; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI7_0@toc@ha
274; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI7_0@toc@l(3)
275; CHECK-FAST-NOVSX-NEXT:    blr
276;
277; CHECK-LABEL: neg_fma_flag_propagation:
278; CHECK:       # %bb.0: # %entry
279; CHECK-NEXT:    xxlxor 1, 1, 1
280; CHECK-NEXT:    blr
281entry:
282  %0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a)
283  ret double %0
284}
285
286define <2 x double> @vec_neg_fma_flag_propagation(<2 x double> %a) {
287; CHECK-FAST-LABEL: vec_neg_fma_flag_propagation:
288; CHECK-FAST:       # %bb.0: # %entry
289; CHECK-FAST-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
290; CHECK-FAST-NEXT:    addi 3, 3, .LCPI8_0@toc@l
291; CHECK-FAST-NEXT:    lxvd2x 0, 0, 3
292; CHECK-FAST-NEXT:    xxswapd 0, 0
293; CHECK-FAST-NEXT:    xvmaddadp 34, 34, 0
294; CHECK-FAST-NEXT:    blr
295;
296; CHECK-FAST-NOVSX-LABEL: vec_neg_fma_flag_propagation:
297; CHECK-FAST-NOVSX:       # %bb.0: # %entry
298; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
299; CHECK-FAST-NOVSX-NEXT:    lfs 1, .LCPI8_0@toc@l(3)
300; CHECK-FAST-NOVSX-NEXT:    fmr 2, 1
301; CHECK-FAST-NOVSX-NEXT:    blr
302;
303; CHECK-LABEL: vec_neg_fma_flag_propagation:
304; CHECK:       # %bb.0: # %entry
305; CHECK-NEXT:    addis 3, 2, .LCPI8_0@toc@ha
306; CHECK-NEXT:    addi 3, 3, .LCPI8_0@toc@l
307; CHECK-NEXT:    lxvd2x 0, 0, 3
308; CHECK-NEXT:    xxswapd 0, 0
309; CHECK-NEXT:    xvmaddadp 34, 34, 0
310; CHECK-NEXT:    blr
311entry:
312  %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)
313  ret <2 x double> %0
314}
315
316define double @fma_combine_const(double %a, double %b) {
317; CHECK-FAST-LABEL: fma_combine_const:
318; CHECK-FAST:       # %bb.0: # %entry
319; CHECK-FAST-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
320; CHECK-FAST-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
321; CHECK-FAST-NEXT:    xsmaddadp 2, 1, 0
322; CHECK-FAST-NEXT:    fmr 1, 2
323; CHECK-FAST-NEXT:    blr
324;
325; CHECK-FAST-NOVSX-LABEL: fma_combine_const:
326; CHECK-FAST-NOVSX:       # %bb.0: # %entry
327; CHECK-FAST-NOVSX-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
328; CHECK-FAST-NOVSX-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
329; CHECK-FAST-NOVSX-NEXT:    fmadd 1, 1, 0, 2
330; CHECK-FAST-NOVSX-NEXT:    blr
331;
332; CHECK-LABEL: fma_combine_const:
333; CHECK:       # %bb.0: # %entry
334; CHECK-NEXT:    addis 3, 2, .LCPI9_0@toc@ha
335; CHECK-NEXT:    lfd 0, .LCPI9_0@toc@l(3)
336; CHECK-NEXT:    addis 3, 2, .LCPI9_1@toc@ha
337; CHECK-NEXT:    lfd 3, .LCPI9_1@toc@l(3)
338; CHECK-NEXT:    xsmuldp 0, 1, 0
339; CHECK-NEXT:    fmr 1, 2
340; CHECK-NEXT:    xsmaddadp 1, 0, 3
341; CHECK-NEXT:    blr
342entry:
343  %0 = fmul double %a, 1.1
344  %1 = call contract double @llvm.fma.f64(double %0, double 2.1, double %b)
345  ret double %1
346}
347
348declare double @llvm.fma.f64(double, double, double) nounwind readnone
349declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone
350