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