Clang Project

clang_source_code/test/CodeGen/builtins-wasm.c
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
6typedef char i8x16 __attribute((vector_size(16)));
7typedef short i16x8 __attribute((vector_size(16)));
8typedef int i32x4 __attribute((vector_size(16)));
9typedef long long i64x2 __attribute((vector_size(16)));
10typedef unsigned char u8x16 __attribute((vector_size(16)));
11typedef unsigned short u16x8 __attribute((vector_size(16)));
12typedef unsigned int u32x4 __attribute((vector_size(16)));
13typedef unsigned long long u64x2 __attribute((vector_size(16)));
14typedef float f32x4 __attribute((vector_size(16)));
15typedef 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
29void 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
35void 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
41void 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
47void 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
53int 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
59int 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
65unsigned 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
71int 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
77int 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
83int 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
89int 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
95long 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
101long 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
107long 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
113long 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
119float 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
125float 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
131double 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
137double 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
144int 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
152int 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
159int 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
166int 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
173int 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
179long 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
185float 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
191double 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
197i8x16 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
204i16x8 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
211i32x4 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
217i64x2 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
223f32x4 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
229f64x2 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
235i8x16 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
242i8x16 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
249i16x8 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
256i16x8 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
263i8x16 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
270i8x16 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
277i16x8 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
284i16x8 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
291i32x4 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
298int 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
304int 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
310int 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
316int 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
322int 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
328int 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
334int 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
340int 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
346f32x4 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
352f64x2 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
358f32x4 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
365f32x4 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
372f64x2 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
379f64x2 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
386f32x4 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
392f64x2 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
398i32x4 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
404i32x4 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
410i64x2 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
416i64x2 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