~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to test/CodeGen/ARM/vdup.ll

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+neon -verify-machineinstrs %s -o - \
 
2
; RUN:  | FileCheck %s
 
3
 
 
4
define <8 x i8> @v_dup8(i8 %A) nounwind {
 
5
;CHECK-LABEL: v_dup8:
 
6
;CHECK: vdup.8
 
7
        %tmp1 = insertelement <8 x i8> zeroinitializer, i8 %A, i32 0
 
8
        %tmp2 = insertelement <8 x i8> %tmp1, i8 %A, i32 1
 
9
        %tmp3 = insertelement <8 x i8> %tmp2, i8 %A, i32 2
 
10
        %tmp4 = insertelement <8 x i8> %tmp3, i8 %A, i32 3
 
11
        %tmp5 = insertelement <8 x i8> %tmp4, i8 %A, i32 4
 
12
        %tmp6 = insertelement <8 x i8> %tmp5, i8 %A, i32 5
 
13
        %tmp7 = insertelement <8 x i8> %tmp6, i8 %A, i32 6
 
14
        %tmp8 = insertelement <8 x i8> %tmp7, i8 %A, i32 7
 
15
        ret <8 x i8> %tmp8
 
16
}
 
17
 
 
18
define <4 x i16> @v_dup16(i16 %A) nounwind {
 
19
;CHECK-LABEL: v_dup16:
 
20
;CHECK: vdup.16
 
21
        %tmp1 = insertelement <4 x i16> zeroinitializer, i16 %A, i32 0
 
22
        %tmp2 = insertelement <4 x i16> %tmp1, i16 %A, i32 1
 
23
        %tmp3 = insertelement <4 x i16> %tmp2, i16 %A, i32 2
 
24
        %tmp4 = insertelement <4 x i16> %tmp3, i16 %A, i32 3
 
25
        ret <4 x i16> %tmp4
 
26
}
 
27
 
 
28
define <2 x i32> @v_dup32(i32 %A) nounwind {
 
29
;CHECK-LABEL: v_dup32:
 
30
;CHECK: vdup.32
 
31
        %tmp1 = insertelement <2 x i32> zeroinitializer, i32 %A, i32 0
 
32
        %tmp2 = insertelement <2 x i32> %tmp1, i32 %A, i32 1
 
33
        ret <2 x i32> %tmp2
 
34
}
 
35
 
 
36
define <2 x float> @v_dupfloat(float %A) nounwind {
 
37
;CHECK-LABEL: v_dupfloat:
 
38
;CHECK: vdup.32
 
39
        %tmp1 = insertelement <2 x float> zeroinitializer, float %A, i32 0
 
40
        %tmp2 = insertelement <2 x float> %tmp1, float %A, i32 1
 
41
        ret <2 x float> %tmp2
 
42
}
 
43
 
 
44
define <16 x i8> @v_dupQ8(i8 %A) nounwind {
 
45
;CHECK-LABEL: v_dupQ8:
 
46
;CHECK: vdup.8
 
47
        %tmp1 = insertelement <16 x i8> zeroinitializer, i8 %A, i32 0
 
48
        %tmp2 = insertelement <16 x i8> %tmp1, i8 %A, i32 1
 
49
        %tmp3 = insertelement <16 x i8> %tmp2, i8 %A, i32 2
 
50
        %tmp4 = insertelement <16 x i8> %tmp3, i8 %A, i32 3
 
51
        %tmp5 = insertelement <16 x i8> %tmp4, i8 %A, i32 4
 
52
        %tmp6 = insertelement <16 x i8> %tmp5, i8 %A, i32 5
 
53
        %tmp7 = insertelement <16 x i8> %tmp6, i8 %A, i32 6
 
54
        %tmp8 = insertelement <16 x i8> %tmp7, i8 %A, i32 7
 
55
        %tmp9 = insertelement <16 x i8> %tmp8, i8 %A, i32 8
 
56
        %tmp10 = insertelement <16 x i8> %tmp9, i8 %A, i32 9
 
57
        %tmp11 = insertelement <16 x i8> %tmp10, i8 %A, i32 10
 
58
        %tmp12 = insertelement <16 x i8> %tmp11, i8 %A, i32 11
 
59
        %tmp13 = insertelement <16 x i8> %tmp12, i8 %A, i32 12
 
60
        %tmp14 = insertelement <16 x i8> %tmp13, i8 %A, i32 13
 
61
        %tmp15 = insertelement <16 x i8> %tmp14, i8 %A, i32 14
 
62
        %tmp16 = insertelement <16 x i8> %tmp15, i8 %A, i32 15
 
63
        ret <16 x i8> %tmp16
 
64
}
 
65
 
 
66
define <8 x i16> @v_dupQ16(i16 %A) nounwind {
 
67
;CHECK-LABEL: v_dupQ16:
 
68
;CHECK: vdup.16
 
69
        %tmp1 = insertelement <8 x i16> zeroinitializer, i16 %A, i32 0
 
70
        %tmp2 = insertelement <8 x i16> %tmp1, i16 %A, i32 1
 
71
        %tmp3 = insertelement <8 x i16> %tmp2, i16 %A, i32 2
 
72
        %tmp4 = insertelement <8 x i16> %tmp3, i16 %A, i32 3
 
73
        %tmp5 = insertelement <8 x i16> %tmp4, i16 %A, i32 4
 
74
        %tmp6 = insertelement <8 x i16> %tmp5, i16 %A, i32 5
 
75
        %tmp7 = insertelement <8 x i16> %tmp6, i16 %A, i32 6
 
76
        %tmp8 = insertelement <8 x i16> %tmp7, i16 %A, i32 7
 
77
        ret <8 x i16> %tmp8
 
78
}
 
79
 
 
80
define <4 x i32> @v_dupQ32(i32 %A) nounwind {
 
81
;CHECK-LABEL: v_dupQ32:
 
82
;CHECK: vdup.32
 
83
        %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %A, i32 0
 
84
        %tmp2 = insertelement <4 x i32> %tmp1, i32 %A, i32 1
 
85
        %tmp3 = insertelement <4 x i32> %tmp2, i32 %A, i32 2
 
86
        %tmp4 = insertelement <4 x i32> %tmp3, i32 %A, i32 3
 
87
        ret <4 x i32> %tmp4
 
88
}
 
89
 
 
90
define <4 x float> @v_dupQfloat(float %A) nounwind {
 
91
;CHECK-LABEL: v_dupQfloat:
 
92
;CHECK: vdup.32
 
93
        %tmp1 = insertelement <4 x float> zeroinitializer, float %A, i32 0
 
94
        %tmp2 = insertelement <4 x float> %tmp1, float %A, i32 1
 
95
        %tmp3 = insertelement <4 x float> %tmp2, float %A, i32 2
 
96
        %tmp4 = insertelement <4 x float> %tmp3, float %A, i32 3
 
97
        ret <4 x float> %tmp4
 
98
}
 
99
 
 
100
; Check to make sure it works with shuffles, too.
 
101
 
 
102
define <8 x i8> @v_shuffledup8(i8 %A) nounwind {
 
103
;CHECK-LABEL: v_shuffledup8:
 
104
;CHECK: vdup.8
 
105
        %tmp1 = insertelement <8 x i8> undef, i8 %A, i32 0
 
106
        %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> zeroinitializer
 
107
        ret <8 x i8> %tmp2
 
108
}
 
109
 
 
110
define <4 x i16> @v_shuffledup16(i16 %A) nounwind {
 
111
;CHECK-LABEL: v_shuffledup16:
 
112
;CHECK: vdup.16
 
113
        %tmp1 = insertelement <4 x i16> undef, i16 %A, i32 0
 
114
        %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> zeroinitializer
 
115
        ret <4 x i16> %tmp2
 
116
}
 
117
 
 
118
define <2 x i32> @v_shuffledup32(i32 %A) nounwind {
 
119
;CHECK-LABEL: v_shuffledup32:
 
120
;CHECK: vdup.32
 
121
        %tmp1 = insertelement <2 x i32> undef, i32 %A, i32 0
 
122
        %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer
 
123
        ret <2 x i32> %tmp2
 
124
}
 
125
 
 
126
define <2 x float> @v_shuffledupfloat(float %A) nounwind {
 
127
;CHECK-LABEL: v_shuffledupfloat:
 
128
;CHECK: vdup.32
 
129
        %tmp1 = insertelement <2 x float> undef, float %A, i32 0
 
130
        %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> zeroinitializer
 
131
        ret <2 x float> %tmp2
 
132
}
 
133
 
 
134
define <16 x i8> @v_shuffledupQ8(i8 %A) nounwind {
 
135
;CHECK-LABEL: v_shuffledupQ8:
 
136
;CHECK: vdup.8
 
137
        %tmp1 = insertelement <16 x i8> undef, i8 %A, i32 0
 
138
        %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> zeroinitializer
 
139
        ret <16 x i8> %tmp2
 
140
}
 
141
 
 
142
define <8 x i16> @v_shuffledupQ16(i16 %A) nounwind {
 
143
;CHECK-LABEL: v_shuffledupQ16:
 
144
;CHECK: vdup.16
 
145
        %tmp1 = insertelement <8 x i16> undef, i16 %A, i32 0
 
146
        %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> zeroinitializer
 
147
        ret <8 x i16> %tmp2
 
148
}
 
149
 
 
150
define <4 x i32> @v_shuffledupQ32(i32 %A) nounwind {
 
151
;CHECK-LABEL: v_shuffledupQ32:
 
152
;CHECK: vdup.32
 
153
        %tmp1 = insertelement <4 x i32> undef, i32 %A, i32 0
 
154
        %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> zeroinitializer
 
155
        ret <4 x i32> %tmp2
 
156
}
 
157
 
 
158
define <4 x float> @v_shuffledupQfloat(float %A) nounwind {
 
159
;CHECK-LABEL: v_shuffledupQfloat:
 
160
;CHECK: vdup.32
 
161
        %tmp1 = insertelement <4 x float> undef, float %A, i32 0
 
162
        %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> zeroinitializer
 
163
        ret <4 x float> %tmp2
 
164
}
 
165
 
 
166
define <8 x i8> @vduplane8(<8 x i8>* %A) nounwind {
 
167
;CHECK-LABEL: vduplane8:
 
168
;CHECK: vdup.8
 
169
        %tmp1 = load <8 x i8>, <8 x i8>* %A
 
170
        %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
 
171
        ret <8 x i8> %tmp2
 
172
}
 
173
 
 
174
define <4 x i16> @vduplane16(<4 x i16>* %A) nounwind {
 
175
;CHECK-LABEL: vduplane16:
 
176
;CHECK: vdup.16
 
177
        %tmp1 = load <4 x i16>, <4 x i16>* %A
 
178
        %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
 
179
        ret <4 x i16> %tmp2
 
180
}
 
181
 
 
182
define <2 x i32> @vduplane32(<2 x i32>* %A) nounwind {
 
183
;CHECK-LABEL: vduplane32:
 
184
;CHECK: vdup.32
 
185
        %tmp1 = load <2 x i32>, <2 x i32>* %A
 
186
        %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> < i32 1, i32 1 >
 
187
        ret <2 x i32> %tmp2
 
188
}
 
189
 
 
190
define <2 x float> @vduplanefloat(<2 x float>* %A) nounwind {
 
191
;CHECK-LABEL: vduplanefloat:
 
192
;CHECK: vdup.32
 
193
        %tmp1 = load <2 x float>, <2 x float>* %A
 
194
        %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> < i32 1, i32 1 >
 
195
        ret <2 x float> %tmp2
 
196
}
 
197
 
 
198
define <16 x i8> @vduplaneQ8(<8 x i8>* %A) nounwind {
 
199
;CHECK-LABEL: vduplaneQ8:
 
200
;CHECK: vdup.8
 
201
        %tmp1 = load <8 x i8>, <8 x i8>* %A
 
202
        %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <16 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
 
203
        ret <16 x i8> %tmp2
 
204
}
 
205
 
 
206
define <8 x i16> @vduplaneQ16(<4 x i16>* %A) nounwind {
 
207
;CHECK-LABEL: vduplaneQ16:
 
208
;CHECK: vdup.16
 
209
        %tmp1 = load <4 x i16>, <4 x i16>* %A
 
210
        %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
 
211
        ret <8 x i16> %tmp2
 
212
}
 
213
 
 
214
define <4 x i32> @vduplaneQ32(<2 x i32>* %A) nounwind {
 
215
;CHECK-LABEL: vduplaneQ32:
 
216
;CHECK: vdup.32
 
217
        %tmp1 = load <2 x i32>, <2 x i32>* %A
 
218
        %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
 
219
        ret <4 x i32> %tmp2
 
220
}
 
221
 
 
222
define <4 x float> @vduplaneQfloat(<2 x float>* %A) nounwind {
 
223
;CHECK-LABEL: vduplaneQfloat:
 
224
;CHECK: vdup.32
 
225
        %tmp1 = load <2 x float>, <2 x float>* %A
 
226
        %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
 
227
        ret <4 x float> %tmp2
 
228
}
 
229
 
 
230
define <2 x i64> @foo(<2 x i64> %arg0_int64x1_t) nounwind readnone {
 
231
entry:
 
232
  %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 1, i32 1>
 
233
  ret <2 x i64> %0
 
234
}
 
235
 
 
236
define <2 x i64> @bar(<2 x i64> %arg0_int64x1_t) nounwind readnone {
 
237
entry:
 
238
  %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
 
239
  ret <2 x i64> %0
 
240
}
 
241
 
 
242
define <2 x double> @baz(<2 x double> %arg0_int64x1_t) nounwind readnone {
 
243
entry:
 
244
  %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 1, i32 1>
 
245
  ret <2 x double> %0
 
246
}
 
247
 
 
248
define <2 x double> @qux(<2 x double> %arg0_int64x1_t) nounwind readnone {
 
249
entry:
 
250
  %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 0, i32 0>
 
251
  ret <2 x double> %0
 
252
}
 
253
 
 
254
; Radar 7373643
 
255
;CHECK-LABEL: redundantVdup:
 
256
;CHECK: vmov.i8
 
257
;CHECK-NOT: vdup.8
 
258
;CHECK: vstr
 
259
define void @redundantVdup(<8 x i8>* %ptr) nounwind {
 
260
  %1 = insertelement <8 x i8> undef, i8 -128, i32 0
 
261
  %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer
 
262
  store <8 x i8> %2, <8 x i8>* %ptr, align 8
 
263
  ret void
 
264
}
 
265
 
 
266
define <4 x i32> @tdupi(i32 %x, i32 %y) {
 
267
;CHECK-LABEL: tdupi:
 
268
;CHECK: vdup.32
 
269
  %1 = insertelement <4 x i32> undef, i32 %x, i32 0
 
270
  %2 = insertelement <4 x i32> %1, i32 %x, i32 1
 
271
  %3 = insertelement <4 x i32> %2, i32 %x, i32 2
 
272
  %4 = insertelement <4 x i32> %3, i32 %y, i32 3
 
273
  ret <4 x i32> %4
 
274
}
 
275
 
 
276
define <4 x float> @tdupf(float %x, float %y) {
 
277
;CHECK-LABEL: tdupf:
 
278
;CHECK: vdup.32
 
279
  %1 = insertelement <4 x float> undef, float %x, i32 0
 
280
  %2 = insertelement <4 x float> %1, float %x, i32 1
 
281
  %3 = insertelement <4 x float> %2, float %x, i32 2
 
282
  %4 = insertelement <4 x float> %3, float %y, i32 3
 
283
  ret <4 x float> %4
 
284
}
 
285
 
 
286
; This test checks that when splatting an element from a vector into another,
 
287
; the value isn't moved out to GPRs first.
 
288
define <4 x i32> @tduplane(<4 x i32> %invec) {
 
289
;CHECK-LABEL: tduplane:
 
290
;CHECK-NOT: vmov {{.*}}, d16[1]
 
291
;CHECK: vdup.32 {{.*}}, d16[1]
 
292
  %in = extractelement <4 x i32> %invec, i32 1
 
293
  %1 = insertelement <4 x i32> undef, i32 %in, i32 0
 
294
  %2 = insertelement <4 x i32> %1, i32 %in, i32 1
 
295
  %3 = insertelement <4 x i32> %2, i32 %in, i32 2
 
296
  %4 = insertelement <4 x i32> %3, i32 255, i32 3
 
297
  ret <4 x i32> %4
 
298
}
 
299
 
 
300
define <2 x float> @check_f32(<4 x float> %v) nounwind {
 
301
;CHECK-LABEL: check_f32:
 
302
;CHECK: vdup.32 {{.*}}, d{{..}}[1]
 
303
  %x = extractelement <4 x float> %v, i32 3
 
304
  %1 = insertelement  <2 x float> undef, float %x, i32 0
 
305
  %2 = insertelement  <2 x float> %1, float %x, i32 1
 
306
  ret <2 x float> %2
 
307
}
 
308
 
 
309
define <2 x i32> @check_i32(<4 x i32> %v) nounwind {
 
310
;CHECK-LABEL: check_i32:
 
311
;CHECK: vdup.32 {{.*}}, d{{..}}[1]
 
312
  %x = extractelement <4 x i32> %v, i32 3
 
313
  %1 = insertelement  <2 x i32> undef, i32 %x, i32 0
 
314
  %2 = insertelement  <2 x i32> %1, i32 %x, i32 1
 
315
  ret <2 x i32> %2
 
316
}
 
317
 
 
318
define <4 x i16> @check_i16(<8 x i16> %v) nounwind {
 
319
;CHECK-LABEL: check_i16:
 
320
;CHECK: vdup.16 {{.*}}, d{{..}}[3]
 
321
  %x = extractelement <8 x i16> %v, i32 3
 
322
  %1 = insertelement  <4 x i16> undef, i16 %x, i32 0
 
323
  %2 = insertelement  <4 x i16> %1, i16 %x, i32 1
 
324
  ret <4 x i16> %2
 
325
}
 
326
 
 
327
define <8 x i8> @check_i8(<16 x i8> %v) nounwind {
 
328
;CHECK-LABEL: check_i8:
 
329
;CHECK: vdup.8 {{.*}}, d{{..}}[3]
 
330
  %x = extractelement <16 x i8> %v, i32 3
 
331
  %1 = insertelement  <8  x i8> undef, i8 %x, i32 0
 
332
  %2 = insertelement  <8  x i8> %1, i8 %x, i32 1
 
333
  ret <8 x i8> %2
 
334
}
 
335
 
 
336
; Check that an SPR splat produces a vdup.
 
337
 
 
338
define <2 x float> @check_spr_splat2(<2 x float> %p, i16 %q) {
 
339
;CHECK-LABEL: check_spr_splat2:
 
340
;CHECK: vdup.32 d
 
341
  %conv = sitofp i16 %q to float
 
342
  %splat.splatinsert = insertelement <2 x float> undef, float %conv, i32 0
 
343
  %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> undef, <2 x i32> zeroinitializer
 
344
  %sub = fsub <2 x float> %splat.splat, %p
 
345
  ret <2 x float> %sub
 
346
}
 
347
 
 
348
define <4 x float> @check_spr_splat4(<4 x float> %p, i16 %q) {
 
349
;CHECK-LABEL: check_spr_splat4:
 
350
;CHECK: vld1.16
 
351
  %conv = sitofp i16 %q to float
 
352
  %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 0
 
353
  %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer
 
354
  %sub = fsub <4 x float> %splat.splat, %p
 
355
  ret <4 x float> %sub
 
356
}
 
357
; Same codegen as above test; scalar is splatted using vld1, so shuffle index is irrelevant.
 
358
define <4 x float> @check_spr_splat4_lane1(<4 x float> %p, i16 %q) {
 
359
;CHECK-LABEL: check_spr_splat4_lane1:
 
360
;CHECK: vld1.16
 
361
  %conv = sitofp i16 %q to float
 
362
  %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 1
 
363
  %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
 
364
  %sub = fsub <4 x float> %splat.splat, %p
 
365
  ret <4 x float> %sub
 
366
}