1; RUN:  llc -amdgpu-scalarize-global-loads=false  -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
2; RUN:  llc -amdgpu-scalarize-global-loads=false  -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
3; RUN:  llc -amdgpu-scalarize-global-loads=false  -march=amdgcn -mcpu=gfx90a -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GFX90A -check-prefix=FUNC %s
4
5declare double @llvm.fma.f64(double, double, double) nounwind readnone
6declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone
7declare <4 x double> @llvm.fma.v4f64(<4 x double>, <4 x double>, <4 x double>) nounwind readnone
8declare double @llvm.fabs.f64(double) nounwind readnone
9
10; FUNC-LABEL: {{^}}fma_f64:
11; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
12; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
13define amdgpu_kernel void @fma_f64(double addrspace(1)* %out, double addrspace(1)* %in1,
14                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
15   %r0 = load double, double addrspace(1)* %in1
16   %r1 = load double, double addrspace(1)* %in2
17   %r2 = load double, double addrspace(1)* %in3
18   %r3 = tail call double @llvm.fma.f64(double %r0, double %r1, double %r2)
19   store double %r3, double addrspace(1)* %out
20   ret void
21}
22
23; FUNC-LABEL: {{^}}fma_v2f64:
24; SI: v_fma_f64
25; SI: v_fma_f64
26; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
27; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
28define amdgpu_kernel void @fma_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %in1,
29                       <2 x double> addrspace(1)* %in2, <2 x double> addrspace(1)* %in3) {
30   %r0 = load <2 x double>, <2 x double> addrspace(1)* %in1
31   %r1 = load <2 x double>, <2 x double> addrspace(1)* %in2
32   %r2 = load <2 x double>, <2 x double> addrspace(1)* %in3
33   %r3 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %r0, <2 x double> %r1, <2 x double> %r2)
34   store <2 x double> %r3, <2 x double> addrspace(1)* %out
35   ret void
36}
37
38; FUNC-LABEL: {{^}}fma_v4f64:
39; SI: v_fma_f64
40; SI: v_fma_f64
41; SI: v_fma_f64
42; SI: v_fma_f64
43; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
44; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
45; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
46; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
47define amdgpu_kernel void @fma_v4f64(<4 x double> addrspace(1)* %out, <4 x double> addrspace(1)* %in1,
48                       <4 x double> addrspace(1)* %in2, <4 x double> addrspace(1)* %in3) {
49   %r0 = load <4 x double>, <4 x double> addrspace(1)* %in1
50   %r1 = load <4 x double>, <4 x double> addrspace(1)* %in2
51   %r2 = load <4 x double>, <4 x double> addrspace(1)* %in3
52   %r3 = tail call <4 x double> @llvm.fma.v4f64(<4 x double> %r0, <4 x double> %r1, <4 x double> %r2)
53   store <4 x double> %r3, <4 x double> addrspace(1)* %out
54   ret void
55}
56
57; FUNC-LABEL: {{^}}fma_f64_abs_src0:
58; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], |v\[[0-9]+:[0-9]+\]|, v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
59; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], |v\[[0-9]+:[0-9]+\]|, v\[[0-9]+:[0-9]+\]}}
60define amdgpu_kernel void @fma_f64_abs_src0(double addrspace(1)* %out, double addrspace(1)* %in1,
61                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
62   %r0 = load double, double addrspace(1)* %in1
63   %r1 = load double, double addrspace(1)* %in2
64   %r2 = load double, double addrspace(1)* %in3
65   %fabs = call double @llvm.fabs.f64(double %r0)
66   %r3 = tail call double @llvm.fma.f64(double %fabs, double %r1, double %r2)
67   store double %r3, double addrspace(1)* %out
68   ret void
69}
70
71; FUNC-LABEL: {{^}}fma_f64_abs_src1:
72; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], \|v\[[0-9]+:[0-9]+\]\|, v\[[0-9]+:[0-9]+\]}}
73; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], \|v\[[0-9]+:[0-9]+\]\|}}
74define amdgpu_kernel void @fma_f64_abs_src1(double addrspace(1)* %out, double addrspace(1)* %in1,
75                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
76   %r0 = load double, double addrspace(1)* %in1
77   %r1 = load double, double addrspace(1)* %in2
78   %r2 = load double, double addrspace(1)* %in3
79   %fabs = call double @llvm.fabs.f64(double %r1)
80   %r3 = tail call double @llvm.fma.f64(double %r0, double %fabs, double %r2)
81   store double %r3, double addrspace(1)* %out
82   ret void
83}
84
85; FUNC-LABEL: {{^}}fma_f64_abs_src2:
86; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], \|v\[[0-9]+:[0-9]+\]\|}}
87; GFX90A: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], \|v\[[0-9]+:[0-9]+\]\|}}
88define amdgpu_kernel void @fma_f64_abs_src2(double addrspace(1)* %out, double addrspace(1)* %in1,
89                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
90   %r0 = load double, double addrspace(1)* %in1
91   %r1 = load double, double addrspace(1)* %in2
92   %r2 = load double, double addrspace(1)* %in3
93   %fabs = call double @llvm.fabs.f64(double %r2)
94   %r3 = tail call double @llvm.fma.f64(double %r0, double %r1, double %fabs)
95   store double %r3, double addrspace(1)* %out
96   ret void
97}
98
99; FUNC-LABEL: {{^}}fma_f64_neg_src0:
100; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
101; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
102define amdgpu_kernel void @fma_f64_neg_src0(double addrspace(1)* %out, double addrspace(1)* %in1,
103                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
104   %r0 = load double, double addrspace(1)* %in1
105   %r1 = load double, double addrspace(1)* %in2
106   %r2 = load double, double addrspace(1)* %in3
107   %fsub = fsub double -0.000000e+00, %r0
108   %r3 = tail call double @llvm.fma.f64(double %fsub, double %r1, double %r2)
109   store double %r3, double addrspace(1)* %out
110   ret void
111}
112
113; FUNC-LABEL: {{^}}fma_f64_neg_src1:
114; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
115; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\]}}
116define amdgpu_kernel void @fma_f64_neg_src1(double addrspace(1)* %out, double addrspace(1)* %in1,
117                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
118   %r0 = load double, double addrspace(1)* %in1
119   %r1 = load double, double addrspace(1)* %in2
120   %r2 = load double, double addrspace(1)* %in3
121   %fsub = fsub double -0.000000e+00, %r1
122   %r3 = tail call double @llvm.fma.f64(double %r0, double %fsub, double %r2)
123   store double %r3, double addrspace(1)* %out
124   ret void
125}
126
127; FUNC-LABEL: {{^}}fma_f64_neg_src2:
128; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\]}}
129; GFX90A: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -v\[[0-9]+:[0-9]+\]}}
130define amdgpu_kernel void @fma_f64_neg_src2(double addrspace(1)* %out, double addrspace(1)* %in1,
131                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
132   %r0 = load double, double addrspace(1)* %in1
133   %r1 = load double, double addrspace(1)* %in2
134   %r2 = load double, double addrspace(1)* %in3
135   %fsub = fsub double -0.000000e+00, %r2
136   %r3 = tail call double @llvm.fma.f64(double %r0, double %r1, double %fsub)
137   store double %r3, double addrspace(1)* %out
138   ret void
139}
140
141; FUNC-LABEL: {{^}}fma_f64_abs_neg_src0:
142; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|, v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\]}}
143; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|, v\[[0-9]+:[0-9]+\]}}
144define amdgpu_kernel void @fma_f64_abs_neg_src0(double addrspace(1)* %out, double addrspace(1)* %in1,
145                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
146   %r0 = load double, double addrspace(1)* %in1
147   %r1 = load double, double addrspace(1)* %in2
148   %r2 = load double, double addrspace(1)* %in3
149   %fabs = call double @llvm.fabs.f64(double %r0)
150   %fsub = fsub double -0.000000e+00, %fabs
151   %r3 = tail call double @llvm.fma.f64(double %fsub, double %r1, double %r2)
152   store double %r3, double addrspace(1)* %out
153   ret void
154}
155
156; FUNC-LABEL: {{^}}fma_f64_abs_neg_src1:
157; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|, v\[[0-9]+:[0-9]+\]}}
158; GFX90A: v_fmac_f64_e64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|}}
159define amdgpu_kernel void @fma_f64_abs_neg_src1(double addrspace(1)* %out, double addrspace(1)* %in1,
160                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
161   %r0 = load double, double addrspace(1)* %in1
162   %r1 = load double, double addrspace(1)* %in2
163   %r2 = load double, double addrspace(1)* %in3
164   %fabs = call double @llvm.fabs.f64(double %r1)
165   %fsub = fsub double -0.000000e+00, %fabs
166   %r3 = tail call double @llvm.fma.f64(double %r0, double %fsub, double %r2)
167   store double %r3, double addrspace(1)* %out
168   ret void
169}
170
171; FUNC-LABEL: {{^}}fma_f64_abs_neg_src2:
172; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|}}
173; GFX90A: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], -\|v\[[0-9]+:[0-9]+\]\|}}
174define amdgpu_kernel void @fma_f64_abs_neg_src2(double addrspace(1)* %out, double addrspace(1)* %in1,
175                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
176   %r0 = load double, double addrspace(1)* %in1
177   %r1 = load double, double addrspace(1)* %in2
178   %r2 = load double, double addrspace(1)* %in3
179   %fabs = call double @llvm.fabs.f64(double %r2)
180   %fsub = fsub double -0.000000e+00, %fabs
181   %r3 = tail call double @llvm.fma.f64(double %r0, double %r1, double %fsub)
182   store double %r3, double addrspace(1)* %out
183   ret void
184}
185
186; FUNC-LABEL: {{^}}fma_f64_lit_src0:
187; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 2.0, v\[[0-9]+:[0-9]+\]}}
188; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], 2.0, v\[[0-9]+:[0-9]+\]}}
189define amdgpu_kernel void @fma_f64_lit_src0(double addrspace(1)* %out,
190                     double addrspace(1)* %in2, double addrspace(1)* %in3) {
191   %r1 = load double, double addrspace(1)* %in2
192   %r2 = load double, double addrspace(1)* %in3
193   %r3 = tail call double @llvm.fma.f64(double +2.0, double %r1, double %r2)
194   store double %r3, double addrspace(1)* %out
195   ret void
196}
197
198; FUNC-LABEL: {{^}}fma_f64_lit_src1:
199; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 2.0, v\[[0-9]+:[0-9]+\]}}
200; GFX90A: v_fmac_f64_e32 {{v\[[0-9]+:[0-9]+\], 2.0, v\[[0-9]+:[0-9]+\]}}
201define amdgpu_kernel void @fma_f64_lit_src1(double addrspace(1)* %out, double addrspace(1)* %in1,
202                     double addrspace(1)* %in3) {
203   %r0 = load double, double addrspace(1)* %in1
204   %r2 = load double, double addrspace(1)* %in3
205   %r3 = tail call double @llvm.fma.f64(double %r0, double +2.0, double %r2)
206   store double %r3, double addrspace(1)* %out
207   ret void
208}
209
210; FUNC-LABEL: {{^}}fma_f64_lit_src2:
211; SI: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 2.0}}
212; GFX90A: v_fma_f64 {{v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], v\[[0-9]+:[0-9]+\], 2.0}}
213define amdgpu_kernel void @fma_f64_lit_src2(double addrspace(1)* %out, double addrspace(1)* %in1,
214                     double addrspace(1)* %in2) {
215   %r0 = load double, double addrspace(1)* %in1
216   %r1 = load double, double addrspace(1)* %in2
217   %r3 = tail call double @llvm.fma.f64(double %r0, double %r1, double +2.0)
218   store double %r3, double addrspace(1)* %out
219   ret void
220}
221