1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-SLOW
2; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-FAST
3; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128-VM
4; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128-VM
5; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes CHECK,NO-SIMD128
6; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
7
8; check that a non-test run (including explicit locals pass) at least finishes
9; RUN: llc < %s -O0 -mattr=+unimplemented-simd128
10; RUN: llc < %s -O2 -mattr=+unimplemented-simd128
11
12; Test that basic SIMD128 arithmetic operations assemble as expected.
13
14target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
15target triple = "wasm32-unknown-unknown"
16
17; ==============================================================================
18; 16 x i8
19; ==============================================================================
20; CHECK-LABEL: add_v16i8:
21; NO-SIMD128-NOT: i8x16
22; SIMD128-NEXT: .functype add_v16i8 (v128, v128) -> (v128){{$}}
23; SIMD128-NEXT: i8x16.add $push[[R:[0-9]+]]=, $0, $1{{$}}
24; SIMD128-NEXT: return $pop[[R]]{{$}}
25define <16 x i8> @add_v16i8(<16 x i8> %x, <16 x i8> %y) {
26  %a = add <16 x i8> %x, %y
27  ret <16 x i8> %a
28}
29
30; CHECK-LABEL: sub_v16i8:
31; NO-SIMD128-NOT: i8x16
32; SIMD128-NEXT: .functype sub_v16i8 (v128, v128) -> (v128){{$}}
33; SIMD128-NEXT: i8x16.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
34; SIMD128-NEXT: return $pop[[R]]{{$}}
35define <16 x i8> @sub_v16i8(<16 x i8> %x, <16 x i8> %y) {
36  %a = sub <16 x i8> %x, %y
37  ret <16 x i8> %a
38}
39
40; CHECK-LABEL: mul_v16i8:
41; NO-SIMD128-NOT: i8x16
42; SIMD128-NEXT: .functype mul_v16i8 (v128, v128) -> (v128){{$}}
43; SIMD128-NEXT: i8x16.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
44; SIMD128-NEXT: return $pop[[R]]{{$}}
45define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) {
46  %a = mul <16 x i8> %x, %y
47  ret <16 x i8> %a
48}
49
50; CHECK-LABEL: neg_v16i8:
51; NO-SIMD128-NOT: i8x16
52; SIMD128-NEXT: .functype neg_v16i8 (v128) -> (v128){{$}}
53; SIMD128-NEXT: i8x16.neg $push[[R:[0-9]+]]=, $0{{$}}
54; SIMD128-NEXT: return $pop[[R]]{{$}}
55define <16 x i8> @neg_v16i8(<16 x i8> %x) {
56  %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0,
57                      i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>,
58                     %x
59  ret <16 x i8> %a
60}
61
62; CHECK-LABEL: shl_v16i8:
63; NO-SIMD128-NOT: i8x16
64; SIMD128-NEXT: .functype shl_v16i8 (v128, i32) -> (v128){{$}}
65; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
66; SIMD128-NEXT: return $pop[[R]]{{$}}
67define <16 x i8> @shl_v16i8(<16 x i8> %v, i8 %x) {
68  %t = insertelement <16 x i8> undef, i8 %x, i32 0
69  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
70    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
71                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
72  %a = shl <16 x i8> %v, %s
73  ret <16 x i8> %a
74}
75
76; CHECK-LABEL: shl_const_v16i8:
77; NO-SIMD128-NOT: i8x16
78; SIMD128-NEXT: .functype shl_const_v16i8 (v128) -> (v128){{$}}
79; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
80; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
81; SIMD128-NEXT: return $pop[[R]]{{$}}
82define <16 x i8> @shl_const_v16i8(<16 x i8> %v) {
83  %a = shl <16 x i8> %v,
84    <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5,
85     i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
86  ret <16 x i8> %a
87}
88
89; CHECK-LABEL: shl_vec_v16i8:
90; NO-SIMD128-NOT: i8x16
91; SIMD128-NEXT: .functype shl_vec_v16i8 (v128, v128) -> (v128){{$}}
92; SIMD128-NEXT: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
93; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
94; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
95; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
96; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
97; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
98; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
99; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
100; Skip 14 lanes
101; SIMD128:      i8x16.extract_lane_s $push[[L4:[0-9]+]]=, $0, 15{{$}}
102; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}}
103; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
104; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 15, $pop[[L6]]{{$}}
105; SIMD128-NEXT: return $pop[[R]]{{$}}
106define <16 x i8> @shl_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
107  %a = shl <16 x i8> %v, %x
108  ret <16 x i8> %a
109}
110
111; CHECK-LABEL: shr_s_v16i8:
112; NO-SIMD128-NOT: i8x16
113; SIMD128-NEXT: .functype shr_s_v16i8 (v128, i32) -> (v128){{$}}
114; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
115; SIMD128-NEXT: return $pop[[R]]{{$}}
116define <16 x i8> @shr_s_v16i8(<16 x i8> %v, i8 %x) {
117  %t = insertelement <16 x i8> undef, i8 %x, i32 0
118  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
119    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
120                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
121  %a = ashr <16 x i8> %v, %s
122  ret <16 x i8> %a
123}
124
125; CHECK-LABEL: shr_s_vec_v16i8:
126; NO-SIMD128-NOT: i8x16
127; SIMD128-NEXT: .functype shr_s_vec_v16i8 (v128, v128) -> (v128){{$}}
128; SIMD128-NEXT: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
129; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
130; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
131; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
132; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
133; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
134; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
135; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
136; Skip 14 lanes
137; SIMD128:      i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 15{{$}}
138; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $1, 15{{$}}
139; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
140; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop{{[0-9]+}}, 15, $pop[[L2]]{{$}}
141; SIMD128-NEXT: return $pop[[R]]{{$}}
142define <16 x i8> @shr_s_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
143  %a = ashr <16 x i8> %v, %x
144  ret <16 x i8> %a
145}
146
147; CHECK-LABEL: shr_u_v16i8:
148; NO-SIMD128-NOT: i8x16
149; SIMD128-NEXT: .functype shr_u_v16i8 (v128, i32) -> (v128){{$}}
150; SIMD128-NEXT: i8x16.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
151; SIMD128-NEXT: return $pop[[R]]{{$}}
152define <16 x i8> @shr_u_v16i8(<16 x i8> %v, i8 %x) {
153  %t = insertelement <16 x i8> undef, i8 %x, i32 0
154  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
155    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
156                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
157  %a = lshr <16 x i8> %v, %s
158  ret <16 x i8> %a
159}
160
161; CHECK-LABEL: shr_u_vec_v16i8:
162; NO-SIMD128-NOT: i8x16
163; SIMD128-NEXT: .functype shr_u_vec_v16i8 (v128, v128) -> (v128){{$}}
164; SIMD128-NEXT: i8x16.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
165; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
166; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
167; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
168; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
169; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
170; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
171; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
172; Skip 14 lanes
173; SIMD128:      i8x16.extract_lane_u $push[[L4:[0-9]+]]=, $0, 15{{$}}
174; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}}
175; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
176; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 15, $pop[[L6]]{{$}}
177; SIMD128-NEXT: return $pop[[R]]{{$}}
178define <16 x i8> @shr_u_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
179  %a = lshr <16 x i8> %v, %x
180  ret <16 x i8> %a
181}
182
183; CHECK-LABEL: and_v16i8:
184; NO-SIMD128-NOT: v128
185; SIMD128-NEXT: .functype and_v16i8 (v128, v128) -> (v128){{$}}
186; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
187; SIMD128-NEXT: return $pop[[R]]{{$}}
188define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) {
189  %a = and <16 x i8> %x, %y
190  ret <16 x i8> %a
191}
192
193; CHECK-LABEL: or_v16i8:
194; NO-SIMD128-NOT: v128
195; SIMD128-NEXT: .functype or_v16i8 (v128, v128) -> (v128){{$}}
196; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
197; SIMD128-NEXT: return $pop[[R]]{{$}}
198define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) {
199  %a = or <16 x i8> %x, %y
200  ret <16 x i8> %a
201}
202
203; CHECK-LABEL: xor_v16i8:
204; NO-SIMD128-NOT: v128
205; SIMD128-NEXT: .functype xor_v16i8 (v128, v128) -> (v128){{$}}
206; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
207; SIMD128-NEXT: return $pop[[R]]{{$}}
208define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) {
209  %a = xor <16 x i8> %x, %y
210  ret <16 x i8> %a
211}
212
213; CHECK-LABEL: not_v16i8:
214; NO-SIMD128-NOT: v128
215; SIMD128-NEXT: .functype not_v16i8 (v128) -> (v128){{$}}
216; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
217; SIMD128-NEXT: return $pop[[R]]{{$}}
218define <16 x i8> @not_v16i8(<16 x i8> %x) {
219  %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1,
220                          i8 -1, i8 -1, i8 -1, i8 -1,
221                          i8 -1, i8 -1, i8 -1, i8 -1,
222                          i8 -1, i8 -1, i8 -1, i8 -1>
223  ret <16 x i8> %a
224}
225
226; CHECK-LABEL: andnot_v16i8:
227; NO-SIMD128-NOT: v128
228; SIMD128-VM-NOT: v128.andnot
229; SIMD128-NEXT: .functype andnot_v16i8 (v128, v128) -> (v128){{$}}
230; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
231; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
232; SIMD128-FAST-NEXT: v128.not
233; SIMD128-FAST-NEXT: v128.and
234; SIMD128-FAST-NEXT: return
235define <16 x i8> @andnot_v16i8(<16 x i8> %x, <16 x i8> %y) {
236 %inv_y = xor <16 x i8> %y,
237   <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
238    i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
239 %a = and <16 x i8> %x, %inv_y
240 ret <16 x i8> %a
241}
242
243; CHECK-LABEL: bitselect_v16i8:
244; NO-SIMD128-NOT: v128
245; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}}
246; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
247; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
248; SIMD128-FAST-NEXT: v128.and
249; SIMD128-FAST-NEXT: v128.not
250; SIMD128-FAST-NEXT: v128.and
251; SIMD128-FAST-NEXT: v128.or
252; SIMD128-FAST-NEXT: return
253define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) {
254  %masked_v1 = and <16 x i8> %c, %v1
255  %inv_mask = xor <16 x i8> %c,
256    <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
257     i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
258  %masked_v2 = and <16 x i8> %inv_mask, %v2
259  %a = or <16 x i8> %masked_v1, %masked_v2
260  ret <16 x i8> %a
261}
262
263; ==============================================================================
264; 8 x i16
265; ==============================================================================
266; CHECK-LABEL: add_v8i16:
267; NO-SIMD128-NOT: i16x8
268; SIMD128-NEXT: .functype add_v8i16 (v128, v128) -> (v128){{$}}
269; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}}
270; SIMD128-NEXT: return $pop[[R]]{{$}}
271define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) {
272  %a = add <8 x i16> %x, %y
273  ret <8 x i16> %a
274}
275
276; CHECK-LABEL: sub_v8i16:
277; NO-SIMD128-NOT: i16x8
278; SIMD128-NEXT: .functype sub_v8i16 (v128, v128) -> (v128){{$}}
279; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
280; SIMD128-NEXT: return $pop[[R]]{{$}}
281define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) {
282  %a = sub <8 x i16> %x, %y
283  ret <8 x i16> %a
284}
285
286; CHECK-LABEL: mul_v8i16:
287; NO-SIMD128-NOT: i16x8
288; SIMD128-NEXT: .functype mul_v8i16 (v128, v128) -> (v128){{$}}
289; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
290; SIMD128-NEXT: return $pop[[R]]{{$}}
291define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) {
292  %a = mul <8 x i16> %x, %y
293  ret <8 x i16> %a
294}
295
296; CHECK-LABEL: neg_v8i16:
297; NO-SIMD128-NOT: i16x8
298; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}}
299; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}}
300; SIMD128-NEXT: return $pop[[R]]{{$}}
301define <8 x i16> @neg_v8i16(<8 x i16> %x) {
302  %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>,
303                     %x
304  ret <8 x i16> %a
305}
306
307; CHECK-LABEL: shl_v8i16:
308; NO-SIMD128-NOT: i16x8
309; SIMD128-NEXT: .functype shl_v8i16 (v128, i32) -> (v128){{$}}
310; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
311; SIMD128-NEXT: return $pop[[R]]{{$}}
312define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) {
313  %t = insertelement <8 x i16> undef, i16 %x, i32 0
314  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
315    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
316  %a = shl <8 x i16> %v, %s
317  ret <8 x i16> %a
318}
319
320; CHECK-LABEL: shl_const_v8i16:
321; NO-SIMD128-NOT: i16x8
322; SIMD128-NEXT: .functype shl_const_v8i16 (v128) -> (v128){{$}}
323; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
324; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
325; SIMD128-NEXT: return $pop[[R]]{{$}}
326define <8 x i16> @shl_const_v8i16(<8 x i16> %v) {
327  %a = shl <8 x i16> %v,
328    <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
329  ret <8 x i16> %a
330}
331
332; CHECK-LABEL: shl_vec_v8i16:
333; NO-SIMD128-NOT: i16x8
334; SIMD128-NEXT: .functype shl_vec_v8i16 (v128, v128) -> (v128){{$}}
335; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
336; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
337; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
338; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
339; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
340; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
341; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
342; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
343; Skip 6 lanes
344; SIMD128:      i16x8.extract_lane_s $push[[L4:[0-9]+]]=, $0, 7{{$}}
345; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}}
346; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
347; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}}
348; SIMD128-NEXT: return $pop[[R]]{{$}}
349define <8 x i16> @shl_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
350  %a = shl <8 x i16> %v, %x
351  ret <8 x i16> %a
352}
353
354; CHECK-LABEL: shr_s_v8i16:
355; NO-SIMD128-NOT: i16x8
356; SIMD128-NEXT: .functype shr_s_v8i16 (v128, i32) -> (v128){{$}}
357; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
358; SIMD128-NEXT: return $pop[[R]]{{$}}
359define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) {
360  %t = insertelement <8 x i16> undef, i16 %x, i32 0
361  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
362    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
363  %a = ashr <8 x i16> %v, %s
364  ret <8 x i16> %a
365}
366
367; CHECK-LABEL: shr_s_vec_v8i16:
368; NO-SIMD128-NOT: i16x8
369; SIMD128-NEXT: .functype shr_s_vec_v8i16 (v128, v128) -> (v128){{$}}
370; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
371; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
372; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
373; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
374; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
375; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
376; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
377; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
378; Skip 6 lanes
379; SIMD128:      i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 7{{$}}
380; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 7{{$}}
381; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
382; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop{{[0-9]+}}, 7, $pop[[L2]]{{$}}
383; SIMD128-NEXT: return $pop[[R]]{{$}}
384define <8 x i16> @shr_s_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
385  %a = ashr <8 x i16> %v, %x
386  ret <8 x i16> %a
387}
388
389; CHECK-LABEL: shr_u_v8i16:
390; NO-SIMD128-NOT: i16x8
391; SIMD128-NEXT: .functype shr_u_v8i16 (v128, i32) -> (v128){{$}}
392; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
393; SIMD128-NEXT: return $pop[[R]]{{$}}
394define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) {
395  %t = insertelement <8 x i16> undef, i16 %x, i32 0
396  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
397    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
398  %a = lshr <8 x i16> %v, %s
399  ret <8 x i16> %a
400}
401
402; CHECK-LABEL: shr_u_vec_v8i16:
403; NO-SIMD128-NOT: i16x8
404; SIMD128-NEXT: .functype shr_u_vec_v8i16 (v128, v128) -> (v128){{$}}
405; SIMD128-NEXT: i16x8.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
406; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
407; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}}
408; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}}
409; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}}
410; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}}
411; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
412; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
413; Skip 6 lanes
414; SIMD128:      i16x8.extract_lane_u $push[[L4:[0-9]+]]=, $0, 7{{$}}
415; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}}
416; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
417; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}}
418; SIMD128-NEXT: return $pop[[R]]{{$}}
419define <8 x i16> @shr_u_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
420  %a = lshr <8 x i16> %v, %x
421  ret <8 x i16> %a
422}
423
424; CHECK-LABEL: and_v8i16:
425; NO-SIMD128-NOT: v128
426; SIMD128-NEXT: .functype and_v8i16 (v128, v128) -> (v128){{$}}
427; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
428; SIMD128-NEXT: return $pop[[R]]{{$}}
429define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) {
430  %a = and <8 x i16> %x, %y
431  ret <8 x i16> %a
432}
433
434; CHECK-LABEL: or_v8i16:
435; NO-SIMD128-NOT: v128
436; SIMD128-NEXT: .functype or_v8i16 (v128, v128) -> (v128){{$}}
437; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
438; SIMD128-NEXT: return $pop[[R]]{{$}}
439define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) {
440  %a = or <8 x i16> %x, %y
441  ret <8 x i16> %a
442}
443
444; CHECK-LABEL: xor_v8i16:
445; NO-SIMD128-NOT: v128
446; SIMD128-NEXT: .functype xor_v8i16 (v128, v128) -> (v128){{$}}
447; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
448; SIMD128-NEXT: return $pop[[R]]{{$}}
449define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) {
450  %a = xor <8 x i16> %x, %y
451  ret <8 x i16> %a
452}
453
454; CHECK-LABEL: not_v8i16:
455; NO-SIMD128-NOT: v128
456; SIMD128-NEXT: .functype not_v8i16 (v128) -> (v128){{$}}
457; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
458; SIMD128-NEXT: return $pop[[R]]{{$}}
459define <8 x i16> @not_v8i16(<8 x i16> %x) {
460  %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1,
461                          i16 -1, i16 -1, i16 -1, i16 -1>
462  ret <8 x i16> %a
463}
464
465; CHECK-LABEL: andnot_v8i16:
466; SIMD128-VM-NOT: v128.andnot
467; NO-SIMD128-NOT: v128
468; SIMD128-NEXT: .functype andnot_v8i16 (v128, v128) -> (v128){{$}}
469; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
470; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
471; SIMD128-FAST-NEXT: v128.not
472; SIMD128-FAST-NEXT: v128.and
473; SIMD128-FAST-NEXT: return
474define <8 x i16> @andnot_v8i16(<8 x i16> %x, <8 x i16> %y) {
475 %inv_y = xor <8 x i16> %y,
476   <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
477 %a = and <8 x i16> %x, %inv_y
478 ret <8 x i16> %a
479}
480
481; CHECK-LABEL: bitselect_v8i16:
482; NO-SIMD128-NOT: v128
483; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}}
484; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
485; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
486; SIMD128-FAST-NEXT: v128.and
487; SIMD128-FAST-NEXT: v128.not
488; SIMD128-FAST-NEXT: v128.and
489; SIMD128-FAST-NEXT: v128.or
490; SIMD128-FAST-NEXT: return
491define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) {
492  %masked_v1 = and <8 x i16> %v1, %c
493  %inv_mask = xor <8 x i16>
494    <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>,
495    %c
496  %masked_v2 = and <8 x i16> %v2, %inv_mask
497  %a = or <8 x i16> %masked_v1, %masked_v2
498  ret <8 x i16> %a
499}
500
501; ==============================================================================
502; 4 x i32
503; ==============================================================================
504; CHECK-LABEL: add_v4i32:
505; NO-SIMD128-NOT: i32x4
506; SIMD128-NEXT: .functype add_v4i32 (v128, v128) -> (v128){{$}}
507; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}}
508; SIMD128-NEXT: return $pop[[R]]{{$}}
509define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) {
510  %a = add <4 x i32> %x, %y
511  ret <4 x i32> %a
512}
513
514; CHECK-LABEL: sub_v4i32:
515; NO-SIMD128-NOT: i32x4
516; SIMD128-NEXT: .functype sub_v4i32 (v128, v128) -> (v128){{$}}
517; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
518; SIMD128-NEXT: return $pop[[R]]{{$}}
519define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) {
520  %a = sub <4 x i32> %x, %y
521  ret <4 x i32> %a
522}
523
524; CHECK-LABEL: mul_v4i32:
525; NO-SIMD128-NOT: i32x4
526; SIMD128-NEXT: .functype mul_v4i32 (v128, v128) -> (v128){{$}}
527; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
528; SIMD128-NEXT: return $pop[[R]]{{$}}
529define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) {
530  %a = mul <4 x i32> %x, %y
531  ret <4 x i32> %a
532}
533
534; CHECK-LABEL: neg_v4i32:
535; NO-SIMD128-NOT: i32x4
536; SIMD128-NEXT: .functype neg_v4i32 (v128) -> (v128){{$}}
537; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
538; SIMD128-NEXT: return $pop[[R]]{{$}}
539define <4 x i32> @neg_v4i32(<4 x i32> %x) {
540  %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x
541  ret <4 x i32> %a
542}
543
544; CHECK-LABEL: shl_v4i32:
545; NO-SIMD128-NOT: i32x4
546; SIMD128-NEXT: .functype shl_v4i32 (v128, i32) -> (v128){{$}}
547; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
548; SIMD128-NEXT: return $pop[[R]]{{$}}
549define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) {
550  %t = insertelement <4 x i32> undef, i32 %x, i32 0
551  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
552    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
553  %a = shl <4 x i32> %v, %s
554  ret <4 x i32> %a
555}
556
557; CHECK-LABEL: shl_const_v4i32:
558; NO-SIMD128-NOT: i32x4
559; SIMD128-NEXT: .functype shl_const_v4i32 (v128) -> (v128){{$}}
560; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
561; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
562; SIMD128-NEXT: return $pop[[R]]{{$}}
563define <4 x i32> @shl_const_v4i32(<4 x i32> %v) {
564  %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5>
565  ret <4 x i32> %a
566}
567
568; CHECK-LABEL: shl_vec_v4i32:
569; NO-SIMD128-NOT: i32x4
570; SIMD128-NEXT: .functype shl_vec_v4i32 (v128, v128) -> (v128){{$}}
571; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
572; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
573; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
574; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
575; Skip 2 lanes
576; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
577; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
578; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
579; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
580; SIMD128-NEXT: return $pop[[R]]{{$}}
581define <4 x i32> @shl_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
582  %a = shl <4 x i32> %v, %x
583  ret <4 x i32> %a
584}
585
586; CHECK-LABEL: shr_s_v4i32:
587; NO-SIMD128-NOT: i32x4
588; SIMD128-NEXT: .functype shr_s_v4i32 (v128, i32) -> (v128){{$}}
589; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
590; SIMD128-NEXT: return $pop[[R]]{{$}}
591define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) {
592  %t = insertelement <4 x i32> undef, i32 %x, i32 0
593  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
594    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
595  %a = ashr <4 x i32> %v, %s
596  ret <4 x i32> %a
597}
598
599; CHECK-LABEL: shr_s_vec_v4i32:
600; NO-SIMD128-NOT: i32x4
601; SIMD128-NEXT: .functype shr_s_vec_v4i32 (v128, v128) -> (v128){{$}}
602; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
603; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
604; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
605; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
606; Skip 2 lanes
607; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
608; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
609; SIMD128-NEXT: i32.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
610; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
611; SIMD128-NEXT: return $pop[[R]]{{$}}
612define <4 x i32> @shr_s_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
613  %a = ashr <4 x i32> %v, %x
614  ret <4 x i32> %a
615}
616
617; CHECK-LABEL: shr_u_v4i32:
618; NO-SIMD128-NOT: i32x4
619; SIMD128-NEXT: .functype shr_u_v4i32 (v128, i32) -> (v128){{$}}
620; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
621; SIMD128-NEXT: return $pop[[R]]{{$}}
622define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) {
623  %t = insertelement <4 x i32> undef, i32 %x, i32 0
624  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
625    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
626  %a = lshr <4 x i32> %v, %s
627  ret <4 x i32> %a
628}
629
630; CHECK-LABEL: shr_u_vec_v4i32:
631; NO-SIMD128-NOT: i32x4
632; SIMD128-NEXT: .functype shr_u_vec_v4i32 (v128, v128) -> (v128){{$}}
633; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
634; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
635; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
636; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
637; Skip 2 lanes
638; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
639; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
640; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
641; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
642; SIMD128-NEXT: return $pop[[R]]{{$}}
643define <4 x i32> @shr_u_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
644  %a = lshr <4 x i32> %v, %x
645  ret <4 x i32> %a
646}
647
648; CHECK-LABEL: and_v4i32:
649; NO-SIMD128-NOT: v128
650; SIMD128-NEXT: .functype and_v4i32 (v128, v128) -> (v128){{$}}
651; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
652; SIMD128-NEXT: return $pop[[R]]{{$}}
653define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) {
654  %a = and <4 x i32> %x, %y
655  ret <4 x i32> %a
656}
657
658; CHECK-LABEL: or_v4i32:
659; NO-SIMD128-NOT: v128
660; SIMD128-NEXT: .functype or_v4i32 (v128, v128) -> (v128){{$}}
661; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
662; SIMD128-NEXT: return $pop[[R]]{{$}}
663define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) {
664  %a = or <4 x i32> %x, %y
665  ret <4 x i32> %a
666}
667
668; CHECK-LABEL: xor_v4i32:
669; NO-SIMD128-NOT: v128
670; SIMD128-NEXT: .functype xor_v4i32 (v128, v128) -> (v128){{$}}
671; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
672; SIMD128-NEXT: return $pop[[R]]{{$}}
673define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) {
674  %a = xor <4 x i32> %x, %y
675  ret <4 x i32> %a
676}
677
678; CHECK-LABEL: not_v4i32:
679; NO-SIMD128-NOT: v128
680; SIMD128-NEXT: .functype not_v4i32 (v128) -> (v128){{$}}
681; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
682; SIMD128-NEXT: return $pop[[R]]{{$}}
683define <4 x i32> @not_v4i32(<4 x i32> %x) {
684  %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
685  ret <4 x i32> %a
686}
687
688; CHECK-LABEL: andnot_v4i32:
689; SIMD128-VM-NOT: v128.andnot
690; NO-SIMD128-NOT: v128
691; SIMD128-NEXT: .functype andnot_v4i32 (v128, v128) -> (v128){{$}}
692; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
693; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
694; SIMD128-FAST-NEXT: v128.not
695; SIMD128-FAST-NEXT: v128.and
696; SIMD128-FAST-NEXT: return
697define <4 x i32> @andnot_v4i32(<4 x i32> %x, <4 x i32> %y) {
698 %inv_y = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1>
699 %a = and <4 x i32> %x, %inv_y
700 ret <4 x i32> %a
701}
702
703; CHECK-LABEL: bitselect_v4i32:
704; NO-SIMD128-NOT: v128
705; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}}
706; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
707; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
708; SIMD128-FAST-NEXT: v128.not
709; SIMD128-FAST-NEXT: v128.and
710; SIMD128-FAST-NEXT: v128.and
711; SIMD128-FAST-NEXT: v128.or
712; SIMD128-FAST-NEXT: return
713define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) {
714  %masked_v1 = and <4 x i32> %c, %v1
715  %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c
716  %masked_v2 = and <4 x i32> %inv_mask, %v2
717  %a = or <4 x i32> %masked_v2, %masked_v1
718  ret <4 x i32> %a
719}
720
721; ==============================================================================
722; 2 x i64
723; ==============================================================================
724; CHECK-LABEL: add_v2i64:
725; NO-SIMD128-NOT: i64x2
726; SIMD128-VM-NOT: i64x2
727; SIMD128-NEXT: .functype add_v2i64 (v128, v128) -> (v128){{$}}
728; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}}
729; SIMD128-NEXT: return $pop[[R]]{{$}}
730define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) {
731  %a = add <2 x i64> %x, %y
732  ret <2 x i64> %a
733}
734
735; CHECK-LABEL: sub_v2i64:
736; NO-SIMD128-NOT: i64x2
737; SIMD128-VM-NOT: i64x2
738; SIMD128-NEXT: .functype sub_v2i64 (v128, v128) -> (v128){{$}}
739; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
740; SIMD128-NEXT: return $pop[[R]]{{$}}
741define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) {
742  %a = sub <2 x i64> %x, %y
743  ret <2 x i64> %a
744}
745
746; v2i64.mul is not in spec
747; CHECK-LABEL: mul_v2i64:
748; NO-SIMD128-NOT: i64x2
749; SIMD128-VM-NOT: i64x2
750; SIMD128-NOT: i64x2.mul
751; SIMD128: i64x2.extract_lane
752; SIMD128: i64.mul
753define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) {
754  %a = mul <2 x i64> %x, %y
755  ret <2 x i64> %a
756}
757
758; CHECK-LABEL: neg_v2i64:
759; NO-SIMD128-NOT: i64x2
760; SIMD128-NEXT: .functype neg_v2i64 (v128) -> (v128){{$}}
761; SIMD128-NEXT: i64x2.neg $push[[R:[0-9]+]]=, $0{{$}}
762; SIMD128-NEXT: return $pop[[R]]{{$}}
763define <2 x i64> @neg_v2i64(<2 x i64> %x) {
764  %a = sub <2 x i64> <i64 0, i64 0>, %x
765  ret <2 x i64> %a
766}
767
768; CHECK-LABEL: shl_v2i64:
769; NO-SIMD128-NOT: i64x2
770; SIMD128-NEXT: .functype shl_v2i64 (v128, i32) -> (v128){{$}}
771; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
772; SIMD128-NEXT: return $pop[[R]]{{$}}
773define <2 x i64> @shl_v2i64(<2 x i64> %v, i32 %x) {
774  %x2 = zext i32 %x to i64
775  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
776  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
777  %a = shl <2 x i64> %v, %s
778  ret <2 x i64> %a
779}
780
781; CHECK-LABEL: shl_sext_v2i64:
782; NO-SIMD128-NOT: i64x2
783; SIMD128-NEXT: .functype shl_sext_v2i64 (v128, i32) -> (v128){{$}}
784; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
785; SIMD128-NEXT: return $pop[[R]]{{$}}
786define <2 x i64> @shl_sext_v2i64(<2 x i64> %v, i32 %x) {
787  %x2 = sext i32 %x to i64
788  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
789  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
790  %a = shl <2 x i64> %v, %s
791  ret <2 x i64> %a
792}
793
794; CHECK-LABEL: shl_noext_v2i64:
795; NO-SIMD128-NOT: i64x2
796; SIMD128-NEXT: .functype shl_noext_v2i64 (v128, i64) -> (v128){{$}}
797; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
798; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
799; SIMD128-NEXT: return $pop[[R]]{{$}}
800define <2 x i64> @shl_noext_v2i64(<2 x i64> %v, i64 %x) {
801  %t = insertelement <2 x i64> undef, i64 %x, i32 0
802  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
803  %a = shl <2 x i64> %v, %s
804  ret <2 x i64> %a
805}
806
807; CHECK-LABEL: shl_const_v2i64:
808; NO-SIMD128-NOT: i64x2
809; SIMD128-NEXT: .functype shl_const_v2i64 (v128) -> (v128){{$}}
810; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
811; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
812; SIMD128-NEXT: return $pop[[R]]{{$}}
813define <2 x i64> @shl_const_v2i64(<2 x i64> %v) {
814  %a = shl <2 x i64> %v, <i64 5, i64 5>
815  ret <2 x i64> %a
816}
817
818; CHECK-LABEL: shl_vec_v2i64:
819; NO-SIMD128-NOT: i64x2
820; SIMD128-NEXT: .functype shl_vec_v2i64 (v128, v128) -> (v128){{$}}
821; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
822; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
823; SIMD128-NEXT: i64.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
824; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
825; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}}
826; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}}
827; SIMD128-NEXT: i64.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
828; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}}
829; SIMD128-NEXT: return $pop[[R]]{{$}}
830define <2 x i64> @shl_vec_v2i64(<2 x i64> %v, <2 x i64> %x) {
831  %a = shl <2 x i64> %v, %x
832  ret <2 x i64> %a
833}
834
835; CHECK-LABEL: shr_s_v2i64:
836; NO-SIMD128-NOT: i64x2
837; SIMD128-NEXT: .functype shr_s_v2i64 (v128, i32) -> (v128){{$}}
838; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
839; SIMD128-NEXT: return $pop[[R]]{{$}}
840define <2 x i64> @shr_s_v2i64(<2 x i64> %v, i32 %x) {
841  %x2 = zext i32 %x to i64
842  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
843  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
844  %a = ashr <2 x i64> %v, %s
845  ret <2 x i64> %a
846}
847
848; CHECK-LABEL: shr_s_sext_v2i64:
849; NO-SIMD128-NOT: i64x2
850; SIMD128-NEXT: .functype shr_s_sext_v2i64 (v128, i32) -> (v128){{$}}
851; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
852; SIMD128-NEXT: return $pop[[R]]{{$}}
853define <2 x i64> @shr_s_sext_v2i64(<2 x i64> %v, i32 %x) {
854  %x2 = sext i32 %x to i64
855  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
856  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
857  %a = ashr <2 x i64> %v, %s
858  ret <2 x i64> %a
859}
860
861; CHECK-LABEL: shr_s_noext_v2i64:
862; NO-SIMD128-NOT: i64x2
863; SIMD128-NEXT: .functype shr_s_noext_v2i64 (v128, i64) -> (v128){{$}}
864; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
865; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
866; SIMD128-NEXT: return $pop[[R]]{{$}}
867define <2 x i64> @shr_s_noext_v2i64(<2 x i64> %v, i64 %x) {
868  %t = insertelement <2 x i64> undef, i64 %x, i32 0
869  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
870  %a = ashr <2 x i64> %v, %s
871  ret <2 x i64> %a
872}
873
874; CHECK-LABEL: shr_s_const_v2i64:
875; NO-SIMD128-NOT: i64x2
876; SIMD128-NEXT: .functype shr_s_const_v2i64 (v128) -> (v128){{$}}
877; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
878; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
879; SIMD128-NEXT: return $pop[[R]]{{$}}
880define <2 x i64> @shr_s_const_v2i64(<2 x i64> %v) {
881  %a = ashr <2 x i64> %v, <i64 5, i64 5>
882  ret <2 x i64> %a
883}
884
885; CHECK-LABEL: shr_s_vec_v2i64:
886; NO-SIMD128-NOT: i64x2
887; SIMD128-NEXT: .functype shr_s_vec_v2i64 (v128, v128) -> (v128){{$}}
888; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
889; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
890; SIMD128-NEXT: i64.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
891; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
892; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}}
893; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}}
894; SIMD128-NEXT: i64.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
895; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}}
896; SIMD128-NEXT: return $pop[[R]]{{$}}
897define <2 x i64> @shr_s_vec_v2i64(<2 x i64> %v, <2 x i64> %x) {
898  %a = ashr <2 x i64> %v, %x
899  ret <2 x i64> %a
900}
901
902; CHECK-LABEL: shr_u_v2i64:
903; NO-SIMD128-NOT: i64x2
904; SIMD128-NEXT: .functype shr_u_v2i64 (v128, i32) -> (v128){{$}}
905; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
906; SIMD128-NEXT: return $pop[[R]]{{$}}
907define <2 x i64> @shr_u_v2i64(<2 x i64> %v, i32 %x) {
908  %x2 = zext i32 %x to i64
909  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
910  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
911  %a = lshr <2 x i64> %v, %s
912  ret <2 x i64> %a
913}
914
915; CHECK-LABEL: shr_u_sext_v2i64:
916; NO-SIMD128-NOT: i64x2
917; SIMD128-NEXT: .functype shr_u_sext_v2i64 (v128, i32) -> (v128){{$}}
918; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
919; SIMD128-NEXT: return $pop[[R]]{{$}}
920define <2 x i64> @shr_u_sext_v2i64(<2 x i64> %v, i32 %x) {
921  %x2 = sext i32 %x to i64
922  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
923  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
924  %a = lshr <2 x i64> %v, %s
925  ret <2 x i64> %a
926}
927
928; CHECK-LABEL: shr_u_noext_v2i64:
929; NO-SIMD128-NOT: i64x2
930; SIMD128-NEXT: .functype shr_u_noext_v2i64 (v128, i64) -> (v128){{$}}
931; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
932; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
933; SIMD128-NEXT: return $pop[[R]]{{$}}
934define <2 x i64> @shr_u_noext_v2i64(<2 x i64> %v, i64 %x) {
935  %t = insertelement <2 x i64> undef, i64 %x, i32 0
936  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
937  %a = lshr <2 x i64> %v, %s
938  ret <2 x i64> %a
939}
940
941; CHECK-LABEL: shr_u_const_v2i64:
942; NO-SIMD128-NOT: i64x2
943; SIMD128-NEXT: .functype shr_u_const_v2i64 (v128) -> (v128){{$}}
944; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
945; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
946; SIMD128-NEXT: return $pop[[R]]{{$}}
947define <2 x i64> @shr_u_const_v2i64(<2 x i64> %v) {
948  %a = lshr <2 x i64> %v, <i64 5, i64 5>
949  ret <2 x i64> %a
950}
951
952; CHECK-LABEL: shr_u_vec_v2i64:
953; NO-SIMD128-NOT: i64x2
954; SIMD128-NEXT: .functype shr_u_vec_v2i64 (v128, v128) -> (v128){{$}}
955; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
956; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
957; SIMD128-NEXT: i64.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
958; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
959; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}}
960; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}}
961; SIMD128-NEXT: i64.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
962; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}}
963; SIMD128-NEXT: return $pop[[R]]{{$}}
964define <2 x i64> @shr_u_vec_v2i64(<2 x i64> %v, <2 x i64> %x) {
965  %a = lshr <2 x i64> %v, %x
966  ret <2 x i64> %a
967}
968
969; CHECK-LABEL: and_v2i64:
970; NO-SIMD128-NOT: v128
971; SIMD128-VM-NOT: v128
972; SIMD128-NEXT: .functype and_v2i64 (v128, v128) -> (v128){{$}}
973; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
974; SIMD128-NEXT: return $pop[[R]]{{$}}
975define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) {
976  %a = and <2 x i64> %x, %y
977  ret <2 x i64> %a
978}
979
980; CHECK-LABEL: or_v2i64:
981; NO-SIMD128-NOT: v128
982; SIMD128-VM-NOT: v128
983; SIMD128-NEXT: .functype or_v2i64 (v128, v128) -> (v128){{$}}
984; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
985; SIMD128-NEXT: return $pop[[R]]{{$}}
986define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) {
987  %a = or <2 x i64> %x, %y
988  ret <2 x i64> %a
989}
990
991; CHECK-LABEL: xor_v2i64:
992; NO-SIMD128-NOT: v128
993; SIMD128-VM-NOT: v128
994; SIMD128-NEXT: .functype xor_v2i64 (v128, v128) -> (v128){{$}}
995; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
996; SIMD128-NEXT: return $pop[[R]]{{$}}
997define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) {
998  %a = xor <2 x i64> %x, %y
999  ret <2 x i64> %a
1000}
1001
1002; CHECK-LABEL: not_v2i64:
1003; NO-SIMD128-NOT: v128
1004; SIMD128-VM-NOT: v128
1005; SIMD128-NEXT: .functype not_v2i64 (v128) -> (v128){{$}}
1006; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
1007; SIMD128-NEXT: return $pop[[R]]{{$}}
1008define <2 x i64> @not_v2i64(<2 x i64> %x) {
1009  %a = xor <2 x i64> %x, <i64 -1, i64 -1>
1010  ret <2 x i64> %a
1011}
1012
1013; CHECK-LABEL: andnot_v2i64:
1014; SIMD128-VM-NOT: v128.andnot
1015; NO-SIMD128-NOT: v128
1016; SIMD128-NEXT: .functype andnot_v2i64 (v128, v128) -> (v128){{$}}
1017; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
1018; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
1019; SIMD128-FAST-NEXT: v128.not
1020; SIMD128-FAST-NEXT: v128.and
1021; SIMD128-FAST-NEXT: return
1022define <2 x i64> @andnot_v2i64(<2 x i64> %x, <2 x i64> %y) {
1023 %inv_y = xor <2 x i64> %y, <i64 -1, i64 -1>
1024 %a = and <2 x i64> %x, %inv_y
1025 ret <2 x i64> %a
1026}
1027
1028; CHECK-LABEL: bitselect_v2i64:
1029; NO-SIMD128-NOT: v128
1030; SIMD128-VM-NOT: v128
1031; SIMD128-NEXT: .functype bitselect_v2i64 (v128, v128, v128) -> (v128){{$}}
1032; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
1033; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
1034; SIMD128-FAST-NEXT: v128.not
1035; SIMD128-FAST-NEXT: v128.and
1036; SIMD128-FAST-NEXT: v128.and
1037; SIMD128-FAST-NEXT: v128.or
1038; SIMD128-FAST-NEXT: return
1039define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) {
1040  %masked_v1 = and <2 x i64> %v1, %c
1041  %inv_mask = xor <2 x i64> <i64 -1, i64 -1>, %c
1042  %masked_v2 = and <2 x i64> %v2, %inv_mask
1043  %a = or <2 x i64> %masked_v2, %masked_v1
1044  ret <2 x i64> %a
1045}
1046
1047; ==============================================================================
1048; 4 x float
1049; ==============================================================================
1050; CHECK-LABEL: neg_v4f32:
1051; NO-SIMD128-NOT: f32x4
1052; SIMD128-NEXT: .functype neg_v4f32 (v128) -> (v128){{$}}
1053; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
1054; SIMD128-NEXT: return $pop[[R]]{{$}}
1055define <4 x float> @neg_v4f32(<4 x float> %x) {
1056  ; nsz makes this semantically equivalent to flipping sign bit
1057  %a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x
1058  ret <4 x float> %a
1059}
1060
1061; CHECK-LABEL: abs_v4f32:
1062; NO-SIMD128-NOT: f32x4
1063; SIMD128-NEXT: .functype abs_v4f32 (v128) -> (v128){{$}}
1064; SIMD128-NEXT: f32x4.abs $push[[R:[0-9]+]]=, $0{{$}}
1065; SIMD128-NEXT: return $pop[[R]]{{$}}
1066declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone
1067define <4 x float> @abs_v4f32(<4 x float> %x) {
1068  %a = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
1069  ret <4 x float> %a
1070}
1071
1072; CHECK-LABEL: min_unordered_v4f32:
1073; NO-SIMD128-NOT: f32x4
1074; SIMD128-NEXT: .functype min_unordered_v4f32 (v128) -> (v128){{$}}
1075; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
1076; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1077; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1078; SIMD128-NEXT: return $pop[[R]]{{$}}
1079define <4 x float> @min_unordered_v4f32(<4 x float> %x) {
1080  %cmps = fcmp ule <4 x float> %x, <float 5., float 5., float 5., float 5.>
1081  %a = select <4 x i1> %cmps, <4 x float> %x,
1082    <4 x float> <float 5., float 5., float 5., float 5.>
1083  ret <4 x float> %a
1084}
1085
1086; CHECK-LABEL: max_unordered_v4f32:
1087; NO-SIMD128-NOT: f32x4
1088; SIMD128-NEXT: .functype max_unordered_v4f32 (v128) -> (v128){{$}}
1089; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
1090; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1091; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1092; SIMD128-NEXT: return $pop[[R]]{{$}}
1093define <4 x float> @max_unordered_v4f32(<4 x float> %x) {
1094  %cmps = fcmp uge <4 x float> %x, <float 5., float 5., float 5., float 5.>
1095  %a = select <4 x i1> %cmps, <4 x float> %x,
1096    <4 x float> <float 5., float 5., float 5., float 5.>
1097  ret <4 x float> %a
1098}
1099
1100; CHECK-LABEL: min_ordered_v4f32:
1101; NO-SIMD128-NOT: f32x4
1102; SIMD128-NEXT: .functype min_ordered_v4f32 (v128) -> (v128){{$}}
1103; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
1104; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1105; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1106; SIMD128-NEXT: return $pop[[R]]{{$}}
1107define <4 x float> @min_ordered_v4f32(<4 x float> %x) {
1108  %cmps = fcmp ole <4 x float> <float 5., float 5., float 5., float 5.>, %x
1109  %a = select <4 x i1> %cmps,
1110    <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x
1111  ret <4 x float> %a
1112}
1113
1114; CHECK-LABEL: max_ordered_v4f32:
1115; NO-SIMD128-NOT: f32x4
1116; SIMD128-NEXT: .functype max_ordered_v4f32 (v128) -> (v128){{$}}
1117; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
1118; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1119; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1120; SIMD128-NEXT: return $pop[[R]]{{$}}
1121define <4 x float> @max_ordered_v4f32(<4 x float> %x) {
1122  %cmps = fcmp oge <4 x float> <float 5., float 5., float 5., float 5.>, %x
1123  %a = select <4 x i1> %cmps,
1124    <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x
1125  ret <4 x float> %a
1126}
1127
1128; CHECK-LABEL: min_intrinsic_v4f32:
1129; NO-SIMD128-NOT: f32x4
1130; SIMD128-NEXT: .functype min_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
1131; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
1132; SIMD128-NEXT: return $pop[[R]]{{$}}
1133declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>)
1134define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
1135  %a = call <4 x float> @llvm.minimum.v4f32(<4 x float> %x, <4 x float> %y)
1136  ret <4 x float> %a
1137}
1138
1139; CHECK-LABEL: minnum_intrinsic_v4f32:
1140; NO-SIMD128-NOT: f32x4
1141; SIMD128-NEXT: .functype minnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
1142; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
1143; SIMD128-NEXT: return $pop[[R]]{{$}}
1144declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
1145define <4 x float> @minnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
1146  %a = call nnan <4 x float> @llvm.minnum.v4f32(<4 x float> %x, <4 x float> %y)
1147  ret <4 x float> %a
1148}
1149
1150; CHECK-LABEL: max_intrinsic_v4f32:
1151; NO-SIMD128-NOT: f32x4
1152; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
1153; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
1154; SIMD128-NEXT: return $pop[[R]]{{$}}
1155declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
1156define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
1157  %a = call <4 x float> @llvm.maximum.v4f32(<4 x float> %x, <4 x float> %y)
1158  ret <4 x float> %a
1159}
1160
1161; CHECK-LABEL: maxnum_intrinsic_v4f32:
1162; NO-SIMD128-NOT: f32x4
1163; SIMD128-NEXT: .functype maxnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
1164; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
1165; SIMD128-NEXT: return $pop[[R]]{{$}}
1166declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
1167define <4 x float> @maxnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
1168  %a = call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y)
1169  ret <4 x float> %a
1170}
1171
1172; CHECK-LABEL: min_const_intrinsic_v4f32:
1173; NO-SIMD128-NOT: f32x4
1174; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}}
1175; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}}
1176; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}}
1177; SIMD128-NEXT: return $pop[[R]]{{$}}
1178define <4 x float> @min_const_intrinsic_v4f32() {
1179  %a = call <4 x float> @llvm.minimum.v4f32(
1180    <4 x float> <float 42., float 42., float 42., float 42.>,
1181    <4 x float> <float 5., float 5., float 5., float 5.>
1182  )
1183  ret <4 x float> %a
1184}
1185
1186; CHECK-LABEL: max_const_intrinsic_v4f32:
1187; NO-SIMD128-NOT: f32x4
1188; SIMD128-NEXT: .functype max_const_intrinsic_v4f32 () -> (v128){{$}}
1189; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}}
1190; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}}
1191; SIMD128-NEXT: return $pop[[R]]{{$}}
1192define <4 x float> @max_const_intrinsic_v4f32() {
1193  %a = call <4 x float> @llvm.maximum.v4f32(
1194    <4 x float> <float 42., float 42., float 42., float 42.>,
1195    <4 x float> <float 5., float 5., float 5., float 5.>
1196  )
1197  ret <4 x float> %a
1198}
1199
1200; CHECK-LABEL: add_v4f32:
1201; NO-SIMD128-NOT: f32x4
1202; SIMD128-NEXT: .functype add_v4f32 (v128, v128) -> (v128){{$}}
1203; SIMD128-NEXT: f32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}}
1204; SIMD128-NEXT: return $pop[[R]]{{$}}
1205define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) {
1206  %a = fadd <4 x float> %x, %y
1207  ret <4 x float> %a
1208}
1209
1210; CHECK-LABEL: sub_v4f32:
1211; NO-SIMD128-NOT: f32x4
1212; SIMD128-NEXT: .functype sub_v4f32 (v128, v128) -> (v128){{$}}
1213; SIMD128-NEXT: f32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
1214; SIMD128-NEXT: return $pop[[R]]{{$}}
1215define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) {
1216  %a = fsub <4 x float> %x, %y
1217  ret <4 x float> %a
1218}
1219
1220; CHECK-LABEL: div_v4f32:
1221; NO-SIMD128-NOT: f32x4
1222; SIMD128-VM-NOT: f32x4.div
1223; SIMD128-NEXT: .functype div_v4f32 (v128, v128) -> (v128){{$}}
1224; SIMD128-NEXT: f32x4.div $push[[R:[0-9]+]]=, $0, $1{{$}}
1225; SIMD128-NEXT: return $pop[[R]]{{$}}
1226define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) {
1227  %a = fdiv <4 x float> %x, %y
1228  ret <4 x float> %a
1229}
1230
1231; CHECK-LABEL: mul_v4f32:
1232; NO-SIMD128-NOT: f32x4
1233; SIMD128-NEXT: .functype mul_v4f32 (v128, v128) -> (v128){{$}}
1234; SIMD128-NEXT: f32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
1235; SIMD128-NEXT: return $pop[[R]]{{$}}
1236define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) {
1237  %a = fmul <4 x float> %x, %y
1238  ret <4 x float> %a
1239}
1240
1241; CHECK-LABEL: sqrt_v4f32:
1242; NO-SIMD128-NOT: f32x4
1243; SIMD128-VM-NOT: f32x4.sqrt
1244; SIMD128-NEXT: .functype sqrt_v4f32 (v128) -> (v128){{$}}
1245; SIMD128-NEXT: f32x4.sqrt $push[[R:[0-9]+]]=, $0{{$}}
1246; SIMD128-NEXT: return $pop[[R]]{{$}}
1247declare <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
1248define <4 x float> @sqrt_v4f32(<4 x float> %x) {
1249  %a = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
1250  ret <4 x float> %a
1251}
1252
1253; ==============================================================================
1254; 2 x double
1255; ==============================================================================
1256; CHECK-LABEL: neg_v2f64:
1257; NO-SIMD128-NOT: f64x2
1258; SIMD128-NEXT: .functype neg_v2f64 (v128) -> (v128){{$}}
1259; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}}
1260; SIMD128-NEXT: return $pop[[R]]{{$}}
1261define <2 x double> @neg_v2f64(<2 x double> %x) {
1262  ; nsz makes this semantically equivalent to flipping sign bit
1263  %a = fsub nsz <2 x double> <double 0., double 0.>, %x
1264  ret <2 x double> %a
1265}
1266
1267; CHECK-LABEL: abs_v2f64:
1268; NO-SIMD128-NOT: f64x2
1269; SIMD128-NEXT: .functype abs_v2f64 (v128) -> (v128){{$}}
1270; SIMD128-NEXT: f64x2.abs $push[[R:[0-9]+]]=, $0{{$}}
1271; SIMD128-NEXT: return $pop[[R]]{{$}}
1272declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone
1273define <2 x double> @abs_v2f64(<2 x double> %x) {
1274  %a = call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
1275  ret <2 x double> %a
1276}
1277
1278; CHECK-LABEL: min_unordered_v2f64:
1279; NO-SIMD128-NOT: f64x2
1280; SIMD128-NEXT: .functype min_unordered_v2f64 (v128) -> (v128){{$}}
1281; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
1282; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1283; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1284; SIMD128-NEXT: return $pop[[R]]{{$}}
1285define <2 x double> @min_unordered_v2f64(<2 x double> %x) {
1286  %cmps = fcmp ule <2 x double> %x, <double 5., double 5.>
1287  %a = select <2 x i1> %cmps, <2 x double> %x,
1288    <2 x double> <double 5., double 5.>
1289  ret <2 x double> %a
1290}
1291
1292; CHECK-LABEL: max_unordered_v2f64:
1293; NO-SIMD128-NOT: f64x2
1294; SIMD128-NEXT: .functype max_unordered_v2f64 (v128) -> (v128){{$}}
1295; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
1296; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1297; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1298; SIMD128-NEXT: return $pop[[R]]{{$}}
1299define <2 x double> @max_unordered_v2f64(<2 x double> %x) {
1300  %cmps = fcmp uge <2 x double> %x, <double 5., double 5.>
1301  %a = select <2 x i1> %cmps, <2 x double> %x,
1302    <2 x double> <double 5., double 5.>
1303  ret <2 x double> %a
1304}
1305
1306; CHECK-LABEL: min_ordered_v2f64:
1307; NO-SIMD128-NOT: f64x2
1308; SIMD128-NEXT: .functype min_ordered_v2f64 (v128) -> (v128){{$}}
1309; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
1310; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1311; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1312; SIMD128-NEXT: return $pop[[R]]{{$}}
1313define <2 x double> @min_ordered_v2f64(<2 x double> %x) {
1314  %cmps = fcmp ole <2 x double> <double 5., double 5.>, %x
1315  %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>,
1316    <2 x double> %x
1317  ret <2 x double> %a
1318}
1319
1320; CHECK-LABEL: max_ordered_v2f64:
1321; NO-SIMD128-NOT: f64x2
1322; SIMD128-NEXT: .functype max_ordered_v2f64 (v128) -> (v128){{$}}
1323; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
1324; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1325; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
1326; SIMD128-NEXT: return $pop[[R]]{{$}}
1327define <2 x double> @max_ordered_v2f64(<2 x double> %x) {
1328  %cmps = fcmp oge <2 x double> <double 5., double 5.>, %x
1329  %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>,
1330    <2 x double> %x
1331  ret <2 x double> %a
1332}
1333
1334; CHECK-LABEL: min_intrinsic_v2f64:
1335; NO-SIMD128-NOT: f64x2
1336; SIMD128-NEXT: .functype min_intrinsic_v2f64 (v128, v128) -> (v128){{$}}
1337; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $1{{$}}
1338; SIMD128-NEXT: return $pop[[R]]{{$}}
1339declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
1340define <2 x double> @min_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) {
1341  %a = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> %y)
1342  ret <2 x double> %a
1343}
1344
1345; CHECK-LABEL: max_intrinsic_v2f64:
1346; NO-SIMD128-NOT: f64x2
1347; SIMD128-NEXT: .functype max_intrinsic_v2f64 (v128, v128) -> (v128){{$}}
1348; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $1{{$}}
1349; SIMD128-NEXT: return $pop[[R]]{{$}}
1350declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
1351define <2 x double> @max_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) {
1352  %a = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> %y)
1353  ret <2 x double> %a
1354}
1355
1356; CHECK-LABEL: min_const_intrinsic_v2f64:
1357; NO-SIMD128-NOT: f64x2
1358; SIMD128-NEXT: .functype min_const_intrinsic_v2f64 () -> (v128){{$}}
1359; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}}
1360; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}}
1361; SIMD128-NEXT: return $pop[[R]]{{$}}
1362define <2 x double> @min_const_intrinsic_v2f64() {
1363  %a = call <2 x double> @llvm.minimum.v2f64(
1364    <2 x double> <double 42., double 42.>,
1365    <2 x double> <double 5., double 5.>
1366  )
1367  ret <2 x double> %a
1368}
1369
1370; CHECK-LABEL: max_const_intrinsic_v2f64:
1371; NO-SIMD128-NOT: f64x2
1372; SIMD128-NEXT: .functype max_const_intrinsic_v2f64 () -> (v128){{$}}
1373; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}}
1374; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}}
1375; SIMD128-NEXT: return $pop[[R]]{{$}}
1376define <2 x double> @max_const_intrinsic_v2f64() {
1377  %a = call <2 x double> @llvm.maximum.v2f64(
1378    <2 x double> <double 42., double 42.>,
1379    <2 x double> <double 5., double 5.>
1380  )
1381  ret <2 x double> %a
1382}
1383
1384; CHECK-LABEL: add_v2f64:
1385; NO-SIMD128-NOT: f64x2
1386; SIMD128-VM-NOT: f62x2
1387; SIMD128-NEXT: .functype add_v2f64 (v128, v128) -> (v128){{$}}
1388; SIMD128-NEXT: f64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}}
1389; SIMD128-NEXT: return $pop[[R]]{{$}}
1390define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) {
1391  %a = fadd <2 x double> %x, %y
1392  ret <2 x double> %a
1393}
1394
1395; CHECK-LABEL: sub_v2f64:
1396; NO-SIMD128-NOT: f64x2
1397; SIMD128-VM-NOT: f62x2
1398; SIMD128-NEXT: .functype sub_v2f64 (v128, v128) -> (v128){{$}}
1399; SIMD128-NEXT: f64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
1400; SIMD128-NEXT: return $pop[[R]]{{$}}
1401define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) {
1402  %a = fsub <2 x double> %x, %y
1403  ret <2 x double> %a
1404}
1405
1406; CHECK-LABEL: div_v2f64:
1407; NO-SIMD128-NOT: f64x2
1408; SIMD128-VM-NOT: f62x2
1409; SIMD128-NEXT: .functype div_v2f64 (v128, v128) -> (v128){{$}}
1410; SIMD128-NEXT: f64x2.div $push[[R:[0-9]+]]=, $0, $1{{$}}
1411; SIMD128-NEXT: return $pop[[R]]{{$}}
1412define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) {
1413  %a = fdiv <2 x double> %x, %y
1414  ret <2 x double> %a
1415}
1416
1417; CHECK-LABEL: mul_v2f64:
1418; NO-SIMD128-NOT: f64x2
1419; SIMD128-VM-NOT: f62x2
1420; SIMD128-NEXT: .functype mul_v2f64 (v128, v128) -> (v128){{$}}
1421; SIMD128-NEXT: f64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
1422; SIMD128-NEXT: return $pop[[R]]{{$}}
1423define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) {
1424  %a = fmul <2 x double> %x, %y
1425  ret <2 x double> %a
1426}
1427
1428; CHECK-LABEL: sqrt_v2f64:
1429; NO-SIMD128-NOT: f64x2
1430; SIMD128-NEXT: .functype sqrt_v2f64 (v128) -> (v128){{$}}
1431; SIMD128-NEXT: f64x2.sqrt $push[[R:[0-9]+]]=, $0{{$}}
1432; SIMD128-NEXT: return $pop[[R]]{{$}}
1433declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
1434define <2 x double> @sqrt_v2f64(<2 x double> %x) {
1435  %a = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
1436  ret <2 x double> %a
1437}
1438