1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-SLOW
2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-FAST
3; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128-VM
4; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128-VM
5; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
6; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 -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 -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext
10; RUN: llc < %s -O2 -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext
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: .param v128, v128{{$}}
23; SIMD128-NEXT: .result v128{{$}}
24; SIMD128-NEXT: i8x16.add $push[[R:[0-9]+]]=, $0, $1{{$}}
25; SIMD128-NEXT: return $pop[[R]]{{$}}
26define <16 x i8> @add_v16i8(<16 x i8> %x, <16 x i8> %y) {
27  %a = add <16 x i8> %x, %y
28  ret <16 x i8> %a
29}
30
31; CHECK-LABEL: sub_v16i8:
32; NO-SIMD128-NOT: i8x16
33; SIMD128-NEXT: .param v128, v128{{$}}
34; SIMD128-NEXT: .result v128{{$}}
35; SIMD128-NEXT: i8x16.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
36; SIMD128-NEXT: return $pop[[R]]{{$}}
37define <16 x i8> @sub_v16i8(<16 x i8> %x, <16 x i8> %y) {
38  %a = sub <16 x i8> %x, %y
39  ret <16 x i8> %a
40}
41
42; CHECK-LABEL: mul_v16i8:
43; NO-SIMD128-NOT: i8x16
44; SIMD128-NEXT: .param v128, v128{{$}}
45; SIMD128-NEXT: .result v128{{$}}
46; SIMD128-NEXT: i8x16.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
47; SIMD128-NEXT: return $pop[[R]]{{$}}
48define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) {
49  %a = mul <16 x i8> %x, %y
50  ret <16 x i8> %a
51}
52
53; CHECK-LABEL: neg_v16i8:
54; NO-SIMD128-NOT: i8x16
55; SIMD128-NEXT: .param v128{{$}}
56; SIMD128-NEXT: .result v128{{$}}
57; SIMD128-NEXT: i8x16.neg $push[[R:[0-9]+]]=, $0{{$}}
58; SIMD128-NEXT: return $pop[[R]]{{$}}
59define <16 x i8> @neg_v16i8(<16 x i8> %x) {
60  %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0,
61                      i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>,
62                     %x
63  ret <16 x i8> %a
64}
65
66; CHECK-LABEL: shl_v16i8:
67; NO-SIMD128-NOT: i8x16
68; SIMD128-NEXT: .param v128, i32{{$}}
69; SIMD128-NEXT: .result v128{{$}}
70; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
71; SIMD128-NEXT: return $pop[[R]]{{$}}
72define <16 x i8> @shl_v16i8(<16 x i8> %v, i8 %x) {
73  %t = insertelement <16 x i8> undef, i8 %x, i32 0
74  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
75    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
76                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
77  %a = shl <16 x i8> %v, %s
78  ret <16 x i8> %a
79}
80
81; CHECK-LABEL: shl_const_v16i8:
82; NO-SIMD128-NOT: i8x16
83; SIMD128-NEXT: .param v128{{$}}
84; SIMD128-NEXT: .result v128{{$}}
85; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
86; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
87; SIMD128-NEXT: return $pop[[R]]{{$}}
88define <16 x i8> @shl_const_v16i8(<16 x i8> %v) {
89  %a = shl <16 x i8> %v,
90    <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5,
91     i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
92  ret <16 x i8> %a
93}
94
95; CHECK-LABEL: shr_s_v16i8:
96; NO-SIMD128-NOT: i8x16
97; SIMD128-NEXT: .param v128, i32{{$}}
98; SIMD128-NEXT: .result v128{{$}}
99; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
100; SIMD128-NEXT: return $pop[[R]]{{$}}
101define <16 x i8> @shr_s_v16i8(<16 x i8> %v, i8 %x) {
102  %t = insertelement <16 x i8> undef, i8 %x, i32 0
103  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
104    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
105                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
106  %a = ashr <16 x i8> %v, %s
107  ret <16 x i8> %a
108}
109
110; CHECK-LABEL: shr_u_v16i8:
111; NO-SIMD128-NOT: i8x16
112; SIMD128-NEXT: .param v128, i32{{$}}
113; SIMD128-NEXT: .result v128{{$}}
114; SIMD128-NEXT: i8x16.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
115; SIMD128-NEXT: return $pop[[R]]{{$}}
116define <16 x i8> @shr_u_v16i8(<16 x i8> %v, i8 %x) {
117  %t = insertelement <16 x i8> undef, i8 %x, i32 0
118  %s = shufflevector <16 x i8> %t, <16 x i8> undef,
119    <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
120                i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
121  %a = lshr <16 x i8> %v, %s
122  ret <16 x i8> %a
123}
124
125; CHECK-LABEL: and_v16i8:
126; NO-SIMD128-NOT: v128
127; SIMD128-NEXT: .param v128, v128{{$}}
128; SIMD128-NEXT: .result v128{{$}}
129; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
130; SIMD128-NEXT: return $pop[[R]]{{$}}
131define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) {
132  %a = and <16 x i8> %x, %y
133  ret <16 x i8> %a
134}
135
136; CHECK-LABEL: or_v16i8:
137; NO-SIMD128-NOT: v128
138; SIMD128-NEXT: .param v128, v128{{$}}
139; SIMD128-NEXT: .result v128{{$}}
140; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
141; SIMD128-NEXT: return $pop[[R]]{{$}}
142define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) {
143  %a = or <16 x i8> %x, %y
144  ret <16 x i8> %a
145}
146
147; CHECK-LABEL: xor_v16i8:
148; NO-SIMD128-NOT: v128
149; SIMD128-NEXT: .param v128, v128{{$}}
150; SIMD128-NEXT: .result v128{{$}}
151; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
152; SIMD128-NEXT: return $pop[[R]]{{$}}
153define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) {
154  %a = xor <16 x i8> %x, %y
155  ret <16 x i8> %a
156}
157
158; CHECK-LABEL: not_v16i8:
159; NO-SIMD128-NOT: v128
160; SIMD128-NEXT: .param v128{{$}}
161; SIMD128-NEXT: .result v128{{$}}
162; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
163; SIMD128-NEXT: return $pop[[R]]{{$}}
164define <16 x i8> @not_v16i8(<16 x i8> %x) {
165  %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1,
166                          i8 -1, i8 -1, i8 -1, i8 -1,
167                          i8 -1, i8 -1, i8 -1, i8 -1,
168                          i8 -1, i8 -1, i8 -1, i8 -1>
169  ret <16 x i8> %a
170}
171
172; CHECK-LABEL: bitselect_v16i8:
173; NO-SIMD128-NOT: v128
174; SIMD128-NEXT: .param v128, v128, v128{{$}}
175; SIMD128-NEXT: .result v128{{$}}
176; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
177; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
178; SIMD128-FAST-NEXT: v128.and
179; SIMD128-FAST-NEXT: v128.not
180; SIMD128-FAST-NEXT: v128.and
181; SIMD128-FAST-NEXT: v128.or
182; SIMD128-FAST-NEXT: return
183define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) {
184  %masked_v1 = and <16 x i8> %c, %v1
185  %inv_mask = xor <16 x i8> %c,
186    <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
187     i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
188  %masked_v2 = and <16 x i8> %inv_mask, %v2
189  %a = or <16 x i8> %masked_v1, %masked_v2
190  ret <16 x i8> %a
191}
192
193; ==============================================================================
194; 8 x i16
195; ==============================================================================
196; CHECK-LABEL: add_v8i16:
197; NO-SIMD128-NOT: i16x8
198; SIMD128-NEXT: .param v128, v128{{$}}
199; SIMD128-NEXT: .result v128{{$}}
200; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}}
201; SIMD128-NEXT: return $pop[[R]]{{$}}
202define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) {
203  %a = add <8 x i16> %x, %y
204  ret <8 x i16> %a
205}
206
207; CHECK-LABEL: sub_v8i16:
208; NO-SIMD128-NOT: i16x8
209; SIMD128-NEXT: .param v128, v128{{$}}
210; SIMD128-NEXT: .result v128{{$}}
211; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
212; SIMD128-NEXT: return $pop[[R]]{{$}}
213define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) {
214  %a = sub <8 x i16> %x, %y
215  ret <8 x i16> %a
216}
217
218; CHECK-LABEL: mul_v8i16:
219; NO-SIMD128-NOT: i16x8
220; SIMD128-NEXT: .param v128, v128{{$}}
221; SIMD128-NEXT: .result v128{{$}}
222; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
223; SIMD128-NEXT: return $pop[[R]]{{$}}
224define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) {
225  %a = mul <8 x i16> %x, %y
226  ret <8 x i16> %a
227}
228
229; CHECK-LABEL: neg_v8i16:
230; NO-SIMD128-NOT: i16x8
231; SIMD128-NEXT: .param v128{{$}}
232; SIMD128-NEXT: .result v128{{$}}
233; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}}
234; SIMD128-NEXT: return $pop[[R]]{{$}}
235define <8 x i16> @neg_v8i16(<8 x i16> %x) {
236  %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>,
237                     %x
238  ret <8 x i16> %a
239}
240
241; CHECK-LABEL: shl_v8i16:
242; NO-SIMD128-NOT: i16x8
243; SIMD128-NEXT: .param v128, i32{{$}}
244; SIMD128-NEXT: .result v128{{$}}
245; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
246; SIMD128-NEXT: return $pop[[R]]{{$}}
247define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) {
248  %t = insertelement <8 x i16> undef, i16 %x, i32 0
249  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
250    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
251  %a = shl <8 x i16> %v, %s
252  ret <8 x i16> %a
253}
254
255; CHECK-LABEL: shl_const_v8i16:
256; NO-SIMD128-NOT: i16x8
257; SIMD128-NEXT: .param v128{{$}}
258; SIMD128-NEXT: .result v128{{$}}
259; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
260; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
261; SIMD128-NEXT: return $pop[[R]]{{$}}
262define <8 x i16> @shl_const_v8i16(<8 x i16> %v) {
263  %a = shl <8 x i16> %v,
264    <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
265  ret <8 x i16> %a
266}
267
268; CHECK-LABEL: shr_s_v8i16:
269; NO-SIMD128-NOT: i16x8
270; SIMD128-NEXT: .param v128, i32{{$}}
271; SIMD128-NEXT: .result v128{{$}}
272; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
273; SIMD128-NEXT: return $pop[[R]]{{$}}
274define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) {
275  %t = insertelement <8 x i16> undef, i16 %x, i32 0
276  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
277    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
278  %a = ashr <8 x i16> %v, %s
279  ret <8 x i16> %a
280}
281
282; CHECK-LABEL: shr_u_v8i16:
283; NO-SIMD128-NOT: i16x8
284; SIMD128-NEXT: .param v128, i32{{$}}
285; SIMD128-NEXT: .result v128{{$}}
286; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
287; SIMD128-NEXT: return $pop[[R]]{{$}}
288define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) {
289  %t = insertelement <8 x i16> undef, i16 %x, i32 0
290  %s = shufflevector <8 x i16> %t, <8 x i16> undef,
291    <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
292  %a = lshr <8 x i16> %v, %s
293  ret <8 x i16> %a
294}
295
296; CHECK-LABEL: and_v8i16:
297; NO-SIMD128-NOT: v128
298; SIMD128-NEXT: .param v128, v128{{$}}
299; SIMD128-NEXT: .result v128{{$}}
300; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
301; SIMD128-NEXT: return $pop[[R]]{{$}}
302define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) {
303  %a = and <8 x i16> %x, %y
304  ret <8 x i16> %a
305}
306
307; CHECK-LABEL: or_v8i16:
308; NO-SIMD128-NOT: v128
309; SIMD128-NEXT: .param v128, v128{{$}}
310; SIMD128-NEXT: .result v128{{$}}
311; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
312; SIMD128-NEXT: return $pop[[R]]{{$}}
313define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) {
314  %a = or <8 x i16> %x, %y
315  ret <8 x i16> %a
316}
317
318; CHECK-LABEL: xor_v8i16:
319; NO-SIMD128-NOT: v128
320; SIMD128-NEXT: .param v128, v128{{$}}
321; SIMD128-NEXT: .result v128{{$}}
322; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
323; SIMD128-NEXT: return $pop[[R]]{{$}}
324define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) {
325  %a = xor <8 x i16> %x, %y
326  ret <8 x i16> %a
327}
328
329; CHECK-LABEL: not_v8i16:
330; NO-SIMD128-NOT: v128
331; SIMD128-NEXT: .param v128{{$}}
332; SIMD128-NEXT: .result v128{{$}}
333; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
334; SIMD128-NEXT: return $pop[[R]]{{$}}
335define <8 x i16> @not_v8i16(<8 x i16> %x) {
336  %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1,
337                          i16 -1, i16 -1, i16 -1, i16 -1>
338  ret <8 x i16> %a
339}
340
341; CHECK-LABEL: bitselect_v8i16:
342; NO-SIMD128-NOT: v128
343; SIMD128-NEXT: .param v128, v128, v128{{$}}
344; SIMD128-NEXT: .result v128{{$}}
345; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
346; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
347; SIMD128-FAST-NEXT: v128.and
348; SIMD128-FAST-NEXT: v128.not
349; SIMD128-FAST-NEXT: v128.and
350; SIMD128-FAST-NEXT: v128.or
351; SIMD128-FAST-NEXT: return
352define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) {
353  %masked_v1 = and <8 x i16> %v1, %c
354  %inv_mask = xor <8 x i16>
355    <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>,
356    %c
357  %masked_v2 = and <8 x i16> %v2, %inv_mask
358  %a = or <8 x i16> %masked_v1, %masked_v2
359  ret <8 x i16> %a
360}
361
362; ==============================================================================
363; 4 x i32
364; ==============================================================================
365; CHECK-LABEL: add_v4i32:
366; NO-SIMD128-NOT: i32x4
367; SIMD128-NEXT: .param v128, v128{{$}}
368; SIMD128-NEXT: .result v128{{$}}
369; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}}
370; SIMD128-NEXT: return $pop[[R]]{{$}}
371define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) {
372  %a = add <4 x i32> %x, %y
373  ret <4 x i32> %a
374}
375
376; CHECK-LABEL: sub_v4i32:
377; NO-SIMD128-NOT: i32x4
378; SIMD128-NEXT: .param v128, v128{{$}}
379; SIMD128-NEXT: .result v128{{$}}
380; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
381; SIMD128-NEXT: return $pop[[R]]{{$}}
382define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) {
383  %a = sub <4 x i32> %x, %y
384  ret <4 x i32> %a
385}
386
387; CHECK-LABEL: mul_v4i32:
388; NO-SIMD128-NOT: i32x4
389; SIMD128-NEXT: .param v128, v128{{$}}
390; SIMD128-NEXT: .result v128{{$}}
391; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
392; SIMD128-NEXT: return $pop[[R]]{{$}}
393define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) {
394  %a = mul <4 x i32> %x, %y
395  ret <4 x i32> %a
396}
397
398; CHECK-LABEL: neg_v4i32:
399; NO-SIMD128-NOT: i32x4
400; SIMD128-NEXT: .param v128{{$}}
401; SIMD128-NEXT: .result v128{{$}}
402; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
403; SIMD128-NEXT: return $pop[[R]]{{$}}
404define <4 x i32> @neg_v4i32(<4 x i32> %x) {
405  %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x
406  ret <4 x i32> %a
407}
408
409; CHECK-LABEL: shl_v4i32:
410; NO-SIMD128-NOT: i32x4
411; SIMD128-NEXT: .param v128, i32{{$}}
412; SIMD128-NEXT: .result v128{{$}}
413; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
414; SIMD128-NEXT: return $pop[[R]]{{$}}
415define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) {
416  %t = insertelement <4 x i32> undef, i32 %x, i32 0
417  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
418    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
419  %a = shl <4 x i32> %v, %s
420  ret <4 x i32> %a
421}
422
423; CHECK-LABEL: shl_const_v4i32:
424; NO-SIMD128-NOT: i32x4
425; SIMD128-NEXT: .param v128{{$}}
426; SIMD128-NEXT: .result v128{{$}}
427; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5
428; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
429; SIMD128-NEXT: return $pop[[R]]{{$}}
430define <4 x i32> @shl_const_v4i32(<4 x i32> %v) {
431  %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5>
432  ret <4 x i32> %a
433}
434
435; CHECK-LABEL: shr_s_v4i32:
436; NO-SIMD128-NOT: i32x4
437; SIMD128-NEXT: .param v128, i32{{$}}
438; SIMD128-NEXT: .result v128{{$}}
439; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
440; SIMD128-NEXT: return $pop[[R]]{{$}}
441define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) {
442  %t = insertelement <4 x i32> undef, i32 %x, i32 0
443  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
444    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
445  %a = ashr <4 x i32> %v, %s
446  ret <4 x i32> %a
447}
448
449; CHECK-LABEL: shr_u_v4i32:
450; NO-SIMD128-NOT: i32x4
451; SIMD128-NEXT: .param v128, i32{{$}}
452; SIMD128-NEXT: .result v128{{$}}
453; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
454; SIMD128-NEXT: return $pop[[R]]{{$}}
455define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) {
456  %t = insertelement <4 x i32> undef, i32 %x, i32 0
457  %s = shufflevector <4 x i32> %t, <4 x i32> undef,
458    <4 x i32> <i32 0, i32 0, i32 0, i32 0>
459  %a = lshr <4 x i32> %v, %s
460  ret <4 x i32> %a
461}
462
463; CHECK-LABEL: and_v4i32:
464; NO-SIMD128-NOT: v128
465; SIMD128-NEXT: .param v128, v128{{$}}
466; SIMD128-NEXT: .result v128{{$}}
467; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
468; SIMD128-NEXT: return $pop[[R]]{{$}}
469define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) {
470  %a = and <4 x i32> %x, %y
471  ret <4 x i32> %a
472}
473
474; CHECK-LABEL: or_v4i32:
475; NO-SIMD128-NOT: v128
476; SIMD128-NEXT: .param v128, v128{{$}}
477; SIMD128-NEXT: .result v128{{$}}
478; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
479; SIMD128-NEXT: return $pop[[R]]{{$}}
480define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) {
481  %a = or <4 x i32> %x, %y
482  ret <4 x i32> %a
483}
484
485; CHECK-LABEL: xor_v4i32:
486; NO-SIMD128-NOT: v128
487; SIMD128-NEXT: .param v128, v128{{$}}
488; SIMD128-NEXT: .result v128{{$}}
489; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
490; SIMD128-NEXT: return $pop[[R]]{{$}}
491define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) {
492  %a = xor <4 x i32> %x, %y
493  ret <4 x i32> %a
494}
495
496; CHECK-LABEL: not_v4i32:
497; NO-SIMD128-NOT: v128
498; SIMD128-NEXT: .param v128{{$}}
499; SIMD128-NEXT: .result v128{{$}}
500; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
501; SIMD128-NEXT: return $pop[[R]]{{$}}
502define <4 x i32> @not_v4i32(<4 x i32> %x) {
503  %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
504  ret <4 x i32> %a
505}
506
507; CHECK-LABEL: bitselect_v4i32:
508; NO-SIMD128-NOT: v128
509; SIMD128-NEXT: .param v128, v128, v128{{$}}
510; SIMD128-NEXT: .result v128{{$}}
511; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
512; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
513; SIMD128-FAST-NEXT: v128.not
514; SIMD128-FAST-NEXT: v128.and
515; SIMD128-FAST-NEXT: v128.and
516; SIMD128-FAST-NEXT: v128.or
517; SIMD128-FAST-NEXT: return
518define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) {
519  %masked_v1 = and <4 x i32> %c, %v1
520  %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c
521  %masked_v2 = and <4 x i32> %inv_mask, %v2
522  %a = or <4 x i32> %masked_v2, %masked_v1
523  ret <4 x i32> %a
524}
525
526; ==============================================================================
527; 2 x i64
528; ==============================================================================
529; CHECK-LABEL: add_v2i64:
530; NO-SIMD128-NOT: i64x2
531; SIMD128-VM-NOT: i64x2
532; SIMD128-NEXT: .param v128, v128{{$}}
533; SIMD128-NEXT: .result v128{{$}}
534; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}}
535; SIMD128-NEXT: return $pop[[R]]{{$}}
536define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) {
537  %a = add <2 x i64> %x, %y
538  ret <2 x i64> %a
539}
540
541; CHECK-LABEL: sub_v2i64:
542; NO-SIMD128-NOT: i64x2
543; SIMD128-VM-NOT: i64x2
544; SIMD128-NEXT: .param v128, v128{{$}}
545; SIMD128-NEXT: .result v128{{$}}
546; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
547; SIMD128-NEXT: return $pop[[R]]{{$}}
548define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) {
549  %a = sub <2 x i64> %x, %y
550  ret <2 x i64> %a
551}
552
553; v2i64.mul is not in spec
554; CHECK-LABEL: mul_v2i64:
555; NO-SIMD128-NOT: i64x2
556; SIMD128-VM-NOT: i64x2
557; SIMD128-NOT: i64x2.mul
558; SIMD128: i64x2.extract_lane
559; SIMD128: i64.mul
560define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) {
561  %a = mul <2 x i64> %x, %y
562  ret <2 x i64> %a
563}
564
565; CHECK-LABEL: neg_v2i64:
566; NO-SIMD128-NOT: i64x2
567; SIMD128-NEXT: .param v128{{$}}
568; SIMD128-NEXT: .result v128{{$}}
569; SIMD128-NEXT: i64x2.neg $push[[R:[0-9]+]]=, $0{{$}}
570; SIMD128-NEXT: return $pop[[R]]{{$}}
571define <2 x i64> @neg_v2i64(<2 x i64> %x) {
572  %a = sub <2 x i64> <i64 0, i64 0>, %x
573  ret <2 x i64> %a
574}
575
576; CHECK-LABEL: shl_v2i64:
577; NO-SIMD128-NOT: i64x2
578; SIMD128-NEXT: .param v128, i32{{$}}
579; SIMD128-NEXT: .result v128{{$}}
580; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
581; SIMD128-NEXT: return $pop[[R]]{{$}}
582define <2 x i64> @shl_v2i64(<2 x i64> %v, i32 %x) {
583  %x2 = zext i32 %x to i64
584  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
585  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
586  %a = shl <2 x i64> %v, %s
587  ret <2 x i64> %a
588}
589
590; CHECK-LABEL: shl_nozext_v2i64:
591; NO-SIMD128-NOT: i64x2
592; SIMD128-NEXT: .param v128, i64{{$}}
593; SIMD128-NEXT: .result v128{{$}}
594; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}}
595; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
596; SIMD128-NEXT: return $pop[[R]]{{$}}
597define <2 x i64> @shl_nozext_v2i64(<2 x i64> %v, i64 %x) {
598  %t = insertelement <2 x i64> undef, i64 %x, i32 0
599  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
600  %a = shl <2 x i64> %v, %s
601  ret <2 x i64> %a
602}
603
604; CHECK-LABEL: shl_const_v2i64:
605; NO-SIMD128-NOT: i64x2
606; SIMD128-NEXT: .param v128{{$}}
607; SIMD128-NEXT: .result v128{{$}}
608; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
609; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
610; SIMD128-NEXT: return $pop[[R]]{{$}}
611define <2 x i64> @shl_const_v2i64(<2 x i64> %v) {
612  %a = shl <2 x i64> %v, <i64 5, i64 5>
613  ret <2 x i64> %a
614}
615
616; CHECK-LABEL: shr_s_v2i64:
617; NO-SIMD128-NOT: i64x2
618; SIMD128-NEXT: .param v128, i32{{$}}
619; SIMD128-NEXT: .result v128{{$}}
620; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
621; SIMD128-NEXT: return $pop[[R]]{{$}}
622define <2 x i64> @shr_s_v2i64(<2 x i64> %v, i32 %x) {
623  %x2 = zext i32 %x to i64
624  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
625  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
626  %a = ashr <2 x i64> %v, %s
627  ret <2 x i64> %a
628}
629
630; CHECK-LABEL: shr_s_nozext_v2i64:
631; NO-SIMD128-NOT: i64x2
632; SIMD128-NEXT: .param v128, i64{{$}}
633; SIMD128-NEXT: .result v128{{$}}
634; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}}
635; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
636; SIMD128-NEXT: return $pop[[R]]{{$}}
637define <2 x i64> @shr_s_nozext_v2i64(<2 x i64> %v, i64 %x) {
638  %t = insertelement <2 x i64> undef, i64 %x, i32 0
639  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
640  %a = ashr <2 x i64> %v, %s
641  ret <2 x i64> %a
642}
643
644; CHECK-LABEL: shr_s_const_v2i64:
645; NO-SIMD128-NOT: i64x2
646; SIMD128-NEXT: .param v128{{$}}
647; SIMD128-NEXT: .result v128{{$}}
648; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
649; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
650; SIMD128-NEXT: return $pop[[R]]{{$}}
651define <2 x i64> @shr_s_const_v2i64(<2 x i64> %v) {
652  %a = ashr <2 x i64> %v, <i64 5, i64 5>
653  ret <2 x i64> %a
654}
655
656; CHECK-LABEL: shr_u_v2i64:
657; NO-SIMD128-NOT: i64x2
658; SIMD128-NEXT: .param v128, i32{{$}}
659; SIMD128-NEXT: .result v128{{$}}
660; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
661; SIMD128-NEXT: return $pop[[R]]{{$}}
662define <2 x i64> @shr_u_v2i64(<2 x i64> %v, i32 %x) {
663  %x2 = zext i32 %x to i64
664  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
665  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
666  %a = lshr <2 x i64> %v, %s
667  ret <2 x i64> %a
668}
669
670; CHECK-LABEL: shr_u_nozext_v2i64:
671; NO-SIMD128-NOT: i64x2
672; SIMD128-NEXT: .param v128, i64{{$}}
673; SIMD128-NEXT: .result v128{{$}}
674; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}}
675; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
676; SIMD128-NEXT: return $pop[[R]]{{$}}
677define <2 x i64> @shr_u_nozext_v2i64(<2 x i64> %v, i64 %x) {
678  %t = insertelement <2 x i64> undef, i64 %x, i32 0
679  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
680  %a = lshr <2 x i64> %v, %s
681  ret <2 x i64> %a
682}
683
684; CHECK-LABEL: shr_u_const_v2i64:
685; NO-SIMD128-NOT: i64x2
686; SIMD128-NEXT: .param v128{{$}}
687; SIMD128-NEXT: .result v128{{$}}
688; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}}
689; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
690; SIMD128-NEXT: return $pop[[R]]{{$}}
691define <2 x i64> @shr_u_const_v2i64(<2 x i64> %v) {
692  %a = lshr <2 x i64> %v, <i64 5, i64 5>
693  ret <2 x i64> %a
694}
695
696; CHECK-LABEL: and_v2i64:
697; NO-SIMD128-NOT: v128
698; SIMD128-VM-NOT: v128
699; SIMD128-NEXT: .param v128, v128{{$}}
700; SIMD128-NEXT: .result v128{{$}}
701; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}}
702; SIMD128-NEXT: return $pop[[R]]{{$}}
703define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) {
704  %a = and <2 x i64> %x, %y
705  ret <2 x i64> %a
706}
707
708; CHECK-LABEL: or_v2i64:
709; NO-SIMD128-NOT: v128
710; SIMD128-VM-NOT: v128
711; SIMD128-NEXT: .param v128, v128{{$}}
712; SIMD128-NEXT: .result v128{{$}}
713; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}}
714; SIMD128-NEXT: return $pop[[R]]{{$}}
715define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) {
716  %a = or <2 x i64> %x, %y
717  ret <2 x i64> %a
718}
719
720; CHECK-LABEL: xor_v2i64:
721; NO-SIMD128-NOT: v128
722; SIMD128-VM-NOT: v128
723; SIMD128-NEXT: .param v128, v128{{$}}
724; SIMD128-NEXT: .result v128{{$}}
725; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}}
726; SIMD128-NEXT: return $pop[[R]]{{$}}
727define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) {
728  %a = xor <2 x i64> %x, %y
729  ret <2 x i64> %a
730}
731
732; CHECK-LABEL: not_v2i64:
733; NO-SIMD128-NOT: v128
734; SIMD128-VM-NOT: v128
735; SIMD128-NEXT: .param v128{{$}}
736; SIMD128-NEXT: .result v128{{$}}
737; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}}
738; SIMD128-NEXT: return $pop[[R]]{{$}}
739define <2 x i64> @not_v2i64(<2 x i64> %x) {
740  %a = xor <2 x i64> %x, <i64 -1, i64 -1>
741  ret <2 x i64> %a
742}
743
744; CHECK-LABEL: bitselect_v2i64:
745; NO-SIMD128-NOT: v128
746; SIMD128-VM-NOT: v128
747; SIMD128-NEXT: .param v128, v128, v128{{$}}
748; SIMD128-NEXT: .result v128{{$}}
749; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}}
750; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}}
751; SIMD128-FAST-NEXT: v128.not
752; SIMD128-FAST-NEXT: v128.and
753; SIMD128-FAST-NEXT: v128.and
754; SIMD128-FAST-NEXT: v128.or
755; SIMD128-FAST-NEXT: return
756define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) {
757  %masked_v1 = and <2 x i64> %v1, %c
758  %inv_mask = xor <2 x i64> <i64 -1, i64 -1>, %c
759  %masked_v2 = and <2 x i64> %v2, %inv_mask
760  %a = or <2 x i64> %masked_v2, %masked_v1
761  ret <2 x i64> %a
762}
763
764; ==============================================================================
765; 4 x float
766; ==============================================================================
767; CHECK-LABEL: neg_v4f32:
768; NO-SIMD128-NOT: f32x4
769; SIMD128-NEXT: .param v128{{$}}
770; SIMD128-NEXT: .result v128{{$}}
771; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
772; SIMD128-NEXT: return $pop[[R]]{{$}}
773define <4 x float> @neg_v4f32(<4 x float> %x) {
774  ; nsz makes this semantically equivalent to flipping sign bit
775  %a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x
776  ret <4 x float> %a
777}
778
779; CHECK-LABEL: abs_v4f32:
780; NO-SIMD128-NOT: f32x4
781; SIMD128-NEXT: .param v128{{$}}
782; SIMD128-NEXT: .result v128{{$}}
783; SIMD128-NEXT: f32x4.abs $push[[R:[0-9]+]]=, $0{{$}}
784; SIMD128-NEXT: return $pop[[R]]{{$}}
785declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone
786define <4 x float> @abs_v4f32(<4 x float> %x) {
787  %a = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
788  ret <4 x float> %a
789}
790
791; CHECK-LABEL: min_unordered_v4f32:
792; NO-SIMD128-NOT: f32x4
793; SIMD128-NEXT: .param v128{{$}}
794; SIMD128-NEXT: .result v128{{$}}
795; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
796; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
797; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
798; SIMD128-NEXT: return $pop[[R]]{{$}}
799define <4 x float> @min_unordered_v4f32(<4 x float> %x) {
800  %cmps = fcmp ule <4 x float> %x, <float 5., float 5., float 5., float 5.>
801  %a = select <4 x i1> %cmps, <4 x float> %x,
802    <4 x float> <float 5., float 5., float 5., float 5.>
803  ret <4 x float> %a
804}
805
806; CHECK-LABEL: max_unordered_v4f32:
807; NO-SIMD128-NOT: f32x4
808; SIMD128-NEXT: .param v128{{$}}
809; SIMD128-NEXT: .result v128{{$}}
810; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
811; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
812; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
813; SIMD128-NEXT: return $pop[[R]]{{$}}
814define <4 x float> @max_unordered_v4f32(<4 x float> %x) {
815  %cmps = fcmp uge <4 x float> %x, <float 5., float 5., float 5., float 5.>
816  %a = select <4 x i1> %cmps, <4 x float> %x,
817    <4 x float> <float 5., float 5., float 5., float 5.>
818  ret <4 x float> %a
819}
820
821; CHECK-LABEL: min_ordered_v4f32:
822; NO-SIMD128-NOT: f32x4
823; SIMD128-NEXT: .param v128{{$}}
824; SIMD128-NEXT: .result v128{{$}}
825; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
826; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
827; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}}
828; SIMD128-NEXT: return $pop[[R]]{{$}}
829define <4 x float> @min_ordered_v4f32(<4 x float> %x) {
830  %cmps = fcmp ole <4 x float> <float 5., float 5., float 5., float 5.>, %x
831  %a = select <4 x i1> %cmps,
832    <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x
833  ret <4 x float> %a
834}
835
836; CHECK-LABEL: max_ordered_v4f32:
837; NO-SIMD128-NOT: f32x4
838; SIMD128-NEXT: .param v128{{$}}
839; SIMD128-NEXT: .result v128{{$}}
840; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2
841; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
842; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}}
843; SIMD128-NEXT: return $pop[[R]]{{$}}
844define <4 x float> @max_ordered_v4f32(<4 x float> %x) {
845  %cmps = fcmp oge <4 x float> <float 5., float 5., float 5., float 5.>, %x
846  %a = select <4 x i1> %cmps,
847    <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x
848  ret <4 x float> %a
849}
850
851; CHECK-LABEL: min_intrinsic_v4f32:
852; NO-SIMD128-NOT: f32x4
853; SIMD128-NEXT: .param v128, v128{{$}}
854; SIMD128-NEXT: .result v128{{$}}
855; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
856; SIMD128-NEXT: return $pop[[R]]{{$}}
857declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>)
858define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
859  %a = call <4 x float> @llvm.minimum.v4f32(<4 x float> %x, <4 x float> %y)
860  ret <4 x float> %a
861}
862
863; CHECK-LABEL: max_intrinsic_v4f32:
864; NO-SIMD128-NOT: f32x4
865; SIMD128-NEXT: .param v128, v128{{$}}
866; SIMD128-NEXT: .result v128{{$}}
867; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
868; SIMD128-NEXT: return $pop[[R]]{{$}}
869declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
870define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
871  %a = call <4 x float> @llvm.maximum.v4f32(<4 x float> %x, <4 x float> %y)
872  ret <4 x float> %a
873}
874
875; CHECK-LABEL: add_v4f32:
876; NO-SIMD128-NOT: f32x4
877; SIMD128-NEXT: .param v128, v128{{$}}
878; SIMD128-NEXT: .result v128{{$}}
879; SIMD128-NEXT: f32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}}
880; SIMD128-NEXT: return $pop[[R]]{{$}}
881define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) {
882  %a = fadd <4 x float> %x, %y
883  ret <4 x float> %a
884}
885
886; CHECK-LABEL: sub_v4f32:
887; NO-SIMD128-NOT: f32x4
888; SIMD128-NEXT: .param v128, v128{{$}}
889; SIMD128-NEXT: .result v128{{$}}
890; SIMD128-NEXT: f32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
891; SIMD128-NEXT: return $pop[[R]]{{$}}
892define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) {
893  %a = fsub <4 x float> %x, %y
894  ret <4 x float> %a
895}
896
897; CHECK-LABEL: div_v4f32:
898; NO-SIMD128-NOT: f32x4
899; SIMD128-NEXT: .param v128, v128{{$}}
900; SIMD128-NEXT: .result v128{{$}}
901; SIMD128-NEXT: f32x4.div $push[[R:[0-9]+]]=, $0, $1{{$}}
902; SIMD128-NEXT: return $pop[[R]]{{$}}
903define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) {
904  %a = fdiv <4 x float> %x, %y
905  ret <4 x float> %a
906}
907
908; CHECK-LABEL: mul_v4f32:
909; NO-SIMD128-NOT: f32x4
910; SIMD128-NEXT: .param v128, v128{{$}}
911; SIMD128-NEXT: .result v128{{$}}
912; SIMD128-NEXT: f32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
913; SIMD128-NEXT: return $pop[[R]]{{$}}
914define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) {
915  %a = fmul <4 x float> %x, %y
916  ret <4 x float> %a
917}
918
919; CHECK-LABEL: sqrt_v4f32:
920; NO-SIMD128-NOT: f32x4
921; SIMD128-NEXT: .param v128{{$}}
922; SIMD128-NEXT: .result v128{{$}}
923; SIMD128-NEXT: f32x4.sqrt $push[[R:[0-9]+]]=, $0{{$}}
924; SIMD128-NEXT: return $pop[[R]]{{$}}
925declare <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
926define <4 x float> @sqrt_v4f32(<4 x float> %x) {
927  %a = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
928  ret <4 x float> %a
929}
930
931; ==============================================================================
932; 2 x double
933; ==============================================================================
934; CHECK-LABEL: neg_v2f64:
935; NO-SIMD128-NOT: f64x2
936; SIMD128-NEXT: .param v128{{$}}
937; SIMD128-NEXT: .result v128{{$}}
938; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}}
939; SIMD128-NEXT: return $pop[[R]]{{$}}
940define <2 x double> @neg_v2f64(<2 x double> %x) {
941  ; nsz makes this semantically equivalent to flipping sign bit
942  %a = fsub nsz <2 x double> <double 0., double 0.>, %x
943  ret <2 x double> %a
944}
945
946; CHECK-LABEL: abs_v2f64:
947; NO-SIMD128-NOT: f64x2
948; SIMD128-NEXT: .param v128{{$}}
949; SIMD128-NEXT: .result v128{{$}}
950; SIMD128-NEXT: f64x2.abs $push[[R:[0-9]+]]=, $0{{$}}
951; SIMD128-NEXT: return $pop[[R]]{{$}}
952declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone
953define <2 x double> @abs_v2f64(<2 x double> %x) {
954  %a = call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
955  ret <2 x double> %a
956}
957
958; CHECK-LABEL: min_unordered_v2f64:
959; NO-SIMD128-NOT: f64x2
960; SIMD128-NEXT: .param v128{{$}}
961; SIMD128-NEXT: .result v128{{$}}
962; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
963; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
964; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
965; SIMD128-NEXT: return $pop[[R]]{{$}}
966define <2 x double> @min_unordered_v2f64(<2 x double> %x) {
967  %cmps = fcmp ule <2 x double> %x, <double 5., double 5.>
968  %a = select <2 x i1> %cmps, <2 x double> %x,
969    <2 x double> <double 5., double 5.>
970  ret <2 x double> %a
971}
972
973; CHECK-LABEL: max_unordered_v2f64:
974; NO-SIMD128-NOT: f64x2
975; SIMD128-NEXT: .param v128{{$}}
976; SIMD128-NEXT: .result v128{{$}}
977; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
978; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
979; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}}
980; SIMD128-NEXT: return $pop[[R]]{{$}}
981define <2 x double> @max_unordered_v2f64(<2 x double> %x) {
982  %cmps = fcmp uge <2 x double> %x, <double 5., double 5.>
983  %a = select <2 x i1> %cmps, <2 x double> %x,
984    <2 x double> <double 5., double 5.>
985  ret <2 x double> %a
986}
987
988; CHECK-LABEL: min_ordered_v2f64:
989; NO-SIMD128-NOT: f64x2
990; SIMD128-NEXT: .param v128{{$}}
991; SIMD128-NEXT: .result v128{{$}}
992; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
993; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
994; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}}
995; SIMD128-NEXT: return $pop[[R]]{{$}}
996define <2 x double> @min_ordered_v2f64(<2 x double> %x) {
997  %cmps = fcmp ole <2 x double> <double 5., double 5.>, %x
998  %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>,
999    <2 x double> %x
1000  ret <2 x double> %a
1001}
1002
1003; CHECK-LABEL: max_ordered_v2f64:
1004; NO-SIMD128-NOT: f64x2
1005; SIMD128-NEXT: .param v128{{$}}
1006; SIMD128-NEXT: .result v128{{$}}
1007; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2
1008; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]]
1009; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}}
1010; SIMD128-NEXT: return $pop[[R]]{{$}}
1011define <2 x double> @max_ordered_v2f64(<2 x double> %x) {
1012  %cmps = fcmp oge <2 x double> <double 5., double 5.>, %x
1013  %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>,
1014    <2 x double> %x
1015  ret <2 x double> %a
1016}
1017
1018; CHECK-LABEL: min_intrinsic_v2f64:
1019; NO-SIMD128-NOT: f64x2
1020; SIMD128-NEXT: .param v128, v128{{$}}
1021; SIMD128-NEXT: .result v128{{$}}
1022; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $1{{$}}
1023; SIMD128-NEXT: return $pop[[R]]{{$}}
1024declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
1025define <2 x double> @min_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) {
1026  %a = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> %y)
1027  ret <2 x double> %a
1028}
1029
1030; CHECK-LABEL: max_intrinsic_v2f64:
1031; NO-SIMD128-NOT: f64x2
1032; SIMD128-NEXT: .param v128, v128{{$}}
1033; SIMD128-NEXT: .result v128{{$}}
1034; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $1{{$}}
1035; SIMD128-NEXT: return $pop[[R]]{{$}}
1036declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
1037define <2 x double> @max_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) {
1038  %a = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> %y)
1039  ret <2 x double> %a
1040}
1041
1042; CHECK-LABEL: add_v2f64:
1043; NO-SIMD128-NOT: f64x2
1044; SIMD128-VM-NOT: f62x2
1045; SIMD128-NEXT: .param v128, v128{{$}}
1046; SIMD128-NEXT: .result v128{{$}}
1047; SIMD128-NEXT: f64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}}
1048; SIMD128-NEXT: return $pop[[R]]{{$}}
1049define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) {
1050  %a = fadd <2 x double> %x, %y
1051  ret <2 x double> %a
1052}
1053
1054; CHECK-LABEL: sub_v2f64:
1055; NO-SIMD128-NOT: f64x2
1056; SIMD128-VM-NOT: f62x2
1057; SIMD128-NEXT: .param v128, v128{{$}}
1058; SIMD128-NEXT: .result v128{{$}}
1059; SIMD128-NEXT: f64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}}
1060; SIMD128-NEXT: return $pop[[R]]{{$}}
1061define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) {
1062  %a = fsub <2 x double> %x, %y
1063  ret <2 x double> %a
1064}
1065
1066; CHECK-LABEL: div_v2f64:
1067; NO-SIMD128-NOT: f64x2
1068; SIMD128-VM-NOT: f62x2
1069; SIMD128-NEXT: .param v128, v128{{$}}
1070; SIMD128-NEXT: .result v128{{$}}
1071; SIMD128-NEXT: f64x2.div $push[[R:[0-9]+]]=, $0, $1{{$}}
1072; SIMD128-NEXT: return $pop[[R]]{{$}}
1073define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) {
1074  %a = fdiv <2 x double> %x, %y
1075  ret <2 x double> %a
1076}
1077
1078; CHECK-LABEL: mul_v2f64:
1079; NO-SIMD128-NOT: f64x2
1080; SIMD128-VM-NOT: f62x2
1081; SIMD128-NEXT: .param v128, v128{{$}}
1082; SIMD128-NEXT: .result v128{{$}}
1083; SIMD128-NEXT: f64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
1084; SIMD128-NEXT: return $pop[[R]]{{$}}
1085define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) {
1086  %a = fmul <2 x double> %x, %y
1087  ret <2 x double> %a
1088}
1089
1090; CHECK-LABEL: sqrt_v2f64:
1091; NO-SIMD128-NOT: f64x2
1092; SIMD128-NEXT: .param v128{{$}}
1093; SIMD128-NEXT: .result v128{{$}}
1094; SIMD128-NEXT: f64x2.sqrt $push[[R:[0-9]+]]=, $0{{$}}
1095; SIMD128-NEXT: return $pop[[R]]{{$}}
1096declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
1097define <2 x double> @sqrt_v2f64(<2 x double> %x) {
1098  %a = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
1099  ret <2 x double> %a
1100}
1101