1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext | FileCheck %s --check-prefixes CHECK,SIMD128
2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128,+sign-ext | FileCheck %s --check-prefixes CHECK,SIMD128-VM
3; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128,+sign-ext | FileCheck %s --check-prefixes CHECK,NO-SIMD128
4
5; Test that basic SIMD128 vector manipulation operations assemble as expected.
6
7target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
8target triple = "wasm32-unknown-unknown"
9
10; ==============================================================================
11; 16 x i8
12; ==============================================================================
13; CHECK-LABEL: const_v16i8:
14; NO-SIMD128-NOT: i8x16
15; SIMD128-NEXT: .result v128{{$}}
16; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=,
17; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
18; SIMD128-NEXT: return $pop[[R]]{{$}}
19define <16 x i8> @const_v16i8() {
20  ret <16 x i8> <i8 00, i8 01, i8 02, i8 03, i8 04, i8 05, i8 06, i8 07,
21                 i8 08, i8 09, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>
22}
23
24; CHECK-LABEL: splat_v16i8:
25; NO-SIMD128-NOT: i8x16
26; SIMD128-NEXT: .param i32{{$}}
27; SIMD128-NEXT: .result v128{{$}}
28; SIMD128-NEXT: i8x16.splat $push[[R:[0-9]+]]=, $0{{$}}
29; SIMD128-NEXT: return $pop[[R]]{{$}}
30define <16 x i8> @splat_v16i8(i8 %x) {
31  %v = insertelement <16 x i8> undef, i8 %x, i32 0
32  %res = shufflevector <16 x i8> %v, <16 x i8> undef,
33    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
34                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
35  ret <16 x i8> %res
36}
37
38; CHECK-LABEL: const_splat_v16i8:
39; SIMD128: i8x16.splat
40define <16 x i8> @const_splat_v16i8() {
41  ret <16 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42,
42                 i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
43}
44
45; CHECK-LABEL: extract_v16i8_s:
46; NO-SIMD128-NOT: i8x16
47; SIMD128-NEXT: .param v128{{$}}
48; SIMD128-NEXT: .result i32{{$}}
49; SIMD128-NEXT: i8x16.extract_lane_s $push[[R:[0-9]+]]=, $0, 13{{$}}
50; SIMD128-NEXT: return $pop[[R]]{{$}}
51define i32 @extract_v16i8_s(<16 x i8> %v) {
52  %elem = extractelement <16 x i8> %v, i8 13
53  %a = sext i8 %elem to i32
54  ret i32 %a
55}
56
57; CHECK-LABEL: extract_v16i8_u:
58; NO-SIMD128-NOT: i8x16
59; SIMD128-NEXT: .param v128{{$}}
60; SIMD128-NEXT: .result i32{{$}}
61; SIMD128-NEXT: i8x16.extract_lane_u $push[[R:[0-9]+]]=, $0, 13{{$}}
62; SIMD128-NEXT: return $pop[[R]]{{$}}
63define i32 @extract_v16i8_u(<16 x i8> %v) {
64  %elem = extractelement <16 x i8> %v, i8 13
65  %a = zext i8 %elem to i32
66  ret i32 %a
67}
68
69; CHECK-LABEL: extract_v16i8:
70; NO-SIMD128-NOT: i8x16
71; SIMD128-NEXT: .param v128{{$}}
72; SIMD128-NEXT: .result i32{{$}}
73; SIMD128-NEXT: i8x16.extract_lane_u $push[[R:[0-9]+]]=, $0, 13{{$}}
74; SIMD128-NEXT: return $pop[[R]]{{$}}
75define i8 @extract_v16i8(<16 x i8> %v) {
76  %elem = extractelement <16 x i8> %v, i8 13
77  ret i8 %elem
78}
79
80; CHECK-LABEL: replace_v16i8:
81; NO-SIMD128-NOT: i8x16
82; SIMD128-NEXT: .param v128, i32{{$}}
83; SIMD128-NEXT: .result v128{{$}}
84; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $0, 11, $1{{$}}
85; SIMD128-NEXT: return $pop[[R]]{{$}}
86define <16 x i8> @replace_v16i8(<16 x i8> %v, i8 %x) {
87  %res = insertelement <16 x i8> %v, i8 %x, i32 11
88  ret <16 x i8> %res
89}
90
91; CHECK-LABEL: shuffle_v16i8:
92; NO-SIMD128-NOT: v8x16
93; SIMD128-NEXT: .param v128, v128{{$}}
94; SIMD128-NEXT: .result v128{{$}}
95; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
96; SIMD128-SAME: 0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31{{$}}
97; SIMD128-NEXT: return $pop[[R]]{{$}}
98define <16 x i8> @shuffle_v16i8(<16 x i8> %x, <16 x i8> %y) {
99  %res = shufflevector <16 x i8> %x, <16 x i8> %y,
100    <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23,
101                i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31>
102  ret <16 x i8> %res
103}
104
105; CHECK-LABEL: build_v16i8:
106; NO-SIMD128-NOT: i8x16
107; SIMD128-NEXT: .param i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}}
108; SIMD128-NEXT: .result v128{{$}}
109; SIMD128-NEXT: i8x16.splat $push[[L0:[0-9]+]]=, $0{{$}}
110; SIMD128-NEXT: i8x16.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
111; SIMD128-NEXT: i8x16.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}}
112; SIMD128-NEXT: i8x16.replace_lane $push[[L3:[0-9]+]]=, $pop[[L2]], 3, $3{{$}}
113; SIMD128-NEXT: i8x16.replace_lane $push[[L4:[0-9]+]]=, $pop[[L3]], 4, $4{{$}}
114; SIMD128-NEXT: i8x16.replace_lane $push[[L5:[0-9]+]]=, $pop[[L4]], 5, $5{{$}}
115; SIMD128-NEXT: i8x16.replace_lane $push[[L6:[0-9]+]]=, $pop[[L5]], 6, $6{{$}}
116; SIMD128-NEXT: i8x16.replace_lane $push[[L7:[0-9]+]]=, $pop[[L6]], 7, $7{{$}}
117; SIMD128-NEXT: i8x16.replace_lane $push[[L8:[0-9]+]]=, $pop[[L7]], 8, $8{{$}}
118; SIMD128-NEXT: i8x16.replace_lane $push[[L9:[0-9]+]]=, $pop[[L8]], 9, $9{{$}}
119; SIMD128-NEXT: i8x16.replace_lane $push[[L10:[0-9]+]]=, $pop[[L9]], 10, $10{{$}}
120; SIMD128-NEXT: i8x16.replace_lane $push[[L11:[0-9]+]]=, $pop[[L10]], 11, $11{{$}}
121; SIMD128-NEXT: i8x16.replace_lane $push[[L12:[0-9]+]]=, $pop[[L11]], 12, $12{{$}}
122; SIMD128-NEXT: i8x16.replace_lane $push[[L13:[0-9]+]]=, $pop[[L12]], 13, $13{{$}}
123; SIMD128-NEXT: i8x16.replace_lane $push[[L14:[0-9]+]]=, $pop[[L13]], 14, $14{{$}}
124; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L14]], 15, $15{{$}}
125; SIMD128-NEXT: return $pop[[R]]{{$}}
126define <16 x i8> @build_v16i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3,
127                              i8 %x4, i8 %x5, i8 %x6, i8 %x7,
128                              i8 %x8, i8 %x9, i8 %x10, i8 %x11,
129                              i8 %x12, i8 %x13, i8 %x14, i8 %x15) {
130  %t0 = insertelement <16 x i8> undef, i8 %x0, i32 0
131  %t1 = insertelement <16 x i8> %t0, i8 %x1, i32 1
132  %t2 = insertelement <16 x i8> %t1, i8 %x2, i32 2
133  %t3 = insertelement <16 x i8> %t2, i8 %x3, i32 3
134  %t4 = insertelement <16 x i8> %t3, i8 %x4, i32 4
135  %t5 = insertelement <16 x i8> %t4, i8 %x5, i32 5
136  %t6 = insertelement <16 x i8> %t5, i8 %x6, i32 6
137  %t7 = insertelement <16 x i8> %t6, i8 %x7, i32 7
138  %t8 = insertelement <16 x i8> %t7, i8 %x8, i32 8
139  %t9 = insertelement <16 x i8> %t8, i8 %x9, i32 9
140  %t10 = insertelement <16 x i8> %t9, i8 %x10, i32 10
141  %t11 = insertelement <16 x i8> %t10, i8 %x11, i32 11
142  %t12 = insertelement <16 x i8> %t11, i8 %x12, i32 12
143  %t13 = insertelement <16 x i8> %t12, i8 %x13, i32 13
144  %t14 = insertelement <16 x i8> %t13, i8 %x14, i32 14
145  %res = insertelement <16 x i8> %t14, i8 %x15, i32 15
146  ret <16 x i8> %res
147}
148
149; ==============================================================================
150; 8 x i16
151; ==============================================================================
152; CHECK-LABEL: const_v8i16:
153; NO-SIMD128-NOT: i16x8
154; SIMD128-NEXT: .result v128{{$}}
155; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 256, 770, 1284, 1798, 2312, 2826, 3340, 3854{{$}}
156; SIMD128-NEXT: return $pop[[R]]{{$}}
157define <8 x i16> @const_v8i16() {
158  ret <8 x i16> <i16 256, i16 770, i16 1284, i16 1798,
159                 i16 2312, i16 2826, i16 3340, i16 3854>
160}
161
162; CHECK-LABEL: splat_v8i16:
163; NO-SIMD128-NOT: i16x8
164; SIMD128-NEXT: .param i32{{$}}
165; SIMD128-NEXT: .result v128{{$}}
166; SIMD128-NEXT: i16x8.splat $push[[R:[0-9]+]]=, $0{{$}}
167; SIMD128-NEXT: return $pop[[R]]{{$}}
168define <8 x i16> @splat_v8i16(i16 %x) {
169  %v = insertelement <8 x i16> undef, i16 %x, i32 0
170  %res = shufflevector <8 x i16> %v, <8 x i16> undef,
171    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
172  ret <8 x i16> %res
173}
174
175; CHECK-LABEL: const_splat_v8i16:
176; SIMD128: i16x8.splat
177define <8 x i16> @const_splat_v8i16() {
178  ret <8 x i16> <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
179}
180
181; CHECK-LABEL: extract_v8i16_s:
182; NO-SIMD128-NOT: i16x8
183; SIMD128-NEXT: .param v128{{$}}
184; SIMD128-NEXT: .result i32{{$}}
185; SIMD128-NEXT: i16x8.extract_lane_s $push[[R:[0-9]+]]=, $0, 5{{$}}
186; SIMD128-NEXT: return $pop[[R]]{{$}}
187define i32 @extract_v8i16_s(<8 x i16> %v) {
188  %elem = extractelement <8 x i16> %v, i16 5
189  %a = sext i16 %elem to i32
190  ret i32 %a
191}
192
193; CHECK-LABEL: extract_v8i16_u:
194; NO-SIMD128-NOT: i16x8
195; SIMD128-NEXT: .param v128{{$}}
196; SIMD128-NEXT: .result i32{{$}}
197; SIMD128-NEXT: i16x8.extract_lane_u $push[[R:[0-9]+]]=, $0, 5{{$}}
198; SIMD128-NEXT: return $pop[[R]]{{$}}
199define i32 @extract_v8i16_u(<8 x i16> %v) {
200  %elem = extractelement <8 x i16> %v, i16 5
201  %a = zext i16 %elem to i32
202  ret i32 %a
203}
204
205; CHECK-LABEL: extract_v8i16:
206; NO-SIMD128-NOT: i16x8
207; SIMD128-NEXT: .param v128{{$}}
208; SIMD128-NEXT: .result i32{{$}}
209; SIMD128-NEXT: i16x8.extract_lane_u $push[[R:[0-9]+]]=, $0, 5{{$}}
210; SIMD128-NEXT: return $pop[[R]]{{$}}
211define i16 @extract_v8i16(<8 x i16> %v) {
212  %elem = extractelement <8 x i16> %v, i16 5
213  ret i16 %elem
214}
215
216; CHECK-LABEL: replace_v8i16:
217; NO-SIMD128-NOT: i16x8
218; SIMD128-NEXT: .param v128, i32{{$}}
219; SIMD128-NEXT: .result v128{{$}}
220; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $0, 7, $1{{$}}
221; SIMD128-NEXT: return $pop[[R]]{{$}}
222define <8 x i16> @replace_v8i16(<8 x i16> %v, i16 %x) {
223  %res = insertelement <8 x i16> %v, i16 %x, i32 7
224  ret <8 x i16> %res
225}
226
227; CHECK-LABEL: shuffle_v8i16:
228; NO-SIMD128-NOT: v8x16
229; SIMD128-NEXT: .param v128, v128{{$}}
230; SIMD128-NEXT: .result v128{{$}}
231; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
232; SIMD128-SAME: 0, 1, 18, 19, 4, 5, 22, 23, 8, 9, 26, 27, 12, 13, 30, 31{{$}}
233; SIMD128-NEXT: return $pop[[R]]{{$}}
234define <8 x i16> @shuffle_v8i16(<8 x i16> %x, <8 x i16> %y) {
235  %res = shufflevector <8 x i16> %x, <8 x i16> %y,
236    <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
237  ret <8 x i16> %res
238}
239
240; CHECK-LABEL: build_v8i16:
241; NO-SIMD128-NOT: i16x8
242; SIMD128-NEXT: .param i32, i32, i32, i32, i32, i32, i32, i32{{$}}
243; SIMD128-NEXT: .result v128{{$}}
244; SIMD128-NEXT: i16x8.splat $push[[L0:[0-9]+]]=, $0{{$}}
245; SIMD128-NEXT: i16x8.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
246; SIMD128-NEXT: i16x8.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}}
247; SIMD128-NEXT: i16x8.replace_lane $push[[L3:[0-9]+]]=, $pop[[L2]], 3, $3{{$}}
248; SIMD128-NEXT: i16x8.replace_lane $push[[L4:[0-9]+]]=, $pop[[L3]], 4, $4{{$}}
249; SIMD128-NEXT: i16x8.replace_lane $push[[L5:[0-9]+]]=, $pop[[L4]], 5, $5{{$}}
250; SIMD128-NEXT: i16x8.replace_lane $push[[L6:[0-9]+]]=, $pop[[L5]], 6, $6{{$}}
251; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L6]], 7, $7{{$}}
252; SIMD128-NEXT: return $pop[[R]]{{$}}
253define <8 x i16> @build_v8i16(i16 %x0, i16 %x1, i16 %x2, i16 %x3,
254                              i16 %x4, i16 %x5, i16 %x6, i16 %x7) {
255  %t0 = insertelement <8 x i16> undef, i16 %x0, i32 0
256  %t1 = insertelement <8 x i16> %t0, i16 %x1, i32 1
257  %t2 = insertelement <8 x i16> %t1, i16 %x2, i32 2
258  %t3 = insertelement <8 x i16> %t2, i16 %x3, i32 3
259  %t4 = insertelement <8 x i16> %t3, i16 %x4, i32 4
260  %t5 = insertelement <8 x i16> %t4, i16 %x5, i32 5
261  %t6 = insertelement <8 x i16> %t5, i16 %x6, i32 6
262  %res = insertelement <8 x i16> %t6, i16 %x7, i32 7
263  ret <8 x i16> %res
264}
265
266; ==============================================================================
267; 4 x i32
268; ==============================================================================
269; CHECK-LABEL: const_v4i32:
270; NO-SIMD128-NOT: i32x4
271; SIMD128-NEXT: .result v128{{$}}
272; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 50462976, 117835012, 185207048, 252579084{{$}}
273; SIMD128-NEXT: return $pop[[R]]{{$}}
274define <4 x i32> @const_v4i32() {
275  ret <4 x i32> <i32 50462976, i32 117835012, i32 185207048, i32 252579084>
276}
277
278; CHECK-LABEL: splat_v4i32:
279; NO-SIMD128-NOT: i32x4
280; SIMD128-NEXT: .param i32{{$}}
281; SIMD128-NEXT: .result v128{{$}}
282; SIMD128-NEXT: i32x4.splat $push[[R:[0-9]+]]=, $0{{$}}
283; SIMD128-NEXT: return $pop[[R]]{{$}}
284define <4 x i32> @splat_v4i32(i32 %x) {
285  %v = insertelement <4 x i32> undef, i32 %x, i32 0
286  %res = shufflevector <4 x i32> %v, <4 x i32> undef,
287    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
288  ret <4 x i32> %res
289}
290
291; CHECK-LABEL: const_splat_v4i32:
292; SIMD128: i32x4.splat
293define <4 x i32> @const_splat_v4i32() {
294  ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
295}
296
297; CHECK-LABEL: extract_v4i32:
298; NO-SIMD128-NOT: i32x4
299; SIMD128-NEXT: .param v128{{$}}
300; SIMD128-NEXT: .result i32{{$}}
301; SIMD128-NEXT: i32x4.extract_lane $push[[R:[0-9]+]]=, $0, 3{{$}}
302; SIMD128-NEXT: return $pop[[R]]{{$}}
303define i32 @extract_v4i32(<4 x i32> %v) {
304  %elem = extractelement <4 x i32> %v, i32 3
305  ret i32 %elem
306}
307
308; CHECK-LABEL: replace_v4i32:
309; NO-SIMD128-NOT: i32x4
310; SIMD128-NEXT: .param v128, i32{{$}}
311; SIMD128-NEXT: .result v128{{$}}
312; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $0, 2, $1{{$}}
313; SIMD128-NEXT: return $pop[[R]]{{$}}
314define <4 x i32> @replace_v4i32(<4 x i32> %v, i32 %x) {
315  %res = insertelement <4 x i32> %v, i32 %x, i32 2
316  ret <4 x i32> %res
317}
318
319; CHECK-LABEL: shuffle_v4i32:
320; NO-SIMD128-NOT: v8x16
321; SIMD128-NEXT: .param v128, v128{{$}}
322; SIMD128-NEXT: .result v128{{$}}
323; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
324; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31{{$}}
325; SIMD128-NEXT: return $pop[[R]]{{$}}
326define <4 x i32> @shuffle_v4i32(<4 x i32> %x, <4 x i32> %y) {
327  %res = shufflevector <4 x i32> %x, <4 x i32> %y,
328    <4 x i32> <i32 0, i32 5, i32 2, i32 7>
329  ret <4 x i32> %res
330}
331
332; CHECK-LABEL: build_v4i32:
333; NO-SIMD128-NOT: i32x4
334; SIMD128-NEXT: .param i32, i32, i32, i32{{$}}
335; SIMD128-NEXT: .result v128{{$}}
336; SIMD128-NEXT: i32x4.splat $push[[L0:[0-9]+]]=, $0{{$}}
337; SIMD128-NEXT: i32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
338; SIMD128-NEXT: i32x4.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}}
339; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L2]], 3, $3{{$}}
340; SIMD128-NEXT: return $pop[[R]]{{$}}
341define <4 x i32> @build_v4i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
342  %t0 = insertelement <4 x i32> undef, i32 %x0, i32 0
343  %t1 = insertelement <4 x i32> %t0, i32 %x1, i32 1
344  %t2 = insertelement <4 x i32> %t1, i32 %x2, i32 2
345  %res = insertelement <4 x i32> %t2, i32 %x3, i32 3
346  ret <4 x i32> %res
347}
348
349; ==============================================================================
350; 2 x i64
351; ==============================================================================
352; CHECK-LABEL: const_v2i64:
353; NO-SIMD128-NOT: i64x2
354; SIMD128-VM-NOT: i64x2
355; SIMD128-NEXT: .result v128{{$}}
356; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 506097522914230528, 1084818905618843912{{$}}
357; SIMD128-NEXT: return $pop[[R]]{{$}}
358define <2 x i64> @const_v2i64() {
359  ret <2 x i64> <i64 506097522914230528, i64 1084818905618843912>
360}
361
362; CHECK-LABEL: splat_v2i64:
363; NO-SIMD128-NOT: i64x2
364; SIMD128-VM-NOT: i64x2
365; SIMD128-NEXT: .param i64{{$}}
366; SIMD128-NEXT: .result v128{{$}}
367; SIMD128-NEXT: i64x2.splat $push[[R:[0-9]+]]=, $0{{$}}
368; SIMD128-NEXT: return $pop[[R]]{{$}}
369define <2 x i64> @splat_v2i64(i64 %x) {
370  %t1 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
371  %res = insertelement <2 x i64> %t1, i64 %x, i32 1
372  ret <2 x i64> %res
373}
374
375; CHECK-LABEL: const_splat_v2i64:
376; SIMD128: i64x2.splat
377define <2 x i64> @const_splat_v2i64() {
378  ret <2 x i64> <i64 42, i64 42>
379}
380
381; CHECK-LABEL: extract_v2i64:
382; NO-SIMD128-NOT: i64x2
383; SIMD128-VM-NOT: i64x2
384; SIMD128-NEXT: .param v128{{$}}
385; SIMD128-NEXT: .result i64{{$}}
386; SIMD128-NEXT: i64x2.extract_lane $push[[R:[0-9]+]]=, $0, 1{{$}}
387; SIMD128-NEXT: return $pop[[R]]{{$}}
388define i64 @extract_v2i64(<2 x i64> %v) {
389  %elem = extractelement <2 x i64> %v, i64 1
390  ret i64 %elem
391}
392
393; CHECK-LABEL: replace_v2i64:
394; NO-SIMD128-NOT: i64x2
395; SIMD128-VM-NOT: i64x2
396; SIMD128-NEXT: .param v128, i64{{$}}
397; SIMD128-NEXT: .result v128{{$}}
398; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $0, 0, $1{{$}}
399; SIMD128-NEXT: return $pop[[R]]{{$}}
400define <2 x i64> @replace_v2i64(<2 x i64> %v, i64 %x) {
401  %res = insertelement <2 x i64> %v, i64 %x, i32 0
402  ret <2 x i64> %res
403}
404
405; CHECK-LABEL: shuffle_v2i64:
406; NO-SIMD128-NOT: v8x16
407; SIMD128-NEXT: .param v128, v128{{$}}
408; SIMD128-NEXT: .result v128{{$}}
409; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
410; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31{{$}}
411; SIMD128-NEXT: return $pop[[R]]{{$}}
412define <2 x i64> @shuffle_v2i64(<2 x i64> %x, <2 x i64> %y) {
413  %res = shufflevector <2 x i64> %x, <2 x i64> %y, <2 x i32> <i32 0, i32 3>
414  ret <2 x i64> %res
415}
416
417; CHECK-LABEL: build_v2i64:
418; NO-SIMD128-NOT: i64x2
419; SIMD128-VM-NOT: i64x2
420; SIMD128-NEXT: .param i64, i64{{$}}
421; SIMD128-NEXT: .result v128{{$}}
422; SIMD128-NEXT: i64x2.splat $push[[L0:[0-9]+]]=, $0{{$}}
423; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
424; SIMD128-NEXT: return $pop[[R]]{{$}}
425define <2 x i64> @build_v2i64(i64 %x0, i64 %x1) {
426  %t0 = insertelement <2 x i64> undef, i64 %x0, i32 0
427  %res = insertelement <2 x i64> %t0, i64 %x1, i32 1
428  ret <2 x i64> %res
429}
430
431; ==============================================================================
432; 4 x f32
433; ==============================================================================
434; CHECK-LABEL: const_v4f32:
435; NO-SIMD128-NOT: f32x4
436; SIMD128-NEXT: .result v128{{$}}
437; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=,
438; SIMD128-SAME: 0x1.0402p-121, 0x1.0c0a08p-113, 0x1.14121p-105, 0x1.1c1a18p-97{{$}}
439; SIMD128-NEXT: return $pop[[R]]{{$}}
440define <4 x float> @const_v4f32() {
441  ret <4 x float> <float 0x3860402000000000, float 0x38e0c0a080000000,
442                   float 0x3961412100000000, float 0x39e1c1a180000000>
443}
444
445; CHECK-LABEL: splat_v4f32:
446; NO-SIMD128-NOT: f32x4
447; SIMD128-NEXT: .param f32{{$}}
448; SIMD128-NEXT: .result v128{{$}}
449; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $0{{$}}
450; SIMD128-NEXT: return $pop[[R]]{{$}}
451define <4 x float> @splat_v4f32(float %x) {
452  %v = insertelement <4 x float> undef, float %x, i32 0
453  %res = shufflevector <4 x float> %v, <4 x float> undef,
454    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
455  ret <4 x float> %res
456}
457
458; CHECK-LABEL: const_splat_v4f32
459; SIMD128: f32x4.splat
460define <4 x float> @const_splat_v4f32() {
461  ret <4 x float> <float 42., float 42., float 42., float 42.>
462}
463
464; CHECK-LABEL: extract_v4f32:
465; NO-SIMD128-NOT: f32x4
466; SIMD128-NEXT: .param v128{{$}}
467; SIMD128-NEXT: .result f32{{$}}
468; SIMD128-NEXT: f32x4.extract_lane $push[[R:[0-9]+]]=, $0, 3{{$}}
469; SIMD128-NEXT: return $pop[[R]]{{$}}
470define float @extract_v4f32(<4 x float> %v) {
471  %elem = extractelement <4 x float> %v, i32 3
472  ret float %elem
473}
474
475; CHECK-LABEL: replace_v4f32:
476; NO-SIMD128-NOT: f32x4
477; SIMD128-NEXT: .param v128, f32{{$}}
478; SIMD128-NEXT: .result v128{{$}}
479; SIMD128-NEXT: f32x4.replace_lane $push[[R:[0-9]+]]=, $0, 2, $1{{$}}
480; SIMD128-NEXT: return $pop[[R]]{{$}}
481define <4 x float> @replace_v4f32(<4 x float> %v, float %x) {
482  %res = insertelement <4 x float> %v, float %x, i32 2
483  ret <4 x float> %res
484}
485
486; CHECK-LABEL: shuffle_v4f32:
487; NO-SIMD128-NOT: v8x16
488; SIMD128-NEXT: .param v128, v128{{$}}
489; SIMD128-NEXT: .result v128{{$}}
490; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
491; SIMD128-SAME: 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31{{$}}
492; SIMD128-NEXT: return $pop[[R]]{{$}}
493define <4 x float> @shuffle_v4f32(<4 x float> %x, <4 x float> %y) {
494  %res = shufflevector <4 x float> %x, <4 x float> %y,
495    <4 x i32> <i32 0, i32 5, i32 2, i32 7>
496  ret <4 x float> %res
497}
498
499; CHECK-LABEL: build_v4f32:
500; NO-SIMD128-NOT: f32x4
501; SIMD128-NEXT: .param f32, f32, f32, f32{{$}}
502; SIMD128-NEXT: .result v128{{$}}
503; SIMD128-NEXT: f32x4.splat $push[[L0:[0-9]+]]=, $0{{$}}
504; SIMD128-NEXT: f32x4.replace_lane $push[[L1:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
505; SIMD128-NEXT: f32x4.replace_lane $push[[L2:[0-9]+]]=, $pop[[L1]], 2, $2{{$}}
506; SIMD128-NEXT: f32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L2]], 3, $3{{$}}
507; SIMD128-NEXT: return $pop[[R]]{{$}}
508define <4 x float> @build_v4f32(float %x0, float %x1, float %x2, float %x3) {
509  %t0 = insertelement <4 x float> undef, float %x0, i32 0
510  %t1 = insertelement <4 x float> %t0, float %x1, i32 1
511  %t2 = insertelement <4 x float> %t1, float %x2, i32 2
512  %res = insertelement <4 x float> %t2, float %x3, i32 3
513  ret <4 x float> %res
514}
515
516; ==============================================================================
517; 2 x f64
518; ==============================================================================
519; CHECK-LABEL: const_v2f64:
520; NO-SIMD128-NOT: f64x2
521; SIMD128-NEXT: .result v128{{$}}
522; SIMD128-NEXT: v128.const $push[[R:[0-9]+]]=, 0x1.60504030201p-911, 0x1.e0d0c0b0a0908p-783{{$}}
523; SIMD128-NEXT: return $pop[[R]]{{$}}
524define <2 x double> @const_v2f64() {
525  ret <2 x double> <double 0x0706050403020100, double 0x0F0E0D0C0B0A0908>
526}
527
528; CHECK-LABEL: splat_v2f64:
529; NO-SIMD128-NOT: f64x2
530; SIMD128-VM-NOT: f64x2
531; SIMD128-NEXT: .param f64{{$}}
532; SIMD128-NEXT: .result v128{{$}}
533; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $0{{$}}
534; SIMD128-NEXT: return $pop[[R]]{{$}}
535define <2 x double> @splat_v2f64(double %x) {
536  %t1 = insertelement <2 x double> zeroinitializer, double %x, i3 0
537  %res = insertelement <2 x double> %t1, double %x, i32 1
538  ret <2 x double> %res
539}
540
541; CHECK-LABEL: const_splat_v2f64:
542; SIMD128: f64x2.splat
543define <2 x double> @const_splat_v2f64() {
544  ret <2 x double> <double 42., double 42.>
545}
546
547; CHECK-LABEL: extract_v2f64:
548; NO-SIMD128-NOT: f64x2
549; SIMD128-VM-NOT: f64x2
550; SIMD128-NEXT: .param v128{{$}}
551; SIMD128-NEXT: .result f64{{$}}
552; SIMD128-NEXT: f64x2.extract_lane $push[[R:[0-9]+]]=, $0, 1{{$}}
553; SIMD128-NEXT: return $pop[[R]]{{$}}
554define double @extract_v2f64(<2 x double> %v) {
555  %elem = extractelement <2 x double> %v, i32 1
556  ret double %elem
557}
558
559; CHECK-LABEL: replace_v2f64:
560; NO-SIMD128-NOT: f64x2
561; SIMD128-VM-NOT: f64x2
562; SIMD128-NEXT: .param v128, f64{{$}}
563; SIMD128-NEXT: .result v128{{$}}
564; SIMD128-NEXT: f64x2.replace_lane $push[[R:[0-9]+]]=, $0, 0, $1{{$}}
565; SIMD128-NEXT: return $pop[[R]]{{$}}
566define <2 x double> @replace_v2f64(<2 x double> %v, double %x) {
567  %res = insertelement <2 x double> %v, double %x, i32 0
568  ret <2 x double> %res
569}
570
571; CHECK-LABEL: shuffle_v2f64:
572; NO-SIMD128-NOT: v8x16
573; SIMD128-NEXT: .param v128, v128{{$}}
574; SIMD128-NEXT: .result v128{{$}}
575; SIMD128-NEXT: v8x16.shuffle $push[[R:[0-9]+]]=, $0, $1,
576; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31{{$}}
577; SIMD128-NEXT: return $pop[[R]]{{$}}
578define <2 x double> @shuffle_v2f64(<2 x double> %x, <2 x double> %y) {
579  %res = shufflevector <2 x double> %x, <2 x double> %y,
580    <2 x i32> <i32 0, i32 3>
581  ret <2 x double> %res
582}
583
584; CHECK-LABEL: build_v2f64:
585; NO-SIMD128-NOT: f64x2
586; SIMD128-VM-NOT: f64x2
587; SIMD128-NEXT: .param f64, f64{{$}}
588; SIMD128-NEXT: .result v128{{$}}
589; SIMD128-NEXT: f64x2.splat $push[[L0:[0-9]+]]=, $0{{$}}
590; SIMD128-NEXT: f64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L0]], 1, $1{{$}}
591; SIMD128-NEXT: return $pop[[R]]{{$}}
592define <2 x double> @build_v2f64(double %x0, double %x1) {
593  %t0 = insertelement <2 x double> undef, double %x0, i32 0
594  %res = insertelement <2 x double> %t0, double %x1, i32 1
595  ret <2 x double> %res
596}
597