xref: /llvm-project/llvm/test/CodeGen/PowerPC/fma.ll (revision 7a001a2d92a777de196eaaa070a4bfc23f40fd87)
1; RUN: llc -verify-machineinstrs < %s -mtriple=ppc32-- -fp-contract=fast -mattr=-vsx -disable-ppc-vsx-fma-mutation=false | FileCheck %s
2; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -fp-contract=fast -mattr=+vsx -mcpu=pwr7 -disable-ppc-vsx-fma-mutation=false | FileCheck -check-prefix=CHECK-VSX %s
3; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -fp-contract=fast -mcpu=pwr8 -disable-ppc-vsx-fma-mutation=false | FileCheck -check-prefix=CHECK-P8 %s
4; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu -fp-contract=fast -mcpu=pwr8 -disable-ppc-vsx-fma-mutation=false | FileCheck -check-prefix=CHECK-P8 %s
5
6declare double @dummy1(double) #0
7declare double @dummy2(double, double) #0
8declare double @dummy3(double, double, double) #0
9declare float @dummy4(float, float) #0
10
11define double @test_FMADD1(double %A, double %B, double %C) {
12	%D = fmul double %A, %B		; <double> [#uses=1]
13	%E = fadd double %C, %D		; <double> [#uses=1]
14	ret double %E
15; CHECK-LABEL: test_FMADD1:
16; CHECK: fmadd
17; CHECK-NEXT: blr
18
19; CHECK-VSX-LABEL: test_FMADD1:
20; CHECK-VSX: xsmaddmdp
21; CHECK-VSX-NEXT: blr
22}
23
24define double @test_FMADD2(double %A, double %B, double %C) {
25	%D = fmul double %A, %B		; <double> [#uses=1]
26	%E = fadd double %D, %C		; <double> [#uses=1]
27	ret double %E
28; CHECK-LABEL: test_FMADD2:
29; CHECK: fmadd
30; CHECK-NEXT: blr
31
32; CHECK-VSX-LABEL: test_FMADD2:
33; CHECK-VSX: xsmaddmdp
34; CHECK-VSX-NEXT: blr
35}
36
37define double @test_FMSUB1(double %A, double %B, double %C) {
38	%D = fmul double %A, %B		; <double> [#uses=1]
39	%E = fsub double %D, %C		; <double> [#uses=1]
40	ret double %E
41; CHECK-LABEL: test_FMSUB1:
42; CHECK: fmsub
43; CHECK-NEXT: blr
44
45; CHECK-VSX-LABEL: test_FMSUB1:
46; CHECK-VSX: xsmsubmdp
47; CHECK-VSX-NEXT: blr
48}
49
50define double @test_FMSUB2(double %A, double %B, double %C, double %D) {
51	%E = fmul double %A, %B 	; <double> [#uses=2]
52	%F = fadd double %E, %C 	; <double> [#uses=1]
53	%G = fsub double %E, %D 	; <double> [#uses=1]
54	%H = call double @dummy2(double %F, double %G)      ; <double> [#uses=1]
55	ret double %H
56; CHECK-LABEL: test_FMSUB2:
57; CHECK: fmadd
58; CHECK-NEXT: fmsub
59
60; CHECK-VSX-LABEL: test_FMSUB2:
61; CHECK-VSX: xsmaddadp
62; CHECK-VSX-NEXT: xsmsubmdp
63}
64
65define double @test_FNMADD1(double %A, double %B, double %C) {
66	%D = fmul double %A, %B		; <double> [#uses=1]
67	%E = fadd double %D, %C		; <double> [#uses=1]
68	%F = fsub double -0.000000e+00, %E		; <double> [#uses=1]
69	ret double %F
70; CHECK-LABEL: test_FNMADD1:
71; CHECK: fnmadd
72; CHECK-NEXT: blr
73
74; CHECK-VSX-LABEL: test_FNMADD1:
75; CHECK-VSX: xsnmaddmdp
76; CHECK-VSX-NEXT: blr
77}
78
79define double @test_FNMADD2(double %A, double %B, double %C) {
80	%D = fmul double %A, %B		; <double> [#uses=1]
81	%E = fadd double %C, %D		; <double> [#uses=1]
82	%F = fsub double -0.000000e+00, %E		; <double> [#uses=1]
83	ret double %F
84; CHECK-LABEL: test_FNMADD2:
85; CHECK: fnmadd
86; CHECK-NEXT: blr
87
88; CHECK-VSX-LABEL: test_FNMADD2:
89; CHECK-VSX: xsnmaddmdp
90; CHECK-VSX-NEXT: blr
91}
92
93define double @test_FNMSUB1(double %A, double %B, double %C) {
94	%D = fmul double %A, %B		; <double> [#uses=1]
95	%E = fsub double %C, %D		; <double> [#uses=1]
96	ret double %E
97; CHECK-LABEL: test_FNMSUB1:
98; CHECK: fneg
99; CHECK-NEXT: fmadd
100; CHECK-NEXT: blr
101
102; CHECK-VSX-LABEL: test_FNMSUB1:
103; CHECK-VSX: xsnegdp
104; CHECK-VSX-NEXT: xsmaddmdp
105}
106
107; need nsz flag to generate fnmsub since it may affect sign of zero
108define double @test_FNMSUB1_NSZ(double %A, double %B, double %C) {
109	%D = fmul nsz double %A, %B		; <double> [#uses=1]
110	%E = fsub nsz double %C, %D		; <double> [#uses=1]
111	ret double %E
112; CHECK-LABEL: test_FNMSUB1_NSZ:
113; CHECK: fnmsub
114; CHECK-NEXT: blr
115
116; CHECK-VSX-LABEL: test_FNMSUB1_NSZ:
117; CHECK-VSX: xsnmsubmdp
118}
119
120define double @test_FNMSUB2(double %A, double %B, double %C) {
121	%D = fmul double %A, %B		; <double> [#uses=1]
122	%E = fsub double %D, %C		; <double> [#uses=1]
123	%F = fsub double -0.000000e+00, %E		; <double> [#uses=1]
124	ret double %F
125; CHECK-LABEL: test_FNMSUB2:
126; CHECK: fnmsub
127; CHECK-NEXT: blr
128
129; CHECK-VSX-LABEL: test_FNMSUB2:
130; CHECK-VSX: xsnmsubmdp
131; CHECK-VSX-NEXT: blr
132}
133
134define float @test_FNMSUBS(float %A, float %B, float %C) {
135	%D = fmul float %A, %B		; <float> [#uses=1]
136	%E = fsub float %D, %C		; <float> [#uses=1]
137	%F = fsub float -0.000000e+00, %E		; <float> [#uses=1]
138	ret float %F
139; CHECK-LABEL: test_FNMSUBS:
140; CHECK: fnmsubs
141; CHECK-NEXT: blr
142
143; CHECK-VSX-LABEL: test_FNMSUBS:
144; CHECK-VSX: fnmsubs
145; CHECK-VSX-NEXT: blr
146}
147
148define float @test_XSMADDMSP(float %A, float %B, float %C) {
149	%D = fmul float %A, %B		; <float> [#uses=1]
150	%E = fadd float %C, %D		; <float> [#uses=1]
151	ret float %E
152; CHECK-P8-LABEL: test_XSMADDMSP:
153; CHECK-P8: xsmaddmsp
154; CHECK-P8-NEXT: blr
155}
156
157define float @test_XSMSUBMSP(float %A, float %B, float %C) {
158	%D = fmul float %A, %B		; <float> [#uses=1]
159	%E = fsub float %D, %C		; <float> [#uses=1]
160	ret float %E
161; CHECK-P8-LABEL: test_XSMSUBMSP:
162; CHECK-P8: xsmsubmsp
163; CHECK-P8-NEXT: blr
164}
165
166define float @test_XSMADDASP(float %A, float %B, float %C, float %D) {
167	%E = fmul float %A, %B 	; <float> [#uses=2]
168	%F = fadd float %E, %C 	; <float> [#uses=1]
169	%G = fsub float %E, %D 	; <float> [#uses=1]
170	%H = call float @dummy4(float %F, float %G)      ; <float> [#uses=1]
171	ret float %H
172; CHECK-P8-LABEL: test_XSMADDASP:
173; CHECK-P8: xsmaddasp
174; CHECK-P8-NEXT: xsmsubmsp
175}
176
177define float @test_XSMSUBASP(float %A, float %B, float %C, float %D) {
178	%E = fmul float %A, %B 	; <float> [#uses=2]
179	%F = fsub float %E, %C 	; <float> [#uses=1]
180	%G = fsub float %E, %D 	; <float> [#uses=1]
181	%H = call float @dummy4(float %F, float %G)      ; <float> [#uses=1]
182	ret float %H
183; CHECK-P8-LABEL: test_XSMSUBASP:
184; CHECK-P8: xsmsubasp
185; CHECK-P8-NEXT: xsmsubmsp
186}
187
188define float @test_XSNMADDMSP(float %A, float %B, float %C) {
189	%D = fmul float %A, %B		; <float> [#uses=1]
190	%E = fadd float %D, %C		; <float> [#uses=1]
191	%F = fsub float -0.000000e+00, %E		; <float> [#uses=1]
192	ret float %F
193; CHECK-P8-LABEL: test_XSNMADDMSP:
194; CHECK-P8: xsnmaddmsp
195; CHECK-P8-NEXT: blr
196}
197
198define float @test_XSNMSUBMSP(float %A, float %B, float %C) {
199	%D = fmul float %A, %B		; <float> [#uses=1]
200	%E = fsub float %D, %C		; <float> [#uses=1]
201	%F = fsub float -0.000000e+00, %E		; <float> [#uses=1]
202	ret float %F
203; CHECK-P8-LABEL: test_XSNMSUBMSP:
204; CHECK-P8: xsnmsubmsp
205; CHECK-P8-NEXT: blr
206}
207
208define float @test_XSNMADDASP(float %A, float %B, float %C) {
209	%D = fmul float %A, %B		; <float> [#uses=1]
210	%E = fadd float %D, %C		; <float> [#uses=1]
211	%F = fsub float -0.000000e+00, %E		; <float> [#uses=1]
212	%H = call float @dummy4(float %E, float %F)      ; <float> [#uses=1]
213	ret float %F
214; CHECK-P8-LABEL: test_XSNMADDASP:
215; CHECK-P8: xsnmaddasp
216
217; CHECK-VSX-LABEL: test_XSNMADDASP:
218; CHECK-VSX: fnmadds
219}
220
221define float @test_XSNMSUBASP(float %A, float %B, float %C) {
222	%D = fmul float %A, %B		; <float> [#uses=1]
223	%E = fsub float %D, %C		; <float> [#uses=1]
224	%F = fsub float -0.000000e+00, %E		; <float> [#uses=1]
225	%H = call float @dummy4(float %E, float %F)      ; <float> [#uses=1]
226	ret float %F
227; CHECK-P8-LABEL: test_XSNMSUBASP:
228; CHECK-P8: xsnmsubasp
229
230; CHECK-VSX-LABEL: test_XSNMSUBASP:
231; CHECK-VSX: fnmsubs
232}
233