• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -march=mips -mattr=+msa,+fp64,+mips32r2 -relocation-model=pic < %s \
2; RUN:   | FileCheck -check-prefixes=ALL,O32 %s
3; RUN: llc -march=mipsel -mattr=+msa,+fp64,+mips32r2 -relocation-model=pic < %s \
4; RUN:   | FileCheck -check-prefixes=ALL,O32 %s
5; RUN: llc -march=mips64 -target-abi=n32 -mattr=+msa,+fp64 -relocation-model=pic < %s \
6; RUN:   | FileCheck -check-prefixes=ALL,N32 %s
7; RUN: llc -march=mips64el -target-abi=n32 -mattr=+msa,+fp64 -relocation-model=pic < %s \
8; RUN:   | FileCheck -check-prefixes=ALL,N32 %s
9; RUN: llc -march=mips64 -mattr=+msa,+fp64 -relocation-model=pic < %s \
10; RUN:   | FileCheck -check-prefixes=ALL,N64 %s
11; RUN: llc -march=mips64el -mattr=+msa,+fp64 -relocation-model=pic < %s \
12; RUN:   | FileCheck -check-prefixes=ALL,N64 %s
13
14@v4f32 = global <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>
15@v2f64 = global <2 x double> <double 0.0, double 0.0>
16@i32 = global i32 0
17@f32 = global float 0.0
18@f64 = global double 0.0
19
20define void @const_v4f32() nounwind {
21  ; ALL-LABEL: const_v4f32:
22
23  store volatile <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, <4 x float>*@v4f32
24  ; ALL: ldi.b  [[R1:\$w[0-9]+]], 0
25
26  store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, <4 x float>*@v4f32
27  ; ALL: lui     [[R1:\$[0-9]+]], 16256
28  ; ALL: fill.w  [[R2:\$w[0-9]+]], [[R1]]
29
30  store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 31.0>, <4 x float>*@v4f32
31  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
32  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
33  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
34  ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
35
36  store volatile <4 x float> <float 65537.0, float 65537.0, float 65537.0, float 65537.0>, <4 x float>*@v4f32
37  ; ALL: lui     [[R1:\$[0-9]+]], 18304
38  ; ALL: ori     [[R2:\$[0-9]+]], [[R1]], 128
39  ; ALL: fill.w  [[R3:\$w[0-9]+]], [[R2]]
40
41  store volatile <4 x float> <float 1.0, float 2.0, float 1.0, float 2.0>, <4 x float>*@v4f32
42  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
43  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
44  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
45  ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
46
47  store volatile <4 x float> <float 3.0, float 4.0, float 5.0, float 6.0>, <4 x float>*@v4f32
48  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
49  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
50  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
51  ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
52
53  ret void
54}
55
56define void @const_v2f64() nounwind {
57  ; ALL-LABEL: const_v2f64:
58
59  store volatile <2 x double> <double 0.0, double 0.0>, <2 x double>*@v2f64
60  ; ALL: ldi.b  [[R1:\$w[0-9]+]], 0
61
62  store volatile <2 x double> <double 72340172838076673.0, double 72340172838076673.0>, <2 x double>*@v2f64
63  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
64  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
65  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
66  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
67
68  store volatile <2 x double> <double 281479271743489.0, double 281479271743489.0>, <2 x double>*@v2f64
69  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
70  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
71  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
72  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
73
74  store volatile <2 x double> <double 4294967297.0, double 4294967297.0>, <2 x double>*@v2f64
75  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
76  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
77  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
78  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
79
80  store volatile <2 x double> <double 1.0, double 1.0>, <2 x double>*@v2f64
81  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
82  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
83  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
84  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
85
86  store volatile <2 x double> <double 1.0, double 31.0>, <2 x double>*@v2f64
87  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
88  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
89  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
90  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
91
92  store volatile <2 x double> <double 3.0, double 4.0>, <2 x double>*@v2f64
93  ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
94  ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
95  ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
96  ; ALL: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
97
98  ret void
99}
100
101define void @nonconst_v4f32() nounwind {
102  ; ALL-LABEL: nonconst_v4f32:
103
104  %1 = load float , float *@f32
105  %2 = insertelement <4 x float> undef, float %1, i32 0
106  %3 = insertelement <4 x float> %2, float %1, i32 1
107  %4 = insertelement <4 x float> %3, float %1, i32 2
108  %5 = insertelement <4 x float> %4, float %1, i32 3
109  store volatile <4 x float> %5, <4 x float>*@v4f32
110  ; ALL: lwc1 $f[[R1:[0-9]+]], 0(
111  ; ALL: splati.w [[R2:\$w[0-9]+]], $w[[R1]]
112
113  ret void
114}
115
116define void @nonconst_v2f64() nounwind {
117  ; ALL-LABEL: nonconst_v2f64:
118
119  %1 = load double , double *@f64
120  %2 = insertelement <2 x double> undef, double %1, i32 0
121  %3 = insertelement <2 x double> %2, double %1, i32 1
122  store volatile <2 x double> %3, <2 x double>*@v2f64
123  ; ALL: ldc1 $f[[R1:[0-9]+]], 0(
124  ; ALL: splati.d [[R2:\$w[0-9]+]], $w[[R1]]
125
126  ret void
127}
128
129define float @extract_v4f32() nounwind {
130  ; ALL-LABEL: extract_v4f32:
131
132  %1 = load <4 x float>, <4 x float>* @v4f32
133  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
134
135  %2 = fadd <4 x float> %1, %1
136  ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
137
138  %3 = extractelement <4 x float> %2, i32 1
139  ; Element 1 can be obtained by splatting it across the vector and extracting
140  ; $w0:sub_lo
141  ; ALL-DAG: splati.w $w0, [[R1]][1]
142
143  ret float %3
144}
145
146define float @extract_v4f32_elt0() nounwind {
147  ; ALL-LABEL: extract_v4f32_elt0:
148
149  %1 = load <4 x float>, <4 x float>* @v4f32
150  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
151
152  %2 = fadd <4 x float> %1, %1
153  ; ALL-DAG: fadd.w $w0, [[R1]], [[R1]]
154
155  %3 = extractelement <4 x float> %2, i32 0
156  ; Element 0 can be obtained by extracting $w0:sub_lo ($f0)
157  ; ALL-NOT: copy_u.w
158  ; ALL-NOT: mtc1
159
160  ret float %3
161}
162
163define float @extract_v4f32_elt2() nounwind {
164  ; ALL-LABEL: extract_v4f32_elt2:
165
166  %1 = load <4 x float>, <4 x float>* @v4f32
167  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
168
169  %2 = fadd <4 x float> %1, %1
170  ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
171
172  %3 = extractelement <4 x float> %2, i32 2
173  ; Element 2 can be obtained by splatting it across the vector and extracting
174  ; $w0:sub_lo
175  ; ALL-DAG: splati.w $w0, [[R1]][2]
176
177  ret float %3
178}
179
180define float @extract_v4f32_vidx() nounwind {
181  ; ALL-LABEL: extract_v4f32_vidx:
182
183  %1 = load <4 x float>, <4 x float>* @v4f32
184  ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)(
185  ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
186  ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
187  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
188
189  %2 = fadd <4 x float> %1, %1
190  ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
191
192  %3 = load i32, i32* @i32
193  ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
194  ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
195  ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
196  ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
197
198  %4 = extractelement <4 x float> %2, i32 %3
199  ; ALL-DAG: splat.w $w0, [[R1]]{{\[}}[[IDX]]]
200
201  ret float %4
202}
203
204define double @extract_v2f64() nounwind {
205  ; ALL-LABEL: extract_v2f64:
206
207  %1 = load <2 x double>, <2 x double>* @v2f64
208  ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
209
210  %2 = fadd <2 x double> %1, %1
211  ; ALL-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
212
213  %3 = extractelement <2 x double> %2, i32 1
214  ; Element 1 can be obtained by splatting it across the vector and extracting
215  ; $w0:sub_64
216  ; ALL-DAG: splati.d $w0, [[R1]][1]
217  ; ALL-NOT: copy_u.w
218  ; ALL-NOT: mtc1
219  ; ALL-NOT: mthc1
220  ; ALL-NOT: sll
221  ; ALL-NOT: sra
222
223  ret double %3
224}
225
226define double @extract_v2f64_elt0() nounwind {
227  ; ALL-LABEL: extract_v2f64_elt0:
228
229  %1 = load <2 x double>, <2 x double>* @v2f64
230  ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
231
232  %2 = fadd <2 x double> %1, %1
233  ; ALL-DAG: fadd.d $w0, [[R1]], [[R1]]
234
235  %3 = extractelement <2 x double> %2, i32 0
236  ; Element 0 can be obtained by extracting $w0:sub_64 ($f0)
237  ; ALL-NOT: copy_u.w
238  ; ALL-NOT: mtc1
239  ; ALL-NOT: mthc1
240  ; ALL-NOT: sll
241  ; ALL-NOT: sra
242
243  ret double %3
244}
245
246define double @extract_v2f64_vidx() nounwind {
247  ; ALL-LABEL: extract_v2f64_vidx:
248
249  %1 = load <2 x double>, <2 x double>* @v2f64
250  ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)(
251  ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
252  ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
253  ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
254
255  %2 = fadd <2 x double> %1, %1
256  ; ALL-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
257
258  %3 = load i32, i32* @i32
259  ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
260  ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
261  ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
262  ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
263
264  %4 = extractelement <2 x double> %2, i32 %3
265  ; ALL-DAG: splat.d $w0, [[R1]]{{\[}}[[IDX]]]
266
267  ret double %4
268}
269
270define void @insert_v4f32(float %a) nounwind {
271  ; ALL-LABEL: insert_v4f32:
272
273  %1 = load <4 x float>, <4 x float>* @v4f32
274  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
275
276  %2 = insertelement <4 x float> %1, float %a, i32 1
277  ; float argument passed in $f12
278  ; ALL-DAG: insve.w [[R1]][1], $w12[0]
279
280  store <4 x float> %2, <4 x float>* @v4f32
281  ; ALL-DAG: st.w [[R1]]
282
283  ret void
284}
285
286define void @insert_v2f64(double %a) nounwind {
287  ; ALL-LABEL: insert_v2f64:
288
289  %1 = load <2 x double>, <2 x double>* @v2f64
290  ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
291
292  %2 = insertelement <2 x double> %1, double %a, i32 1
293  ; double argument passed in $f12
294  ; ALL-DAG: insve.d [[R1]][1], $w12[0]
295
296  store <2 x double> %2, <2 x double>* @v2f64
297  ; ALL-DAG: st.d [[R1]]
298
299  ret void
300}
301
302define void @insert_v4f32_vidx(float %a) nounwind {
303  ; ALL-LABEL: insert_v4f32_vidx:
304
305  %1 = load <4 x float>, <4 x float>* @v4f32
306  ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)(
307  ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
308  ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
309  ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
310
311  %2 = load i32, i32* @i32
312  ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
313  ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
314  ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
315  ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
316
317  %3 = insertelement <4 x float> %1, float %a, i32 %2
318  ; float argument passed in $f12
319  ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2
320  ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
321  ; ALL-DAG: insve.w [[R1]][0], $w12[0]
322  ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
323  ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
324
325  store <4 x float> %3, <4 x float>* @v4f32
326  ; ALL-DAG: st.w [[R1]]
327
328  ret void
329}
330
331define void @insert_v2f64_vidx(double %a) nounwind {
332  ; ALL-LABEL: insert_v2f64_vidx:
333
334  %1 = load <2 x double>, <2 x double>* @v2f64
335  ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)(
336  ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
337  ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
338  ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
339
340  %2 = load i32, i32* @i32
341  ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
342  ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
343  ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
344  ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
345
346  %3 = insertelement <2 x double> %1, double %a, i32 %2
347  ; double argument passed in $f12
348  ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 3
349  ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
350  ; ALL-DAG: insve.d [[R1]][0], $w12[0]
351  ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
352  ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
353
354  store <2 x double> %3, <2 x double>* @v2f64
355  ; ALL-DAG: st.d [[R1]]
356
357  ret void
358}
359