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; 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: min_s_v16i8:
51; NO-SIMD128-NOT: i8x16
52; SIMD128-NEXT: .functype min_s_v16i8 (v128, v128) -> (v128){{$}}
53; SIMD128-NEXT: i8x16.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
54; SIMD128-NEXT: return $pop[[R]]{{$}}
55define <16 x i8> @min_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
56  %c = icmp slt <16 x i8> %x, %y
57  %a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
58  ret <16 x i8> %a
59}
60
61; CHECK-LABEL: min_u_v16i8:
62; NO-SIMD128-NOT: i8x16
63; SIMD128-NEXT: .functype min_u_v16i8 (v128, v128) -> (v128){{$}}
64; SIMD128-NEXT: i8x16.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
65; SIMD128-NEXT: return $pop[[R]]{{$}}
66define <16 x i8> @min_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
67  %c = icmp ult <16 x i8> %x, %y
68  %a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
69  ret <16 x i8> %a
70}
71
72; CHECK-LABEL: max_s_v16i8:
73; NO-SIMD128-NOT: i8x16
74; SIMD128-NEXT: .functype max_s_v16i8 (v128, v128) -> (v128){{$}}
75; SIMD128-NEXT: i8x16.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
76; SIMD128-NEXT: return $pop[[R]]{{$}}
77define <16 x i8> @max_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
78  %c = icmp sgt <16 x i8> %x, %y
79  %a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
80  ret <16 x i8> %a
81}
82
83; CHECK-LABEL: max_u_v16i8:
84; NO-SIMD128-NOT: i8x16
85; SIMD128-NEXT: .functype max_u_v16i8 (v128, v128) -> (v128){{$}}
86; SIMD128-NEXT: i8x16.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
87; SIMD128-NEXT: return $pop[[R]]{{$}}
88define <16 x i8> @max_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
89  %c = icmp ugt <16 x i8> %x, %y
90  %a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
91  ret <16 x i8> %a
92}
93
94; CHECK-LABEL: avgr_u_v16i8:
95; NO-SIMD128-NOT: i8x16
96; SIMD128-NEXT: .functype avgr_u_v16i8 (v128, v128) -> (v128){{$}}
97; SIMD128-NEXT: i8x16.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
98; SIMD128-NEXT: return $pop[[R]]{{$}}
99define <16 x i8> @avgr_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
100  %a = add nuw <16 x i8> %x, %y
101  %b = add nuw <16 x i8> %a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1,
102                              i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
103  %c = udiv <16 x i8> %b, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2,
104                           i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2>
105  ret <16 x i8> %c
106}
107
108; CHECK-LABEL: avgr_u_v16i8_wrap:
109; NO-SIMD128-NOT: i8x16
110; SIMD128-NEXT: .functype avgr_u_v16i8_wrap (v128, v128) -> (v128){{$}}
111; SIMD128-NOT: i8x16.avgr_u
112define <16 x i8> @avgr_u_v16i8_wrap(<16 x i8> %x, <16 x i8> %y) {
113  %a = add <16 x i8> %x, %y
114  %b = add <16 x i8> %a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1,
115                          i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
116  %c = udiv <16 x i8> %b, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2,
117                           i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2>
118  ret <16 x i8> %c
119}
120
121; CHECK-LABEL: abs_v16i8:
122; NO-SIMD128-NOT: i8x16
123; SIMD128-NEXT: .functype abs_v16i8 (v128) -> (v128){{$}}
124; SIMD128-NEXT: i8x16.abs $push[[R:[0-9]+]]=, $0{{$}}
125; SIMD128-NEXT: return $pop[[R]]{{$}}
126define <16 x i8> @abs_v16i8(<16 x i8> %x) {
127  %a = sub <16 x i8> zeroinitializer, %x
128  %b = icmp slt <16 x i8> %x, zeroinitializer
129  %c = select <16 x i1> %b, <16 x i8> %a, <16 x i8> %x
130  ret <16 x i8> %c
131}
132
133; CHECK-LABEL: neg_v16i8:
134; NO-SIMD128-NOT: i8x16
135; SIMD128-NEXT: .functype neg_v16i8 (v128) -> (v128){{$}}
136; SIMD128-NEXT: i8x16.neg $push[[R:[0-9]+]]=, $0{{$}}
137; SIMD128-NEXT: return $pop[[R]]{{$}}
138define <16 x i8> @neg_v16i8(<16 x i8> %x) {
139  %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0,
140                      i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>,
141                     %x
142  ret <16 x i8> %a
143}
144
145; CHECK-LABEL: shl_v16i8:
146; NO-SIMD128-NOT: i8x16
147; SIMD128-NEXT: .functype shl_v16i8 (v128, i32) -> (v128){{$}}
148; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
149; SIMD128-NEXT: return $pop[[R]]{{$}}
150define <16 x i8> @shl_v16i8(<16 x i8> %v, i8 %x) {
151  %t = insertelement <16 x i8> undef, i8 %x, i32 0
152  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
153    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
154                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
155  %a = shl <16 x i8> %v, %s
156  ret <16 x i8> %a
157}
158
159; CHECK-LABEL: shl_const_v16i8:
160; NO-SIMD128-NOT: i8x16
161; SIMD128-NEXT: .functype shl_const_v16i8 (v128) -> (v128){{$}}
162; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
163; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
164; SIMD128-NEXT: return $pop[[R]]{{$}}
165define <16 x i8> @shl_const_v16i8(<16 x i8> %v) {
166  %a = shl <16 x i8> %v,
167    <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5,
168     i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
169  ret <16 x i8> %a
170}
171
172; CHECK-LABEL: shl_vec_v16i8:
173; NO-SIMD128-NOT: i8x16
174; SIMD128-NEXT: .functype shl_vec_v16i8 (v128, v128) -> (v128){{$}}
175; SIMD128-NEXT: i8x16.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
176; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
177; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
178; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
179; SIMD128-NEXT: i32.shl $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]
180; SIMD128-NEXT: i8x16.splat $push[[M3:[0-9]+]]=, $pop[[M2]]
181; Skip 14 lanes
182; SIMD128:      i8x16.extract_lane_u $push[[L4:[0-9]+]]=, $0, 15{{$}}
183; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}}
184; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 7{{$}}
185; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
186; SIMD128-NEXT: i32.shl $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
187; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 15, $pop[[M6]]{{$}}
188; SIMD128-NEXT: return $pop[[R]]{{$}}
189define <16 x i8> @shl_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
190  %a = shl <16 x i8> %v, %x
191  ret <16 x i8> %a
192}
193
194; CHECK-LABEL: shr_s_v16i8:
195; NO-SIMD128-NOT: i8x16
196; SIMD128-NEXT: .functype shr_s_v16i8 (v128, i32) -> (v128){{$}}
197; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
198; SIMD128-NEXT: return $pop[[R]]{{$}}
199define <16 x i8> @shr_s_v16i8(<16 x i8> %v, i8 %x) {
200  %t = insertelement <16 x i8> undef, i8 %x, i32 0
201  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
202    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
203                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
204  %a = ashr <16 x i8> %v, %s
205  ret <16 x i8> %a
206}
207
208; CHECK-LABEL: shr_s_vec_v16i8:
209; NO-SIMD128-NOT: i8x16
210; SIMD128-NEXT: .functype shr_s_vec_v16i8 (v128, v128) -> (v128){{$}}
211; SIMD128-NEXT: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
212; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
213; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
214; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
215; SIMD128-NEXT: i32.shr_s $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]
216; SIMD128-NEXT: i8x16.splat $push[[M3:[0-9]+]]=, $pop[[M2]]
217; Skip 14 lanes
218; SIMD128:      i8x16.extract_lane_s $push[[L4:[0-9]+]]=, $0, 15{{$}}
219; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}}
220; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 7{{$}}
221; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
222; SIMD128-NEXT: i32.shr_s $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
223; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 15, $pop[[M6]]{{$}}
224; SIMD128-NEXT: return $pop[[R]]{{$}}
225define <16 x i8> @shr_s_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
226  %a = ashr <16 x i8> %v, %x
227  ret <16 x i8> %a
228}
229
230; CHECK-LABEL: shr_u_v16i8:
231; NO-SIMD128-NOT: i8x16
232; SIMD128-NEXT: .functype shr_u_v16i8 (v128, i32) -> (v128){{$}}
233; SIMD128-NEXT: i8x16.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
234; SIMD128-NEXT: return $pop[[R]]{{$}}
235define <16 x i8> @shr_u_v16i8(<16 x i8> %v, i8 %x) {
236  %t = insertelement <16 x i8> undef, i8 %x, i32 0
237  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
238    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
239                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
240  %a = lshr <16 x i8> %v, %s
241  ret <16 x i8> %a
242}
243
244; CHECK-LABEL: shr_u_vec_v16i8:
245; NO-SIMD128-NOT: i8x16
246; SIMD128-NEXT: .functype shr_u_vec_v16i8 (v128, v128) -> (v128){{$}}
247; SIMD128-NEXT: i8x16.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
248; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
249; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}}
250; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
251; SIMD128-NEXT: i32.shr_u $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]
252; SIMD128-NEXT: i8x16.splat $push[[M3:[0-9]+]]=, $pop[[M2]]
253; Skip 14 lanes
254; SIMD128:      i8x16.extract_lane_u $push[[L4:[0-9]+]]=, $0, 15{{$}}
255; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}}
256; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 7{{$}}
257; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
258; SIMD128-NEXT: i32.shr_u $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
259; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 15, $pop[[M6]]{{$}}
260; SIMD128-NEXT: return $pop[[R]]{{$}}
261define <16 x i8> @shr_u_vec_v16i8(<16 x i8> %v, <16 x i8> %x) {
262  %a = lshr <16 x i8> %v, %x
263  ret <16 x i8> %a
264}
265
266; CHECK-LABEL: and_v16i8:
267; NO-SIMD128-NOT: v128
268; SIMD128-NEXT: .functype and_v16i8 (v128, v128) -> (v128){{$}}
269; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
270; SIMD128-NEXT: return $pop[[R]]{{$}}
271define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) {
272  %a = and <16 x i8> %x, %y
273  ret <16 x i8> %a
274}
275
276; CHECK-LABEL: or_v16i8:
277; NO-SIMD128-NOT: v128
278; SIMD128-NEXT: .functype or_v16i8 (v128, v128) -> (v128){{$}}
279; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
280; SIMD128-NEXT: return $pop[[R]]{{$}}
281define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) {
282  %a = or <16 x i8> %x, %y
283  ret <16 x i8> %a
284}
285
286; CHECK-LABEL: xor_v16i8:
287; NO-SIMD128-NOT: v128
288; SIMD128-NEXT: .functype xor_v16i8 (v128, v128) -> (v128){{$}}
289; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
290; SIMD128-NEXT: return $pop[[R]]{{$}}
291define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) {
292  %a = xor <16 x i8> %x, %y
293  ret <16 x i8> %a
294}
295
296; CHECK-LABEL: not_v16i8:
297; NO-SIMD128-NOT: v128
298; SIMD128-NEXT: .functype not_v16i8 (v128) -> (v128){{$}}
299; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
300; SIMD128-NEXT: return $pop[[R]]{{$}}
301define <16 x i8> @not_v16i8(<16 x i8> %x) {
302  %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1,
303                          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  ret <16 x i8> %a
307}
308
309; CHECK-LABEL: andnot_v16i8:
310; NO-SIMD128-NOT: v128
311; SIMD128-NEXT: .functype andnot_v16i8 (v128, v128) -> (v128){{$}}
312; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
313; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
314; SIMD128-FAST-NEXT: v128.not
315; SIMD128-FAST-NEXT: v128.and
316; SIMD128-FAST-NEXT: return
317define <16 x i8> @andnot_v16i8(<16 x i8> %x, <16 x i8> %y) {
318 %inv_y = xor <16 x i8> %y,
319   <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
320    i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
321 %a = and <16 x i8> %x, %inv_y
322 ret <16 x i8> %a
323}
324
325; CHECK-LABEL: bitselect_v16i8:
326; NO-SIMD128-NOT: v128
327; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}}
328; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
329; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
330; SIMD128-FAST-NEXT: v128.and
331; SIMD128-FAST-NEXT: v128.not
332; SIMD128-FAST-NEXT: v128.and
333; SIMD128-FAST-NEXT: v128.or
334; SIMD128-FAST-NEXT: return
335define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) {
336  %masked_v1 = and <16 x i8> %c, %v1
337  %inv_mask = xor <16 x i8> %c,
338    <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
339     i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
340  %masked_v2 = and <16 x i8> %inv_mask, %v2
341  %a = or <16 x i8> %masked_v1, %masked_v2
342  ret <16 x i8> %a
343}
344
345; ==============================================================================
346; 8 x i16
347; ==============================================================================
348; CHECK-LABEL: add_v8i16:
349; NO-SIMD128-NOT: i16x8
350; SIMD128-NEXT: .functype add_v8i16 (v128, v128) -> (v128){{$}}
351; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}}
352; SIMD128-NEXT: return $pop[[R]]{{$}}
353define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) {
354  %a = add <8 x i16> %x, %y
355  ret <8 x i16> %a
356}
357
358; CHECK-LABEL: sub_v8i16:
359; NO-SIMD128-NOT: i16x8
360; SIMD128-NEXT: .functype sub_v8i16 (v128, v128) -> (v128){{$}}
361; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
362; SIMD128-NEXT: return $pop[[R]]{{$}}
363define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) {
364  %a = sub <8 x i16> %x, %y
365  ret <8 x i16> %a
366}
367
368; CHECK-LABEL: mul_v8i16:
369; NO-SIMD128-NOT: i16x8
370; SIMD128-NEXT: .functype mul_v8i16 (v128, v128) -> (v128){{$}}
371; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
372; SIMD128-NEXT: return $pop[[R]]{{$}}
373define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) {
374  %a = mul <8 x i16> %x, %y
375  ret <8 x i16> %a
376}
377
378; CHECK-LABEL: min_s_v8i16:
379; NO-SIMD128-NOT: i16x8
380; SIMD128-NEXT: .functype min_s_v8i16 (v128, v128) -> (v128){{$}}
381; SIMD128-NEXT: i16x8.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
382; SIMD128-NEXT: return $pop[[R]]{{$}}
383define <8 x i16> @min_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
384  %c = icmp slt <8 x i16> %x, %y
385  %a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
386  ret <8 x i16> %a
387}
388
389; CHECK-LABEL: min_u_v8i16:
390; NO-SIMD128-NOT: i16x8
391; SIMD128-NEXT: .functype min_u_v8i16 (v128, v128) -> (v128){{$}}
392; SIMD128-NEXT: i16x8.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
393; SIMD128-NEXT: return $pop[[R]]{{$}}
394define <8 x i16> @min_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
395  %c = icmp ult <8 x i16> %x, %y
396  %a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
397  ret <8 x i16> %a
398}
399
400; CHECK-LABEL: max_s_v8i16:
401; NO-SIMD128-NOT: i16x8
402; SIMD128-NEXT: .functype max_s_v8i16 (v128, v128) -> (v128){{$}}
403; SIMD128-NEXT: i16x8.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
404; SIMD128-NEXT: return $pop[[R]]{{$}}
405define <8 x i16> @max_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
406  %c = icmp sgt <8 x i16> %x, %y
407  %a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
408  ret <8 x i16> %a
409}
410
411; CHECK-LABEL: max_u_v8i16:
412; NO-SIMD128-NOT: i16x8
413; SIMD128-NEXT: .functype max_u_v8i16 (v128, v128) -> (v128){{$}}
414; SIMD128-NEXT: i16x8.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
415; SIMD128-NEXT: return $pop[[R]]{{$}}
416define <8 x i16> @max_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
417  %c = icmp ugt <8 x i16> %x, %y
418  %a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
419  ret <8 x i16> %a
420}
421
422; CHECK-LABEL: avgr_u_v8i16:
423; NO-SIMD128-NOT: i16x8
424; SIMD128-NEXT: .functype avgr_u_v8i16 (v128, v128) -> (v128){{$}}
425; SIMD128-NEXT: i16x8.avgr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
426; SIMD128-NEXT: return $pop[[R]]{{$}}
427define <8 x i16> @avgr_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
428  %a = add nuw <8 x i16> %x, %y
429  %b = add nuw <8 x i16> %a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
430  %c = udiv <8 x i16> %b, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>
431  ret <8 x i16> %c
432}
433
434; CHECK-LABEL: avgr_u_v8i16_wrap:
435; NO-SIMD128-NOT: i16x8
436; SIMD128-NEXT: .functype avgr_u_v8i16_wrap (v128, v128) -> (v128){{$}}
437; SIMD128-NOT: i16x8.avgr_u
438define <8 x i16> @avgr_u_v8i16_wrap(<8 x i16> %x, <8 x i16> %y) {
439  %a = add <8 x i16> %x, %y
440  %b = add <8 x i16> %a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
441  %c = udiv <8 x i16> %b, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>
442  ret <8 x i16> %c
443}
444
445; CHECK-LABEL: abs_v8i16:
446; NO-SIMD128-NOT: i16x8
447; SIMD128-NEXT: .functype abs_v8i16 (v128) -> (v128){{$}}
448; SIMD128-NEXT: i16x8.abs $push[[R:[0-9]+]]=, $0{{$}}
449; SIMD128-NEXT: return $pop[[R]]{{$}}
450define <8 x i16> @abs_v8i16(<8 x i16> %x) {
451  %a = sub <8 x i16> zeroinitializer, %x
452  %b = icmp slt <8 x i16> %x, zeroinitializer
453  %c = select <8 x i1> %b, <8 x i16> %a, <8 x i16> %x
454  ret <8 x i16> %c
455}
456
457; CHECK-LABEL: neg_v8i16:
458; NO-SIMD128-NOT: i16x8
459; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}}
460; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}}
461; SIMD128-NEXT: return $pop[[R]]{{$}}
462define <8 x i16> @neg_v8i16(<8 x i16> %x) {
463  %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>,
464                     %x
465  ret <8 x i16> %a
466}
467
468; CHECK-LABEL: shl_v8i16:
469; NO-SIMD128-NOT: i16x8
470; SIMD128-NEXT: .functype shl_v8i16 (v128, i32) -> (v128){{$}}
471; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
472; SIMD128-NEXT: return $pop[[R]]{{$}}
473define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) {
474  %t = insertelement <8 x i16> undef, i16 %x, i32 0
475  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
476    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
477  %a = shl <8 x i16> %v, %s
478  ret <8 x i16> %a
479}
480
481; CHECK-LABEL: shl_const_v8i16:
482; NO-SIMD128-NOT: i16x8
483; SIMD128-NEXT: .functype shl_const_v8i16 (v128) -> (v128){{$}}
484; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
485; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
486; SIMD128-NEXT: return $pop[[R]]{{$}}
487define <8 x i16> @shl_const_v8i16(<8 x i16> %v) {
488  %a = shl <8 x i16> %v,
489    <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
490  ret <8 x i16> %a
491}
492
493; CHECK-LABEL: shl_vec_v8i16:
494; NO-SIMD128-NOT: i16x8
495; SIMD128-NEXT: .functype shl_vec_v8i16 (v128, v128) -> (v128){{$}}
496; SIMD128-NEXT: i16x8.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
497; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
498; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
499; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
500; SIMD128-NEXT: i32.shl $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]{{$}}
501; SIMD128-NEXT: i16x8.splat $push[[M3:[0-9]+]]=, $pop[[M2]]{{$}}
502; Skip 6 lanes
503; SIMD128:      i16x8.extract_lane_u $push[[L4:[0-9]+]]=, $0, 7{{$}}
504; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}}
505; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 15{{$}}
506; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
507; SIMD128-NEXT: i32.shl $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
508; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 7, $pop[[M6]]{{$}}
509; SIMD128-NEXT: return $pop[[R]]{{$}}
510define <8 x i16> @shl_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
511  %a = shl <8 x i16> %v, %x
512  ret <8 x i16> %a
513}
514
515; CHECK-LABEL: shr_s_v8i16:
516; NO-SIMD128-NOT: i16x8
517; SIMD128-NEXT: .functype shr_s_v8i16 (v128, i32) -> (v128){{$}}
518; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
519; SIMD128-NEXT: return $pop[[R]]{{$}}
520define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) {
521  %t = insertelement <8 x i16> undef, i16 %x, i32 0
522  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
523    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
524  %a = ashr <8 x i16> %v, %s
525  ret <8 x i16> %a
526}
527
528; CHECK-LABEL: shr_s_vec_v8i16:
529; NO-SIMD128-NOT: i16x8
530; SIMD128-NEXT: .functype shr_s_vec_v8i16 (v128, v128) -> (v128){{$}}
531; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}}
532; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
533; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
534; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
535; SIMD128-NEXT: i32.shr_s $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]{{$}}
536; SIMD128-NEXT: i16x8.splat $push[[M3:[0-9]+]]=, $pop[[M2]]{{$}}
537; Skip 6 lanes
538; SIMD128:      i16x8.extract_lane_s $push[[L4:[0-9]+]]=, $0, 7{{$}}
539; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}}
540; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 15{{$}}
541; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
542; SIMD128-NEXT: i32.shr_s $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
543; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 7, $pop[[M6]]{{$}}
544; SIMD128-NEXT: return $pop[[R]]{{$}}
545define <8 x i16> @shr_s_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
546  %a = ashr <8 x i16> %v, %x
547  ret <8 x i16> %a
548}
549
550; CHECK-LABEL: shr_u_v8i16:
551; NO-SIMD128-NOT: i16x8
552; SIMD128-NEXT: .functype shr_u_v8i16 (v128, i32) -> (v128){{$}}
553; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
554; SIMD128-NEXT: return $pop[[R]]{{$}}
555define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) {
556  %t = insertelement <8 x i16> undef, i16 %x, i32 0
557  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
558    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
559  %a = lshr <8 x i16> %v, %s
560  ret <8 x i16> %a
561}
562
563; CHECK-LABEL: shr_u_vec_v8i16:
564; NO-SIMD128-NOT: i16x8
565; SIMD128-NEXT: .functype shr_u_vec_v8i16 (v128, v128) -> (v128){{$}}
566; SIMD128-NEXT: i16x8.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}}
567; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 0{{$}}
568; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}}
569; SIMD128-NEXT: i32.and $push[[M1:[0-9]+]]=, $pop[[L1]], $pop[[M0]]{{$}}
570; SIMD128-NEXT: i32.shr_u $push[[M2:[0-9]+]]=, $pop[[L0]], $pop[[M1]]{{$}}
571; SIMD128-NEXT: i16x8.splat $push[[M3:[0-9]+]]=, $pop[[M2]]{{$}}
572; Skip 6 lanes
573; SIMD128:      i16x8.extract_lane_u $push[[L4:[0-9]+]]=, $0, 7{{$}}
574; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}}
575; SIMD128-NEXT: i32.const $push[[M4:[0-9]+]]=, 15{{$}}
576; SIMD128-NEXT: i32.and $push[[M5:[0-9]+]]=, $pop[[L5]], $pop[[M4]]{{$}}
577; SIMD128-NEXT: i32.shr_u $push[[M6:[0-9]+]]=, $pop[[L4]], $pop[[M5]]{{$}}
578; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[M7:[0-9]+]], 7, $pop[[M6]]{{$}}
579; SIMD128-NEXT: return $pop[[R]]{{$}}
580define <8 x i16> @shr_u_vec_v8i16(<8 x i16> %v, <8 x i16> %x) {
581  %a = lshr <8 x i16> %v, %x
582  ret <8 x i16> %a
583}
584
585; CHECK-LABEL: and_v8i16:
586; NO-SIMD128-NOT: v128
587; SIMD128-NEXT: .functype and_v8i16 (v128, v128) -> (v128){{$}}
588; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
589; SIMD128-NEXT: return $pop[[R]]{{$}}
590define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) {
591  %a = and <8 x i16> %x, %y
592  ret <8 x i16> %a
593}
594
595; CHECK-LABEL: or_v8i16:
596; NO-SIMD128-NOT: v128
597; SIMD128-NEXT: .functype or_v8i16 (v128, v128) -> (v128){{$}}
598; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
599; SIMD128-NEXT: return $pop[[R]]{{$}}
600define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) {
601  %a = or <8 x i16> %x, %y
602  ret <8 x i16> %a
603}
604
605; CHECK-LABEL: xor_v8i16:
606; NO-SIMD128-NOT: v128
607; SIMD128-NEXT: .functype xor_v8i16 (v128, v128) -> (v128){{$}}
608; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
609; SIMD128-NEXT: return $pop[[R]]{{$}}
610define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) {
611  %a = xor <8 x i16> %x, %y
612  ret <8 x i16> %a
613}
614
615; CHECK-LABEL: not_v8i16:
616; NO-SIMD128-NOT: v128
617; SIMD128-NEXT: .functype not_v8i16 (v128) -> (v128){{$}}
618; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
619; SIMD128-NEXT: return $pop[[R]]{{$}}
620define <8 x i16> @not_v8i16(<8 x i16> %x) {
621  %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1,
622                          i16 -1, i16 -1, i16 -1, i16 -1>
623  ret <8 x i16> %a
624}
625
626; CHECK-LABEL: andnot_v8i16:
627; NO-SIMD128-NOT: v128
628; SIMD128-NEXT: .functype andnot_v8i16 (v128, v128) -> (v128){{$}}
629; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
630; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
631; SIMD128-FAST-NEXT: v128.not
632; SIMD128-FAST-NEXT: v128.and
633; SIMD128-FAST-NEXT: return
634define <8 x i16> @andnot_v8i16(<8 x i16> %x, <8 x i16> %y) {
635 %inv_y = xor <8 x i16> %y,
636   <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
637 %a = and <8 x i16> %x, %inv_y
638 ret <8 x i16> %a
639}
640
641; CHECK-LABEL: bitselect_v8i16:
642; NO-SIMD128-NOT: v128
643; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}}
644; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
645; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
646; SIMD128-FAST-NEXT: v128.and
647; SIMD128-FAST-NEXT: v128.not
648; SIMD128-FAST-NEXT: v128.and
649; SIMD128-FAST-NEXT: v128.or
650; SIMD128-FAST-NEXT: return
651define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) {
652  %masked_v1 = and <8 x i16> %v1, %c
653  %inv_mask = xor <8 x i16>
654    <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>,
655    %c
656  %masked_v2 = and <8 x i16> %v2, %inv_mask
657  %a = or <8 x i16> %masked_v1, %masked_v2
658  ret <8 x i16> %a
659}
660
661; ==============================================================================
662; 4 x i32
663; ==============================================================================
664; CHECK-LABEL: add_v4i32:
665; NO-SIMD128-NOT: i32x4
666; SIMD128-NEXT: .functype add_v4i32 (v128, v128) -> (v128){{$}}
667; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}}
668; SIMD128-NEXT: return $pop[[R]]{{$}}
669define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) {
670  %a = add <4 x i32> %x, %y
671  ret <4 x i32> %a
672}
673
674; CHECK-LABEL: sub_v4i32:
675; NO-SIMD128-NOT: i32x4
676; SIMD128-NEXT: .functype sub_v4i32 (v128, v128) -> (v128){{$}}
677; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
678; SIMD128-NEXT: return $pop[[R]]{{$}}
679define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) {
680  %a = sub <4 x i32> %x, %y
681  ret <4 x i32> %a
682}
683
684; CHECK-LABEL: mul_v4i32:
685; NO-SIMD128-NOT: i32x4
686; SIMD128-NEXT: .functype mul_v4i32 (v128, v128) -> (v128){{$}}
687; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
688; SIMD128-NEXT: return $pop[[R]]{{$}}
689define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) {
690  %a = mul <4 x i32> %x, %y
691  ret <4 x i32> %a
692}
693
694; CHECK-LABEL: min_s_v4i32:
695; NO-SIMD128-NOT: i32x4
696; SIMD128-NEXT: .functype min_s_v4i32 (v128, v128) -> (v128){{$}}
697; SIMD128-NEXT: i32x4.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
698; SIMD128-NEXT: return $pop[[R]]{{$}}
699define <4 x i32> @min_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
700  %c = icmp slt <4 x i32> %x, %y
701  %a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
702  ret <4 x i32> %a
703}
704
705; CHECK-LABEL: min_u_v4i32:
706; NO-SIMD128-NOT: i32x4
707; SIMD128-NEXT: .functype min_u_v4i32 (v128, v128) -> (v128){{$}}
708; SIMD128-NEXT: i32x4.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
709; SIMD128-NEXT: return $pop[[R]]{{$}}
710define <4 x i32> @min_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
711  %c = icmp ult <4 x i32> %x, %y
712  %a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
713  ret <4 x i32> %a
714}
715
716; CHECK-LABEL: max_s_v4i32:
717; NO-SIMD128-NOT: i32x4
718; SIMD128-NEXT: .functype max_s_v4i32 (v128, v128) -> (v128){{$}}
719; SIMD128-NEXT: i32x4.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
720; SIMD128-NEXT: return $pop[[R]]{{$}}
721define <4 x i32> @max_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
722  %c = icmp sgt <4 x i32> %x, %y
723  %a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
724  ret <4 x i32> %a
725}
726
727; CHECK-LABEL: max_u_v4i32:
728; NO-SIMD128-NOT: i32x4
729; SIMD128-NEXT: .functype max_u_v4i32 (v128, v128) -> (v128){{$}}
730; SIMD128-NEXT: i32x4.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
731; SIMD128-NEXT: return $pop[[R]]{{$}}
732define <4 x i32> @max_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
733  %c = icmp ugt <4 x i32> %x, %y
734  %a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
735  ret <4 x i32> %a
736}
737
738; CHECK-LABEL: abs_v4i32:
739; NO-SIMD128-NOT: i32x4
740; SIMD128-NEXT: .functype abs_v4i32 (v128) -> (v128){{$}}
741; SIMD128-NEXT: i32x4.abs $push[[R:[0-9]+]]=, $0{{$}}
742; SIMD128-NEXT: return $pop[[R]]{{$}}
743define <4 x i32> @abs_v4i32(<4 x i32> %x) {
744  %a = sub <4 x i32> zeroinitializer, %x
745  %b = icmp slt <4 x i32> %x, zeroinitializer
746  %c = select <4 x i1> %b, <4 x i32> %a, <4 x i32> %x
747  ret <4 x i32> %c
748}
749
750; CHECK-LABEL: neg_v4i32:
751; NO-SIMD128-NOT: i32x4
752; SIMD128-NEXT: .functype neg_v4i32 (v128) -> (v128){{$}}
753; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
754; SIMD128-NEXT: return $pop[[R]]{{$}}
755define <4 x i32> @neg_v4i32(<4 x i32> %x) {
756  %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x
757  ret <4 x i32> %a
758}
759
760; CHECK-LABEL: shl_v4i32:
761; NO-SIMD128-NOT: i32x4
762; SIMD128-NEXT: .functype shl_v4i32 (v128, i32) -> (v128){{$}}
763; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
764; SIMD128-NEXT: return $pop[[R]]{{$}}
765define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) {
766  %t = insertelement <4 x i32> undef, i32 %x, i32 0
767  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
768    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
769  %a = shl <4 x i32> %v, %s
770  ret <4 x i32> %a
771}
772
773; CHECK-LABEL: shl_const_v4i32:
774; NO-SIMD128-NOT: i32x4
775; SIMD128-NEXT: .functype shl_const_v4i32 (v128) -> (v128){{$}}
776; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
777; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
778; SIMD128-NEXT: return $pop[[R]]{{$}}
779define <4 x i32> @shl_const_v4i32(<4 x i32> %v) {
780  %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5>
781  ret <4 x i32> %a
782}
783
784; CHECK-LABEL: shl_vec_v4i32:
785; NO-SIMD128-NOT: i32x4
786; SIMD128-NEXT: .functype shl_vec_v4i32 (v128, v128) -> (v128){{$}}
787; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
788; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
789; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
790; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
791; Skip 2 lanes
792; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
793; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
794; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
795; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
796; SIMD128-NEXT: return $pop[[R]]{{$}}
797define <4 x i32> @shl_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
798  %a = shl <4 x i32> %v, %x
799  ret <4 x i32> %a
800}
801
802; CHECK-LABEL: shr_s_v4i32:
803; NO-SIMD128-NOT: i32x4
804; SIMD128-NEXT: .functype shr_s_v4i32 (v128, i32) -> (v128){{$}}
805; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
806; SIMD128-NEXT: return $pop[[R]]{{$}}
807define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) {
808  %t = insertelement <4 x i32> undef, i32 %x, i32 0
809  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
810    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
811  %a = ashr <4 x i32> %v, %s
812  ret <4 x i32> %a
813}
814
815; CHECK-LABEL: shr_s_vec_v4i32:
816; NO-SIMD128-NOT: i32x4
817; SIMD128-NEXT: .functype shr_s_vec_v4i32 (v128, v128) -> (v128){{$}}
818; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
819; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
820; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
821; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
822; Skip 2 lanes
823; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
824; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
825; SIMD128-NEXT: i32.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
826; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
827; SIMD128-NEXT: return $pop[[R]]{{$}}
828define <4 x i32> @shr_s_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
829  %a = ashr <4 x i32> %v, %x
830  ret <4 x i32> %a
831}
832
833; CHECK-LABEL: shr_u_v4i32:
834; NO-SIMD128-NOT: i32x4
835; SIMD128-NEXT: .functype shr_u_v4i32 (v128, i32) -> (v128){{$}}
836; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
837; SIMD128-NEXT: return $pop[[R]]{{$}}
838define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) {
839  %t = insertelement <4 x i32> undef, i32 %x, i32 0
840  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
841    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
842  %a = lshr <4 x i32> %v, %s
843  ret <4 x i32> %a
844}
845
846; CHECK-LABEL: shr_u_vec_v4i32:
847; NO-SIMD128-NOT: i32x4
848; SIMD128-NEXT: .functype shr_u_vec_v4i32 (v128, v128) -> (v128){{$}}
849; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}}
850; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}}
851; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
852; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}}
853; Skip 2 lanes
854; SIMD128:      i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}}
855; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}}
856; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
857; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}}
858; SIMD128-NEXT: return $pop[[R]]{{$}}
859define <4 x i32> @shr_u_vec_v4i32(<4 x i32> %v, <4 x i32> %x) {
860  %a = lshr <4 x i32> %v, %x
861  ret <4 x i32> %a
862}
863
864; CHECK-LABEL: and_v4i32:
865; NO-SIMD128-NOT: v128
866; SIMD128-NEXT: .functype and_v4i32 (v128, v128) -> (v128){{$}}
867; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
868; SIMD128-NEXT: return $pop[[R]]{{$}}
869define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) {
870  %a = and <4 x i32> %x, %y
871  ret <4 x i32> %a
872}
873
874; CHECK-LABEL: or_v4i32:
875; NO-SIMD128-NOT: v128
876; SIMD128-NEXT: .functype or_v4i32 (v128, v128) -> (v128){{$}}
877; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
878; SIMD128-NEXT: return $pop[[R]]{{$}}
879define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) {
880  %a = or <4 x i32> %x, %y
881  ret <4 x i32> %a
882}
883
884; CHECK-LABEL: xor_v4i32:
885; NO-SIMD128-NOT: v128
886; SIMD128-NEXT: .functype xor_v4i32 (v128, v128) -> (v128){{$}}
887; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
888; SIMD128-NEXT: return $pop[[R]]{{$}}
889define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) {
890  %a = xor <4 x i32> %x, %y
891  ret <4 x i32> %a
892}
893
894; CHECK-LABEL: not_v4i32:
895; NO-SIMD128-NOT: v128
896; SIMD128-NEXT: .functype not_v4i32 (v128) -> (v128){{$}}
897; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
898; SIMD128-NEXT: return $pop[[R]]{{$}}
899define <4 x i32> @not_v4i32(<4 x i32> %x) {
900  %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
901  ret <4 x i32> %a
902}
903
904; CHECK-LABEL: andnot_v4i32:
905; NO-SIMD128-NOT: v128
906; SIMD128-NEXT: .functype andnot_v4i32 (v128, v128) -> (v128){{$}}
907; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}}
908; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
909; SIMD128-FAST-NEXT: v128.not
910; SIMD128-FAST-NEXT: v128.and
911; SIMD128-FAST-NEXT: return
912define <4 x i32> @andnot_v4i32(<4 x i32> %x, <4 x i32> %y) {
913 %inv_y = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1>
914 %a = and <4 x i32> %x, %inv_y
915 ret <4 x i32> %a
916}
917
918; CHECK-LABEL: bitselect_v4i32:
919; NO-SIMD128-NOT: v128
920; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}}
921; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
922; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
923; SIMD128-FAST-NEXT: v128.not
924; SIMD128-FAST-NEXT: v128.and
925; SIMD128-FAST-NEXT: v128.and
926; SIMD128-FAST-NEXT: v128.or
927; SIMD128-FAST-NEXT: return
928define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) {
929  %masked_v1 = and <4 x i32> %c, %v1
930  %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c
931  %masked_v2 = and <4 x i32> %inv_mask, %v2
932  %a = or <4 x i32> %masked_v2, %masked_v1
933  ret <4 x i32> %a
934}
935
936; ==============================================================================
937; 2 x i64
938; ==============================================================================
939; CHECK-LABEL: add_v2i64:
940; NO-SIMD128-NOT: i64x2
941; SIMD128-NEXT: .functype add_v2i64 (v128, v128) -> (v128){{$}}
942; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}}
943; SIMD128-NEXT: return $pop[[R]]{{$}}
944define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) {
945  %a = add <2 x i64> %x, %y
946  ret <2 x i64> %a
947}
948
949; CHECK-LABEL: sub_v2i64:
950; NO-SIMD128-NOT: i64x2
951; SIMD128-NEXT: .functype sub_v2i64 (v128, v128) -> (v128){{$}}
952; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
953; SIMD128-NEXT: return $pop[[R]]{{$}}
954define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) {
955  %a = sub <2 x i64> %x, %y
956  ret <2 x i64> %a
957}
958
959; v2i64.mul is not in spec
960; CHECK-LABEL: mul_v2i64:
961; NO-SIMD128-NOT: i64x2
962; SIMD128-NOT: i64x2.mul
963; SIMD128: i64x2.extract_lane
964; SIMD128: i64.mul
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