1 // RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
2 // RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
3 // RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
4 
5 // SIMD convenience types
6 typedef char i8x16 __attribute((vector_size(16)));
7 typedef short i16x8 __attribute((vector_size(16)));
8 typedef int i32x4 __attribute((vector_size(16)));
9 typedef long long i64x2 __attribute((vector_size(16)));
10 typedef unsigned char u8x16 __attribute((vector_size(16)));
11 typedef unsigned short u16x8 __attribute((vector_size(16)));
12 typedef unsigned int u32x4 __attribute((vector_size(16)));
13 typedef unsigned long long u64x2 __attribute((vector_size(16)));
14 typedef float f32x4 __attribute((vector_size(16)));
15 typedef double f64x2 __attribute((vector_size(16)));
16 
17 __SIZE_TYPE__ memory_size(void) {
18   return __builtin_wasm_memory_size(0);
19   // WEBASSEMBLY32: call {{i.*}} @llvm.wasm.memory.size.i32(i32 0)
20   // WEBASSEMBLY64: call {{i.*}} @llvm.wasm.memory.size.i64(i32 0)
21 }
22 
23 __SIZE_TYPE__ memory_grow(__SIZE_TYPE__ delta) {
24   return __builtin_wasm_memory_grow(0, delta);
25   // WEBASSEMBLY32: call i32 @llvm.wasm.memory.grow.i32(i32 0, i32 %{{.*}})
26   // WEBASSEMBLY64: call i64 @llvm.wasm.memory.grow.i64(i32 0, i64 %{{.*}})
27 }
28 
29 void memory_init(void *dest, int offset, int size) {
30   __builtin_wasm_memory_init(3, 0, dest, offset, size);
31   // WEBASSEMBLY32: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
32   // WEBASSEMBLY64: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
33 }
34 
35 void data_drop() {
36   __builtin_wasm_data_drop(3);
37   // WEBASSEMBLY32: call void @llvm.wasm.data.drop(i32 3)
38   // WEBASSEMBLY64: call void @llvm.wasm.data.drop(i32 3)
39 }
40 
41 void throw(void *obj) {
42   return __builtin_wasm_throw(0, obj);
43   // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})
44   // WEBASSEMBLY64: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})
45 }
46 
47 void rethrow_in_catch(void) {
48   return __builtin_wasm_rethrow_in_catch();
49   // WEBASSEMBLY32: call void @llvm.wasm.rethrow.in.catch()
50   // WEBASSEMBLY64: call void @llvm.wasm.rethrow.in.catch()
51 }
52 
53 int atomic_wait_i32(int *addr, int expected, long long timeout) {
54   return __builtin_wasm_atomic_wait_i32(addr, expected, timeout);
55   // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
56   // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
57 }
58 
59 int atomic_wait_i64(long long *addr, long long expected, long long timeout) {
60   return __builtin_wasm_atomic_wait_i64(addr, expected, timeout);
61   // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
62   // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
63 }
64 
65 unsigned int atomic_notify(int *addr, unsigned int count) {
66   return __builtin_wasm_atomic_notify(addr, count);
67   // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
68   // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}})
69 }
70 
71 int trunc_saturate_s_i32_f32(float f) {
72   return __builtin_wasm_trunc_saturate_s_i32_f32(f);
73   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float %f)
74   // WEBASSEMBLY-NEXT: ret
75 }
76 
77 int trunc_saturate_u_i32_f32(float f) {
78   return __builtin_wasm_trunc_saturate_u_i32_f32(f);
79   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float %f)
80   // WEBASSEMBLY-NEXT: ret
81 }
82 
83 int trunc_saturate_s_i32_f64(double f) {
84   return __builtin_wasm_trunc_saturate_s_i32_f64(f);
85   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double %f)
86   // WEBASSEMBLY-NEXT: ret
87 }
88 
89 int trunc_saturate_u_i32_f64(double f) {
90   return __builtin_wasm_trunc_saturate_u_i32_f64(f);
91   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double %f)
92   // WEBASSEMBLY-NEXT: ret
93 }
94 
95 long long trunc_saturate_s_i64_f32(float f) {
96   return __builtin_wasm_trunc_saturate_s_i64_f32(f);
97   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float %f)
98   // WEBASSEMBLY-NEXT: ret
99 }
100 
101 long long trunc_saturate_u_i64_f32(float f) {
102   return __builtin_wasm_trunc_saturate_u_i64_f32(f);
103   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float %f)
104   // WEBASSEMBLY-NEXT: ret
105 }
106 
107 long long trunc_saturate_s_i64_f64(double f) {
108   return __builtin_wasm_trunc_saturate_s_i64_f64(f);
109   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double %f)
110   // WEBASSEMBLY-NEXT: ret
111 }
112 
113 long long trunc_saturate_u_i64_f64(double f) {
114   return __builtin_wasm_trunc_saturate_u_i64_f64(f);
115   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double %f)
116   // WEBASSEMBLY-NEXT: ret
117 }
118 
119 float min_f32(float x, float y) {
120   return __builtin_wasm_min_f32(x, y);
121   // WEBASSEMBLY: call float @llvm.minimum.f32(float %x, float %y)
122   // WEBASSEMBLY-NEXT: ret
123 }
124 
125 float max_f32(float x, float y) {
126   return __builtin_wasm_max_f32(x, y);
127   // WEBASSEMBLY: call float @llvm.maximum.f32(float %x, float %y)
128   // WEBASSEMBLY-NEXT: ret
129 }
130 
131 double min_f64(double x, double y) {
132   return __builtin_wasm_min_f64(x, y);
133   // WEBASSEMBLY: call double @llvm.minimum.f64(double %x, double %y)
134   // WEBASSEMBLY-NEXT: ret
135 }
136 
137 double max_f64(double x, double y) {
138   return __builtin_wasm_max_f64(x, y);
139   // WEBASSEMBLY: call double @llvm.maximum.f64(double %x, double %y)
140   // WEBASSEMBLY-NEXT: ret
141 }
142 
143 
144 int extract_lane_s_i8x16(i8x16 v) {
145   return __builtin_wasm_extract_lane_s_i8x16(v, 13);
146   // MISSING-SIMD: error: '__builtin_wasm_extract_lane_s_i8x16' needs target feature simd128
147   // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13
148   // WEBASSEMBLY-NEXT: sext
149   // WEBASSEMBLY-NEXT: ret
150 }
151 
152 int extract_lane_u_i8x16(i8x16 v) {
153   return __builtin_wasm_extract_lane_u_i8x16(v, 13);
154   // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13
155   // WEBASSEMBLY-NEXT: zext
156   // WEBASSEMBLY-NEXT: ret
157 }
158 
159 int extract_lane_s_i16x8(i16x8 v) {
160   return __builtin_wasm_extract_lane_s_i16x8(v, 7);
161   // WEBASSEMBLY: extractelement <8 x i16> %v, i32 7
162   // WEBASSEMBLY-NEXT: sext
163   // WEBASSEMBLY-NEXT: ret
164 }
165 
166 int extract_lane_u_i16x8(i16x8 v) {
167   return __builtin_wasm_extract_lane_u_i16x8(v, 7);
168   // WEBASSEMBLY: extractelement <8 x i16> %v, i32 7
169   // WEBASSEMBLY-NEXT: zext
170   // WEBASSEMBLY-NEXT: ret
171 }
172 
173 int extract_lane_i32x4(i32x4 v) {
174   return __builtin_wasm_extract_lane_i32x4(v, 3);
175   // WEBASSEMBLY: extractelement <4 x i32> %v, i32 3
176   // WEBASSEMBLY-NEXT: ret
177 }
178 
179 long long extract_lane_i64x2(i64x2 v) {
180   return __builtin_wasm_extract_lane_i64x2(v, 1);
181   // WEBASSEMBLY: extractelement <2 x i64> %v, i32 1
182   // WEBASSEMBLY-NEXT: ret
183 }
184 
185 float extract_lane_f32x4(f32x4 v) {
186   return __builtin_wasm_extract_lane_f32x4(v, 3);
187   // WEBASSEMBLY: extractelement <4 x float> %v, i32 3
188   // WEBASSEMBLY-NEXT: ret
189 }
190 
191 double extract_lane_f64x2(f64x2 v) {
192   return __builtin_wasm_extract_lane_f64x2(v, 1);
193   // WEBASSEMBLY: extractelement <2 x double> %v, i32 1
194   // WEBASSEMBLY-NEXT: ret
195 }
196 
197 i8x16 replace_lane_i8x16(i8x16 v, int x) {
198   return __builtin_wasm_replace_lane_i8x16(v, 13, x);
199   // WEBASSEMBLY: trunc i32 %x to i8
200   // WEBASSEMBLY-NEXT: insertelement <16 x i8> %v, i8 %{{.*}}, i32 13
201   // WEBASSEMBLY-NEXT: ret
202 }
203 
204 i16x8 replace_lane_i16x8(i16x8 v, int x) {
205   return __builtin_wasm_replace_lane_i16x8(v, 7, x);
206   // WEBASSEMBLY: trunc i32 %x to i16
207   // WEBASSEMBLY-NEXT: insertelement <8 x i16> %v, i16 %{{.*}}, i32 7
208   // WEBASSEMBLY-NEXT: ret
209 }
210 
211 i32x4 replace_lane_i32x4(i32x4 v, int x) {
212   return __builtin_wasm_replace_lane_i32x4(v, 3, x);
213   // WEBASSEMBLY: insertelement <4 x i32> %v, i32 %x, i32 3
214   // WEBASSEMBLY-NEXT: ret
215 }
216 
217 i64x2 replace_lane_i64x2(i64x2 v, long long x) {
218   return __builtin_wasm_replace_lane_i64x2(v, 1, x);
219   // WEBASSEMBLY: insertelement <2 x i64> %v, i64 %x, i32 1
220   // WEBASSEMBLY-NEXT: ret
221 }
222 
223 f32x4 replace_lane_f32x4(f32x4 v, float x) {
224   return __builtin_wasm_replace_lane_f32x4(v, 3, x);
225   // WEBASSEMBLY: insertelement <4 x float> %v, float %x, i32 3
226   // WEBASSEMBLY-NEXT: ret
227 }
228 
229 f64x2 replace_lane_f64x2(f64x2 v, double x) {
230   return __builtin_wasm_replace_lane_f64x2(v, 1, x);
231   // WEBASSEMBLY: insertelement <2 x double> %v, double %x, i32 1
232   // WEBASSEMBLY-NEXT: ret
233 }
234 
235 i8x16 add_saturate_s_i8x16(i8x16 x, i8x16 y) {
236   return __builtin_wasm_add_saturate_s_i8x16(x, y);
237   // WEBASSEMBLY: call <16 x i8> @llvm.sadd.sat.v16i8(
238   // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
239   // WEBASSEMBLY-NEXT: ret
240 }
241 
242 i8x16 add_saturate_u_i8x16(i8x16 x, i8x16 y) {
243   return __builtin_wasm_add_saturate_u_i8x16(x, y);
244   // WEBASSEMBLY: call <16 x i8> @llvm.uadd.sat.v16i8(
245   // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
246   // WEBASSEMBLY-NEXT: ret
247 }
248 
249 i16x8 add_saturate_s_i16x8(i16x8 x, i16x8 y) {
250   return __builtin_wasm_add_saturate_s_i16x8(x, y);
251   // WEBASSEMBLY: call <8 x i16> @llvm.sadd.sat.v8i16(
252   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
253   // WEBASSEMBLY-NEXT: ret
254 }
255 
256 i16x8 add_saturate_u_i16x8(i16x8 x, i16x8 y) {
257   return __builtin_wasm_add_saturate_u_i16x8(x, y);
258   // WEBASSEMBLY: call <8 x i16> @llvm.uadd.sat.v8i16(
259   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
260   // WEBASSEMBLY-NEXT: ret
261 }
262 
263 i8x16 sub_saturate_s_i8x16(i8x16 x, i8x16 y) {
264   return __builtin_wasm_sub_saturate_s_i8x16(x, y);
265   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.signed.v16i8(
266   // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
267   // WEBASSEMBLY-NEXT: ret
268 }
269 
270 i8x16 sub_saturate_u_i8x16(i8x16 x, i8x16 y) {
271   return __builtin_wasm_sub_saturate_u_i8x16(x, y);
272   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.sub.saturate.unsigned.v16i8(
273   // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
274   // WEBASSEMBLY-NEXT: ret
275 }
276 
277 i16x8 sub_saturate_s_i16x8(i16x8 x, i16x8 y) {
278   return __builtin_wasm_sub_saturate_s_i16x8(x, y);
279   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.signed.v8i16(
280   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
281   // WEBASSEMBLY-NEXT: ret
282 }
283 
284 i16x8 sub_saturate_u_i16x8(i16x8 x, i16x8 y) {
285   return __builtin_wasm_sub_saturate_u_i16x8(x, y);
286   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.sub.saturate.unsigned.v8i16(
287   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
288   // WEBASSEMBLY-NEXT: ret
289 }
290 
291 i32x4 bitselect(i32x4 x, i32x4 y, i32x4 c) {
292   return __builtin_wasm_bitselect(x, y, c);
293   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.bitselect.v4i32(
294   // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y, <4 x i32> %c)
295   // WEBASSEMBLY-NEXT: ret
296 }
297 
298 int any_true_i8x16(i8x16 x) {
299   return __builtin_wasm_any_true_i8x16(x);
300   // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
301   // WEBASSEMBLY: ret
302 }
303 
304 int any_true_i16x8(i16x8 x) {
305   return __builtin_wasm_any_true_i16x8(x);
306   // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x)
307   // WEBASSEMBLY: ret
308 }
309 
310 int any_true_i32x4(i32x4 x) {
311   return __builtin_wasm_any_true_i32x4(x);
312   // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x)
313   // WEBASSEMBLY: ret
314 }
315 
316 int any_true_i64x2(i64x2 x) {
317   return __builtin_wasm_any_true_i64x2(x);
318   // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x)
319   // WEBASSEMBLY: ret
320 }
321 
322 int all_true_i8x16(i8x16 x) {
323   return __builtin_wasm_all_true_i8x16(x);
324   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
325   // WEBASSEMBLY: ret
326 }
327 
328 int all_true_i16x8(i16x8 x) {
329   return __builtin_wasm_all_true_i16x8(x);
330   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
331   // WEBASSEMBLY: ret
332 }
333 
334 int all_true_i32x4(i32x4 x) {
335   return __builtin_wasm_all_true_i32x4(x);
336   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
337   // WEBASSEMBLY: ret
338 }
339 
340 int all_true_i64x2(i64x2 x) {
341   return __builtin_wasm_all_true_i64x2(x);
342   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
343   // WEBASSEMBLY: ret
344 }
345 
346 f32x4 abs_f32x4(f32x4 x) {
347   return __builtin_wasm_abs_f32x4(x);
348   // WEBASSEMBLY: call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
349   // WEBASSEMBLY: ret
350 }
351 
352 f64x2 abs_f64x2(f64x2 x) {
353   return __builtin_wasm_abs_f64x2(x);
354   // WEBASSEMBLY: call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
355   // WEBASSEMBLY: ret
356 }
357 
358 f32x4 min_f32x4(f32x4 x, f32x4 y) {
359   return __builtin_wasm_min_f32x4(x, y);
360   // WEBASSEMBLY: call <4 x float> @llvm.minimum.v4f32(
361   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
362   // WEBASSEMBLY-NEXT: ret
363 }
364 
365 f32x4 max_f32x4(f32x4 x, f32x4 y) {
366   return __builtin_wasm_max_f32x4(x, y);
367   // WEBASSEMBLY: call <4 x float> @llvm.maximum.v4f32(
368   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
369   // WEBASSEMBLY-NEXT: ret
370 }
371 
372 f64x2 min_f64x2(f64x2 x, f64x2 y) {
373   return __builtin_wasm_min_f64x2(x, y);
374   // WEBASSEMBLY: call <2 x double> @llvm.minimum.v2f64(
375   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
376   // WEBASSEMBLY-NEXT: ret
377 }
378 
379 f64x2 max_f64x2(f64x2 x, f64x2 y) {
380   return __builtin_wasm_max_f64x2(x, y);
381   // WEBASSEMBLY: call <2 x double> @llvm.maximum.v2f64(
382   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
383   // WEBASSEMBLY-NEXT: ret
384 }
385 
386 f32x4 sqrt_f32x4(f32x4 x) {
387   return __builtin_wasm_sqrt_f32x4(x);
388   // WEBASSEMBLY: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
389   // WEBASSEMBLY: ret
390 }
391 
392 f64x2 sqrt_f64x2(f64x2 x) {
393   return __builtin_wasm_sqrt_f64x2(x);
394   // WEBASSEMBLY: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
395   // WEBASSEMBLY: ret
396 }
397 
398 i32x4 trunc_saturate_s_i32x4_f32x4(f32x4 f) {
399   return __builtin_wasm_trunc_saturate_s_i32x4_f32x4(f);
400   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %f)
401   // WEBASSEMBLY-NEXT: ret
402 }
403 
404 i32x4 trunc_saturate_u_i32x4_f32x4(f32x4 f) {
405   return __builtin_wasm_trunc_saturate_u_i32x4_f32x4(f);
406   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32(<4 x float> %f)
407   // WEBASSEMBLY-NEXT: ret
408 }
409 
410 i64x2 trunc_saturate_s_i64x2_f64x2(f64x2 f) {
411   return __builtin_wasm_trunc_saturate_s_i64x2_f64x2(f);
412   // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double> %f)
413   // WEBASSEMBLY-NEXT: ret
414 }
415 
416 i64x2 trunc_saturate_u_i64x2_f64x2(f64x2 f) {
417   return __builtin_wasm_trunc_saturate_u_i64x2_f64x2(f);
418   // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double> %f)
419   // WEBASSEMBLY-NEXT: ret
420 }
421