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