1; Test the MSA intrinsics that are encoded with the 2RF instruction format.
2
3; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck %s
4; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s | FileCheck %s
5
6@llvm_mips_flog2_w_ARG1 = global <4 x float> <float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, align 16
7@llvm_mips_flog2_w_RES  = global <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, align 16
8
9define void @llvm_mips_flog2_w_test() nounwind {
10entry:
11  %0 = load <4 x float>* @llvm_mips_flog2_w_ARG1
12  %1 = tail call <4 x float> @llvm.mips.flog2.w(<4 x float> %0)
13  store <4 x float> %1, <4 x float>* @llvm_mips_flog2_w_RES
14  ret void
15}
16
17declare <4 x float> @llvm.mips.flog2.w(<4 x float>) nounwind
18
19; CHECK: llvm_mips_flog2_w_test:
20; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_flog2_w_ARG1)
21; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
22; CHECK-DAG: flog2.w [[WD:\$w[0-9]+]], [[WS]]
23; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_flog2_w_RES)
24; CHECK-DAG: st.w [[WD]], 0([[R2]])
25; CHECK: .size llvm_mips_flog2_w_test
26;
27@llvm_mips_flog2_d_ARG1 = global <2 x double> <double 0.000000e+00, double 1.000000e+00>, align 16
28@llvm_mips_flog2_d_RES  = global <2 x double> <double 0.000000e+00, double 0.000000e+00>, align 16
29
30define void @llvm_mips_flog2_d_test() nounwind {
31entry:
32  %0 = load <2 x double>* @llvm_mips_flog2_d_ARG1
33  %1 = tail call <2 x double> @llvm.mips.flog2.d(<2 x double> %0)
34  store <2 x double> %1, <2 x double>* @llvm_mips_flog2_d_RES
35  ret void
36}
37
38declare <2 x double> @llvm.mips.flog2.d(<2 x double>) nounwind
39
40; CHECK: llvm_mips_flog2_d_test:
41; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_flog2_d_ARG1)
42; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
43; CHECK-DAG: flog2.d [[WD:\$w[0-9]+]], [[WS]]
44; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_flog2_d_RES)
45; CHECK-DAG: st.d [[WD]], 0([[R2]])
46; CHECK: .size llvm_mips_flog2_d_test
47
48define void @flog2_w_test() nounwind {
49entry:
50  %0 = load <4 x float>* @llvm_mips_flog2_w_ARG1
51  %1 = tail call <4 x float> @llvm.log2.v4f32(<4 x float> %0)
52  store <4 x float> %1, <4 x float>* @llvm_mips_flog2_w_RES
53  ret void
54}
55
56declare <4 x float> @llvm.log2.v4f32(<4 x float> %val)
57
58; CHECK: flog2_w_test:
59; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_flog2_w_ARG1)
60; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
61; CHECK-DAG: flog2.w [[WD:\$w[0-9]+]], [[WS]]
62; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_flog2_w_RES)
63; CHECK-DAG: st.w [[WD]], 0([[R2]])
64; CHECK: .size flog2_w_test
65
66define void @flog2_d_test() nounwind {
67entry:
68  %0 = load <2 x double>* @llvm_mips_flog2_d_ARG1
69  %1 = tail call <2 x double> @llvm.log2.v2f64(<2 x double> %0)
70  store <2 x double> %1, <2 x double>* @llvm_mips_flog2_d_RES
71  ret void
72}
73
74declare <2 x double> @llvm.log2.v2f64(<2 x double> %val)
75
76; CHECK: flog2_d_test:
77; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_flog2_d_ARG1)
78; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
79; CHECK-DAG: flog2.d [[WD:\$w[0-9]+]], [[WS]]
80; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_flog2_d_RES)
81; CHECK-DAG: st.d [[WD]], 0([[R2]])
82; CHECK: .size flog2_d_test
83;
84@llvm_mips_frint_w_ARG1 = global <4 x float> <float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, align 16
85@llvm_mips_frint_w_RES  = global <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, align 16
86
87define void @llvm_mips_frint_w_test() nounwind {
88entry:
89  %0 = load <4 x float>* @llvm_mips_frint_w_ARG1
90  %1 = tail call <4 x float> @llvm.mips.frint.w(<4 x float> %0)
91  store <4 x float> %1, <4 x float>* @llvm_mips_frint_w_RES
92  ret void
93}
94
95declare <4 x float> @llvm.mips.frint.w(<4 x float>) nounwind
96
97; CHECK: llvm_mips_frint_w_test:
98; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frint_w_ARG1)
99; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
100; CHECK-DAG: frint.w [[WD:\$w[0-9]+]], [[WS]]
101; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frint_w_RES)
102; CHECK-DAG: st.w [[WD]], 0([[R2]])
103; CHECK: .size llvm_mips_frint_w_test
104;
105@llvm_mips_frint_d_ARG1 = global <2 x double> <double 0.000000e+00, double 1.000000e+00>, align 16
106@llvm_mips_frint_d_RES  = global <2 x double> <double 0.000000e+00, double 0.000000e+00>, align 16
107
108define void @llvm_mips_frint_d_test() nounwind {
109entry:
110  %0 = load <2 x double>* @llvm_mips_frint_d_ARG1
111  %1 = tail call <2 x double> @llvm.mips.frint.d(<2 x double> %0)
112  store <2 x double> %1, <2 x double>* @llvm_mips_frint_d_RES
113  ret void
114}
115
116declare <2 x double> @llvm.mips.frint.d(<2 x double>) nounwind
117
118; CHECK: llvm_mips_frint_d_test:
119; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frint_d_ARG1)
120; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
121; CHECK-DAG: frint.d [[WD:\$w[0-9]+]], [[WS]]
122; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frint_d_RES)
123; CHECK-DAG: st.d [[WD]], 0([[R2]])
124; CHECK: .size llvm_mips_frint_d_test
125
126define void @frint_w_test() nounwind {
127entry:
128  %0 = load <4 x float>* @llvm_mips_frint_w_ARG1
129  %1 = tail call <4 x float> @llvm.rint.v4f32(<4 x float> %0)
130  store <4 x float> %1, <4 x float>* @llvm_mips_frint_w_RES
131  ret void
132}
133
134declare <4 x float> @llvm.rint.v4f32(<4 x float>) nounwind
135
136; CHECK: frint_w_test:
137; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frint_w_ARG1)
138; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
139; CHECK-DAG: frint.w [[WD:\$w[0-9]+]], [[WS]]
140; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frint_w_RES)
141; CHECK-DAG: st.w [[WD]], 0([[R2]])
142; CHECK: .size frint_w_test
143
144define void @frint_d_test() nounwind {
145entry:
146  %0 = load <2 x double>* @llvm_mips_frint_d_ARG1
147  %1 = tail call <2 x double> @llvm.rint.v2f64(<2 x double> %0)
148  store <2 x double> %1, <2 x double>* @llvm_mips_frint_d_RES
149  ret void
150}
151
152declare <2 x double> @llvm.rint.v2f64(<2 x double>) nounwind
153
154; CHECK: frint_d_test:
155; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frint_d_ARG1)
156; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
157; CHECK-DAG: frint.d [[WD:\$w[0-9]+]], [[WS]]
158; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frint_d_RES)
159; CHECK-DAG: st.d [[WD]], 0([[R2]])
160; CHECK: .size frint_d_test
161;
162@llvm_mips_frcp_w_ARG1 = global <4 x float> <float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, align 16
163@llvm_mips_frcp_w_RES  = global <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, align 16
164
165define void @llvm_mips_frcp_w_test() nounwind {
166entry:
167  %0 = load <4 x float>* @llvm_mips_frcp_w_ARG1
168  %1 = tail call <4 x float> @llvm.mips.frcp.w(<4 x float> %0)
169  store <4 x float> %1, <4 x float>* @llvm_mips_frcp_w_RES
170  ret void
171}
172
173declare <4 x float> @llvm.mips.frcp.w(<4 x float>) nounwind
174
175; CHECK: llvm_mips_frcp_w_test:
176; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frcp_w_ARG1)
177; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
178; CHECK-DAG: frcp.w [[WD:\$w[0-9]+]], [[WS]]
179; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frcp_w_RES)
180; CHECK-DAG: st.w [[WD]], 0([[R2]])
181; CHECK: .size llvm_mips_frcp_w_test
182;
183@llvm_mips_frcp_d_ARG1 = global <2 x double> <double 0.000000e+00, double 1.000000e+00>, align 16
184@llvm_mips_frcp_d_RES  = global <2 x double> <double 0.000000e+00, double 0.000000e+00>, align 16
185
186define void @llvm_mips_frcp_d_test() nounwind {
187entry:
188  %0 = load <2 x double>* @llvm_mips_frcp_d_ARG1
189  %1 = tail call <2 x double> @llvm.mips.frcp.d(<2 x double> %0)
190  store <2 x double> %1, <2 x double>* @llvm_mips_frcp_d_RES
191  ret void
192}
193
194declare <2 x double> @llvm.mips.frcp.d(<2 x double>) nounwind
195
196; CHECK: llvm_mips_frcp_d_test:
197; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frcp_d_ARG1)
198; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
199; CHECK-DAG: frcp.d [[WD:\$w[0-9]+]], [[WS]]
200; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frcp_d_RES)
201; CHECK-DAG: st.d [[WD]], 0([[R2]])
202; CHECK: .size llvm_mips_frcp_d_test
203;
204@llvm_mips_frsqrt_w_ARG1 = global <4 x float> <float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, align 16
205@llvm_mips_frsqrt_w_RES  = global <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, align 16
206
207define void @llvm_mips_frsqrt_w_test() nounwind {
208entry:
209  %0 = load <4 x float>* @llvm_mips_frsqrt_w_ARG1
210  %1 = tail call <4 x float> @llvm.mips.frsqrt.w(<4 x float> %0)
211  store <4 x float> %1, <4 x float>* @llvm_mips_frsqrt_w_RES
212  ret void
213}
214
215declare <4 x float> @llvm.mips.frsqrt.w(<4 x float>) nounwind
216
217; CHECK: llvm_mips_frsqrt_w_test:
218; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frsqrt_w_ARG1)
219; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
220; CHECK-DAG: frsqrt.w [[WD:\$w[0-9]+]], [[WS]]
221; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frsqrt_w_RES)
222; CHECK-DAG: st.w [[WD]], 0([[R2]])
223; CHECK: .size llvm_mips_frsqrt_w_test
224;
225@llvm_mips_frsqrt_d_ARG1 = global <2 x double> <double 0.000000e+00, double 1.000000e+00>, align 16
226@llvm_mips_frsqrt_d_RES  = global <2 x double> <double 0.000000e+00, double 0.000000e+00>, align 16
227
228define void @llvm_mips_frsqrt_d_test() nounwind {
229entry:
230  %0 = load <2 x double>* @llvm_mips_frsqrt_d_ARG1
231  %1 = tail call <2 x double> @llvm.mips.frsqrt.d(<2 x double> %0)
232  store <2 x double> %1, <2 x double>* @llvm_mips_frsqrt_d_RES
233  ret void
234}
235
236declare <2 x double> @llvm.mips.frsqrt.d(<2 x double>) nounwind
237
238; CHECK: llvm_mips_frsqrt_d_test:
239; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_frsqrt_d_ARG1)
240; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
241; CHECK-DAG: frsqrt.d [[WD:\$w[0-9]+]], [[WS]]
242; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_frsqrt_d_RES)
243; CHECK-DAG: st.d [[WD]], 0([[R2]])
244; CHECK: .size llvm_mips_frsqrt_d_test
245;
246@llvm_mips_fsqrt_w_ARG1 = global <4 x float> <float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, align 16
247@llvm_mips_fsqrt_w_RES  = global <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, align 16
248
249define void @llvm_mips_fsqrt_w_test() nounwind {
250entry:
251  %0 = load <4 x float>* @llvm_mips_fsqrt_w_ARG1
252  %1 = tail call <4 x float> @llvm.mips.fsqrt.w(<4 x float> %0)
253  store <4 x float> %1, <4 x float>* @llvm_mips_fsqrt_w_RES
254  ret void
255}
256
257declare <4 x float> @llvm.mips.fsqrt.w(<4 x float>) nounwind
258
259; CHECK: llvm_mips_fsqrt_w_test:
260; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_fsqrt_w_ARG1)
261; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
262; CHECK-DAG: fsqrt.w [[WD:\$w[0-9]+]], [[WS]]
263; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_fsqrt_w_RES)
264; CHECK-DAG: st.w [[WD]], 0([[R2]])
265; CHECK: .size llvm_mips_fsqrt_w_test
266;
267@llvm_mips_fsqrt_d_ARG1 = global <2 x double> <double 0.000000e+00, double 1.000000e+00>, align 16
268@llvm_mips_fsqrt_d_RES  = global <2 x double> <double 0.000000e+00, double 0.000000e+00>, align 16
269
270define void @llvm_mips_fsqrt_d_test() nounwind {
271entry:
272  %0 = load <2 x double>* @llvm_mips_fsqrt_d_ARG1
273  %1 = tail call <2 x double> @llvm.mips.fsqrt.d(<2 x double> %0)
274  store <2 x double> %1, <2 x double>* @llvm_mips_fsqrt_d_RES
275  ret void
276}
277
278declare <2 x double> @llvm.mips.fsqrt.d(<2 x double>) nounwind
279
280; CHECK: llvm_mips_fsqrt_d_test:
281; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_fsqrt_d_ARG1)
282; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
283; CHECK-DAG: fsqrt.d [[WD:\$w[0-9]+]], [[WS]]
284; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_fsqrt_d_RES)
285; CHECK-DAG: st.d [[WD]], 0([[R2]])
286; CHECK: .size llvm_mips_fsqrt_d_test
287
288define void @fsqrt_w_test() nounwind {
289entry:
290  %0 = load <4 x float>* @llvm_mips_fsqrt_w_ARG1
291  %1 = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %0)
292  store <4 x float> %1, <4 x float>* @llvm_mips_fsqrt_w_RES
293  ret void
294}
295
296declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) nounwind
297
298; CHECK: fsqrt_w_test:
299; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_fsqrt_w_ARG1)
300; CHECK-DAG: ld.w [[WS:\$w[0-9]+]], 0([[R1]])
301; CHECK-DAG: fsqrt.w [[WD:\$w[0-9]+]], [[WS]]
302; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_fsqrt_w_RES)
303; CHECK-DAG: st.w [[WD]], 0([[R2]])
304; CHECK: .size fsqrt_w_test
305
306define void @fsqrt_d_test() nounwind {
307entry:
308  %0 = load <2 x double>* @llvm_mips_fsqrt_d_ARG1
309  %1 = tail call <2 x double> @llvm.sqrt.v2f64(<2 x double> %0)
310  store <2 x double> %1, <2 x double>* @llvm_mips_fsqrt_d_RES
311  ret void
312}
313
314declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) nounwind
315
316; CHECK: fsqrt_d_test:
317; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_fsqrt_d_ARG1)
318; CHECK-DAG: ld.d [[WS:\$w[0-9]+]], 0([[R1]])
319; CHECK-DAG: fsqrt.d [[WD:\$w[0-9]+]], [[WS]]
320; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_fsqrt_d_RES)
321; CHECK-DAG: st.d [[WD]], 0([[R2]])
322; CHECK: .size fsqrt_d_test
323;
324