xref: /llvm-project/clang/test/CodeGen/builtins-wasm.c (revision ea58410d0fd75c9dc6d395bba15e939ed7c35cb1)
1 // RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -target-feature +fp16 -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
2 // RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +reference-types -target-feature +simd128 -target-feature +relaxed-simd -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -target-feature +fp16 -flax-vector-conversions=none -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
3 // RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +reference-types -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -target-feature +atomics -flax-vector-conversions=none -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
4 
5 // SIMD convenience types
6 typedef signed 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 __fp16 f16x8 __attribute((vector_size(16)));
15 typedef float f32x4 __attribute((vector_size(16)));
16 typedef double f64x2 __attribute((vector_size(16)));
17 
18 __SIZE_TYPE__ memory_size(void) {
19   return __builtin_wasm_memory_size(0);
20   // WEBASSEMBLY32: call {{i.*}} @llvm.wasm.memory.size.i32(i32 0)
21   // WEBASSEMBLY64: call {{i.*}} @llvm.wasm.memory.size.i64(i32 0)
22 }
23 
24 __SIZE_TYPE__ memory_grow(__SIZE_TYPE__ delta) {
25   return __builtin_wasm_memory_grow(0, delta);
26   // WEBASSEMBLY32: call i32 @llvm.wasm.memory.grow.i32(i32 0, i32 %{{.*}})
27   // WEBASSEMBLY64: call i64 @llvm.wasm.memory.grow.i64(i32 0, i64 %{{.*}})
28 }
29 
30 __SIZE_TYPE__ tls_size(void) {
31   return __builtin_wasm_tls_size();
32   // WEBASSEMBLY32: call i32 @llvm.wasm.tls.size.i32()
33   // WEBASSEMBLY64: call i64 @llvm.wasm.tls.size.i64()
34 }
35 
36 __SIZE_TYPE__ tls_align(void) {
37   return __builtin_wasm_tls_align();
38   // WEBASSEMBLY32: call i32 @llvm.wasm.tls.align.i32()
39   // WEBASSEMBLY64: call i64 @llvm.wasm.tls.align.i64()
40 }
41 
42 void *tls_base(void) {
43   return __builtin_wasm_tls_base();
44   // WEBASSEMBLY: call ptr @llvm.wasm.tls.base()
45 }
46 
47 void throw(void *obj) {
48   return __builtin_wasm_throw(0, obj);
49   // WEBASSEMBLY: call void @llvm.wasm.throw(i32 0, ptr %{{.*}})
50 }
51 
52 void rethrow(void) {
53   return __builtin_wasm_rethrow();
54   // WEBASSEMBLY32: call void @llvm.wasm.rethrow()
55   // WEBASSEMBLY64: call void @llvm.wasm.rethrow()
56 }
57 
58 int memory_atomic_wait32(int *addr, int expected, long long timeout) {
59   return __builtin_wasm_memory_atomic_wait32(addr, expected, timeout);
60   // WEBASSEMBLY: call i32 @llvm.wasm.memory.atomic.wait32(ptr %{{.*}}, i32 %{{.*}}, i64 %{{.*}})
61 }
62 
63 int memory_atomic_wait64(long long *addr, long long expected, long long timeout) {
64   return __builtin_wasm_memory_atomic_wait64(addr, expected, timeout);
65   // WEBASSEMBLY: call i32 @llvm.wasm.memory.atomic.wait64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
66 }
67 
68 unsigned int memory_atomic_notify(int *addr, unsigned int count) {
69   return __builtin_wasm_memory_atomic_notify(addr, count);
70   // WEBASSEMBLY: call i32 @llvm.wasm.memory.atomic.notify(ptr %{{.*}}, i32 %{{.*}})
71 }
72 
73 int trunc_s_i32_f32(float f) {
74   return __builtin_wasm_trunc_s_i32_f32(f);
75   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.signed.i32.f32(float %f)
76   // WEBASSEMBLY-NEXT: ret
77 }
78 
79 int trunc_u_i32_f32(float f) {
80   return __builtin_wasm_trunc_u_i32_f32(f);
81   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.unsigned.i32.f32(float %f)
82   // WEBASSEMBLY-NEXT: ret
83 }
84 
85 int trunc_s_i32_f64(double f) {
86   return __builtin_wasm_trunc_s_i32_f64(f);
87   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.signed.i32.f64(double %f)
88   // WEBASSEMBLY-NEXT: ret
89 }
90 
91 int trunc_u_i32_f64(double f) {
92   return __builtin_wasm_trunc_u_i32_f64(f);
93   // WEBASSEMBLY: call i32 @llvm.wasm.trunc.unsigned.i32.f64(double %f)
94   // WEBASSEMBLY-NEXT: ret
95 }
96 
97 long long trunc_s_i64_f32(float f) {
98   return __builtin_wasm_trunc_s_i64_f32(f);
99   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.signed.i64.f32(float %f)
100   // WEBASSEMBLY-NEXT: ret
101 }
102 
103 long long trunc_u_i64_f32(float f) {
104   return __builtin_wasm_trunc_u_i64_f32(f);
105   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.unsigned.i64.f32(float %f)
106   // WEBASSEMBLY-NEXT: ret
107 }
108 
109 long long trunc_s_i64_f64(double f) {
110   return __builtin_wasm_trunc_s_i64_f64(f);
111   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.signed.i64.f64(double %f)
112   // WEBASSEMBLY-NEXT: ret
113 }
114 
115 long long trunc_u_i64_f64(double f) {
116   return __builtin_wasm_trunc_u_i64_f64(f);
117   // WEBASSEMBLY: call i64 @llvm.wasm.trunc.unsigned.i64.f64(double %f)
118   // WEBASSEMBLY-NEXT: ret
119 }
120 
121 int trunc_saturate_s_i32_f32(float f) {
122   return __builtin_wasm_trunc_saturate_s_i32_f32(f);
123   // WEBASSEMBLY: call i32 @llvm.fptosi.sat.i32.f32(float %f)
124   // WEBASSEMBLY-NEXT: ret
125 }
126 
127 int trunc_saturate_u_i32_f32(float f) {
128   return __builtin_wasm_trunc_saturate_u_i32_f32(f);
129   // WEBASSEMBLY: call i32 @llvm.fptoui.sat.i32.f32(float %f)
130   // WEBASSEMBLY-NEXT: ret
131 }
132 
133 int trunc_saturate_s_i32_f64(double f) {
134   return __builtin_wasm_trunc_saturate_s_i32_f64(f);
135   // WEBASSEMBLY: call i32 @llvm.fptosi.sat.i32.f64(double %f)
136   // WEBASSEMBLY-NEXT: ret
137 }
138 
139 int trunc_saturate_u_i32_f64(double f) {
140   return __builtin_wasm_trunc_saturate_u_i32_f64(f);
141   // WEBASSEMBLY: call i32 @llvm.fptoui.sat.i32.f64(double %f)
142   // WEBASSEMBLY-NEXT: ret
143 }
144 
145 long long trunc_saturate_s_i64_f32(float f) {
146   return __builtin_wasm_trunc_saturate_s_i64_f32(f);
147   // WEBASSEMBLY: call i64 @llvm.fptosi.sat.i64.f32(float %f)
148   // WEBASSEMBLY-NEXT: ret
149 }
150 
151 long long trunc_saturate_u_i64_f32(float f) {
152   return __builtin_wasm_trunc_saturate_u_i64_f32(f);
153   // WEBASSEMBLY: call i64 @llvm.fptoui.sat.i64.f32(float %f)
154   // WEBASSEMBLY-NEXT: ret
155 }
156 
157 long long trunc_saturate_s_i64_f64(double f) {
158   return __builtin_wasm_trunc_saturate_s_i64_f64(f);
159   // WEBASSEMBLY: call i64 @llvm.fptosi.sat.i64.f64(double %f)
160   // WEBASSEMBLY-NEXT: ret
161 }
162 
163 long long trunc_saturate_u_i64_f64(double f) {
164   return __builtin_wasm_trunc_saturate_u_i64_f64(f);
165   // WEBASSEMBLY: call i64 @llvm.fptoui.sat.i64.f64(double %f)
166   // WEBASSEMBLY-NEXT: ret
167 }
168 
169 float min_f32(float x, float y) {
170   return __builtin_wasm_min_f32(x, y);
171   // WEBASSEMBLY: call float @llvm.minimum.f32(float %x, float %y)
172   // WEBASSEMBLY-NEXT: ret
173 }
174 
175 float max_f32(float x, float y) {
176   return __builtin_wasm_max_f32(x, y);
177   // WEBASSEMBLY: call float @llvm.maximum.f32(float %x, float %y)
178   // WEBASSEMBLY-NEXT: ret
179 }
180 
181 double min_f64(double x, double y) {
182   return __builtin_wasm_min_f64(x, y);
183   // WEBASSEMBLY: call double @llvm.minimum.f64(double %x, double %y)
184   // WEBASSEMBLY-NEXT: ret
185 }
186 
187 double max_f64(double x, double y) {
188   return __builtin_wasm_max_f64(x, y);
189   // WEBASSEMBLY: call double @llvm.maximum.f64(double %x, double %y)
190   // WEBASSEMBLY-NEXT: ret
191 }
192 
193 i8x16 abs_i8x16(i8x16 v) {
194   return __builtin_wasm_abs_i8x16(v);
195   // MISSING-SIMD: error: '__builtin_wasm_abs_i8x16' needs target feature simd128
196   // WEBASSEMBLY: call <16 x i8> @llvm.abs.v16i8(<16 x i8> %v, i1 false)
197   // WEBASSEMBLY-NEXT: ret
198 }
199 
200 i16x8 abs_i16x8(i16x8 v) {
201   return __builtin_wasm_abs_i16x8(v);
202   // WEBASSEMBLY: call <8 x i16> @llvm.abs.v8i16(<8 x i16> %v, i1 false)
203   // WEBASSEMBLY-NEXT: ret
204 }
205 
206 i32x4 abs_i32x4(i32x4 v) {
207   return __builtin_wasm_abs_i32x4(v);
208   // WEBASSEMBLY: call <4 x i32> @llvm.abs.v4i32(<4 x i32> %v, i1 false)
209   // WEBASSEMBLY-NEXT: ret
210 }
211 
212 i64x2 abs_i64x2(i64x2 v) {
213   return __builtin_wasm_abs_i64x2(v);
214   // WEBASSEMBLY: call <2 x i64> @llvm.abs.v2i64(<2 x i64> %v, i1 false)
215   // WEBASSEMBLY-NEXT: ret
216 }
217 
218 u8x16 avgr_u_i8x16(u8x16 x, u8x16 y) {
219   return __builtin_wasm_avgr_u_i8x16(x, y);
220   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.avgr.unsigned.v16i8(
221   // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
222   // WEBASSEMBLY-NEXT: ret
223 }
224 
225 u16x8 avgr_u_i16x8(u16x8 x, u16x8 y) {
226   return __builtin_wasm_avgr_u_i16x8(x, y);
227   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.avgr.unsigned.v8i16(
228   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
229   // WEBASSEMBLY-NEXT: ret
230 }
231 
232 i16x8 q15mulr_sat_s_i16x8(i16x8 x, i16x8 y) {
233   return __builtin_wasm_q15mulr_sat_s_i16x8(x, y);
234   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.q15mulr.sat.signed(
235   // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
236   // WEBASSEMBLY-NEXT: ret
237 }
238 
239 i16x8 extadd_pairwise_i8x16_s_i16x8(i8x16 v) {
240   return __builtin_wasm_extadd_pairwise_i8x16_s_i16x8(v);
241   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.extadd.pairwise.signed.v8i16(
242   // WEBASSEMBLY-SAME: <16 x i8> %v)
243   // WEBASSEMBLY-NEXT: ret
244 }
245 
246 u16x8 extadd_pairwise_i8x16_u_i16x8(u8x16 v) {
247   return __builtin_wasm_extadd_pairwise_i8x16_u_i16x8(v);
248   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.extadd.pairwise.unsigned.v8i16(
249   // WEBASSEMBLY-SAME: <16 x i8> %v)
250   // WEBASSEMBLY-NEXT: ret
251 }
252 
253 i32x4 extadd_pairwise_i16x8_s_i32x4(i16x8 v) {
254   return __builtin_wasm_extadd_pairwise_i16x8_s_i32x4(v);
255   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.extadd.pairwise.signed.v4i32(
256   // WEBASSEMBLY-SAME: <8 x i16> %v)
257   // WEBASSEMBLY-NEXT: ret
258 }
259 
260 u32x4 extadd_pairwise_i16x8_u_i32x4(u16x8 v) {
261   return __builtin_wasm_extadd_pairwise_i16x8_u_i32x4(v);
262   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.extadd.pairwise.unsigned.v4i32(
263   // WEBASSEMBLY-SAME: <8 x i16> %v)
264   // WEBASSEMBLY-NEXT: ret
265 }
266 
267 i32x4 dot_i16x8_s(i16x8 x, i16x8 y) {
268   return __builtin_wasm_dot_s_i32x4_i16x8(x, y);
269   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.dot(<8 x i16> %x, <8 x i16> %y)
270   // WEBASSEMBLY-NEXT: ret
271 }
272 
273 i32x4 bitselect(i32x4 x, i32x4 y, i32x4 c) {
274   return __builtin_wasm_bitselect(x, y, c);
275   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.bitselect.v4i32(
276   // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y, <4 x i32> %c)
277   // WEBASSEMBLY-NEXT: ret
278 }
279 
280 int any_true_v128(i8x16 x) {
281   return __builtin_wasm_any_true_v128(x);
282   // WEBASSEMBLY: call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
283   // WEBASSEMBLY: ret
284 }
285 
286 int all_true_i8x16(i8x16 x) {
287   return __builtin_wasm_all_true_i8x16(x);
288   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
289   // WEBASSEMBLY: ret
290 }
291 
292 int all_true_i16x8(i16x8 x) {
293   return __builtin_wasm_all_true_i16x8(x);
294   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
295   // WEBASSEMBLY: ret
296 }
297 
298 int all_true_i32x4(i32x4 x) {
299   return __builtin_wasm_all_true_i32x4(x);
300   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
301   // WEBASSEMBLY: ret
302 }
303 
304 int all_true_i64x2(i64x2 x) {
305   return __builtin_wasm_all_true_i64x2(x);
306   // WEBASSEMBLY: call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
307   // WEBASSEMBLY: ret
308 }
309 
310 int bitmask_i8x16(i8x16 x) {
311   return __builtin_wasm_bitmask_i8x16(x);
312   // WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v16i8(<16 x i8> %x)
313   // WEBASSEMBLY: ret
314 }
315 
316 int bitmask_i16x8(i16x8 x) {
317   return __builtin_wasm_bitmask_i16x8(x);
318   // WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v8i16(<8 x i16> %x)
319   // WEBASSEMBLY: ret
320 }
321 
322 int bitmask_i32x4(i32x4 x) {
323   return __builtin_wasm_bitmask_i32x4(x);
324   // WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v4i32(<4 x i32> %x)
325   // WEBASSEMBLY: ret
326 }
327 
328 int bitmask_i64x2(i64x2 x) {
329   return __builtin_wasm_bitmask_i64x2(x);
330   // WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v2i64(<2 x i64> %x)
331   // WEBASSEMBLY: ret
332 }
333 
334 f32x4 abs_f32x4(f32x4 x) {
335   return __builtin_wasm_abs_f32x4(x);
336   // WEBASSEMBLY: call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
337   // WEBASSEMBLY: ret
338 }
339 
340 f64x2 abs_f64x2(f64x2 x) {
341   return __builtin_wasm_abs_f64x2(x);
342   // WEBASSEMBLY: call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)
343   // WEBASSEMBLY: ret
344 }
345 
346 f32x4 min_f32x4(f32x4 x, f32x4 y) {
347   return __builtin_wasm_min_f32x4(x, y);
348   // WEBASSEMBLY: call <4 x float> @llvm.minimum.v4f32(
349   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
350   // WEBASSEMBLY-NEXT: ret
351 }
352 
353 f32x4 max_f32x4(f32x4 x, f32x4 y) {
354   return __builtin_wasm_max_f32x4(x, y);
355   // WEBASSEMBLY: call <4 x float> @llvm.maximum.v4f32(
356   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
357   // WEBASSEMBLY-NEXT: ret
358 }
359 
360 f32x4 pmin_f32x4(f32x4 x, f32x4 y) {
361   return __builtin_wasm_pmin_f32x4(x, y);
362   // WEBASSEMBLY: call <4 x float> @llvm.wasm.pmin.v4f32(
363   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
364   // WEBASSEMBLY-NEXT: ret
365 }
366 
367 f32x4 pmax_f32x4(f32x4 x, f32x4 y) {
368   return __builtin_wasm_pmax_f32x4(x, y);
369   // WEBASSEMBLY: call <4 x float> @llvm.wasm.pmax.v4f32(
370   // WEBASSEMBLY-SAME: <4 x float> %x, <4 x float> %y)
371   // WEBASSEMBLY-NEXT: ret
372 }
373 
374 f64x2 min_f64x2(f64x2 x, f64x2 y) {
375   return __builtin_wasm_min_f64x2(x, y);
376   // WEBASSEMBLY: call <2 x double> @llvm.minimum.v2f64(
377   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
378   // WEBASSEMBLY-NEXT: ret
379 }
380 
381 f64x2 max_f64x2(f64x2 x, f64x2 y) {
382   return __builtin_wasm_max_f64x2(x, y);
383   // WEBASSEMBLY: call <2 x double> @llvm.maximum.v2f64(
384   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
385   // WEBASSEMBLY-NEXT: ret
386 }
387 
388 f64x2 pmin_f64x2(f64x2 x, f64x2 y) {
389   return __builtin_wasm_pmin_f64x2(x, y);
390   // WEBASSEMBLY: call <2 x double> @llvm.wasm.pmin.v2f64(
391   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
392   // WEBASSEMBLY-NEXT: ret
393 }
394 
395 f64x2 pmax_f64x2(f64x2 x, f64x2 y) {
396   return __builtin_wasm_pmax_f64x2(x, y);
397   // WEBASSEMBLY: call <2 x double> @llvm.wasm.pmax.v2f64(
398   // WEBASSEMBLY-SAME: <2 x double> %x, <2 x double> %y)
399   // WEBASSEMBLY-NEXT: ret
400 }
401 
402 f32x4 ceil_f32x4(f32x4 x) {
403   return __builtin_wasm_ceil_f32x4(x);
404   // WEBASSEMBLY: call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
405   // WEBASSEMBLY: ret
406 }
407 
408 f32x4 floor_f32x4(f32x4 x) {
409   return __builtin_wasm_floor_f32x4(x);
410   // WEBASSEMBLY: call <4 x float> @llvm.floor.v4f32(<4 x float> %x)
411   // WEBASSEMBLY: ret
412 }
413 
414 f32x4 trunc_f32x4(f32x4 x) {
415   return __builtin_wasm_trunc_f32x4(x);
416   // WEBASSEMBLY: call <4 x float> @llvm.trunc.v4f32(<4 x float> %x)
417   // WEBASSEMBLY: ret
418 }
419 
420 f32x4 nearest_f32x4(f32x4 x) {
421   return __builtin_wasm_nearest_f32x4(x);
422   // WEBASSEMBLY: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %x)
423   // WEBASSEMBLY: ret
424 }
425 
426 f64x2 ceil_f64x2(f64x2 x) {
427   return __builtin_wasm_ceil_f64x2(x);
428   // WEBASSEMBLY: call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
429   // WEBASSEMBLY: ret
430 }
431 
432 f64x2 floor_f64x2(f64x2 x) {
433   return __builtin_wasm_floor_f64x2(x);
434   // WEBASSEMBLY: call <2 x double> @llvm.floor.v2f64(<2 x double> %x)
435   // WEBASSEMBLY: ret
436 }
437 
438 f64x2 trunc_f64x2(f64x2 x) {
439   return __builtin_wasm_trunc_f64x2(x);
440   // WEBASSEMBLY: call <2 x double> @llvm.trunc.v2f64(<2 x double> %x)
441   // WEBASSEMBLY: ret
442 }
443 
444 f64x2 nearest_f64x2(f64x2 x) {
445   return __builtin_wasm_nearest_f64x2(x);
446   // WEBASSEMBLY: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %x)
447   // WEBASSEMBLY: ret
448 }
449 
450 f32x4 sqrt_f32x4(f32x4 x) {
451   return __builtin_wasm_sqrt_f32x4(x);
452   // WEBASSEMBLY: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
453   // WEBASSEMBLY: ret
454 }
455 
456 f64x2 sqrt_f64x2(f64x2 x) {
457   return __builtin_wasm_sqrt_f64x2(x);
458   // WEBASSEMBLY: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x)
459   // WEBASSEMBLY: ret
460 }
461 
462 i32x4 trunc_saturate_s_i32x4_f32x4(f32x4 f) {
463   return __builtin_wasm_trunc_saturate_s_i32x4_f32x4(f);
464   // WEBASSEMBLY: call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> %f)
465   // WEBASSEMBLY-NEXT: ret
466 }
467 
468 i32x4 trunc_saturate_u_i32x4_f32x4(f32x4 f) {
469   return __builtin_wasm_trunc_saturate_u_i32x4_f32x4(f);
470   // WEBASSEMBLY: call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
471   // WEBASSEMBLY-NEXT: ret
472 }
473 
474 i8x16 narrow_s_i8x16_i16x8(i16x8 low, i16x8 high) {
475   return __builtin_wasm_narrow_s_i8x16_i16x8(low, high);
476   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.narrow.signed.v16i8.v8i16(
477   // WEBASSEMBLY-SAME: <8 x i16> %low, <8 x i16> %high)
478   // WEBASSEMBLY: ret
479 }
480 
481 u8x16 narrow_u_i8x16_i16x8(i16x8 low, i16x8 high) {
482   return __builtin_wasm_narrow_u_i8x16_i16x8(low, high);
483   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.narrow.unsigned.v16i8.v8i16(
484   // WEBASSEMBLY-SAME: <8 x i16> %low, <8 x i16> %high)
485   // WEBASSEMBLY: ret
486 }
487 
488 i16x8 narrow_s_i16x8_i32x4(i32x4 low, i32x4 high) {
489   return __builtin_wasm_narrow_s_i16x8_i32x4(low, high);
490   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.narrow.signed.v8i16.v4i32(
491   // WEBASSEMBLY-SAME: <4 x i32> %low, <4 x i32> %high)
492   // WEBASSEMBLY: ret
493 }
494 
495 u16x8 narrow_u_i16x8_i32x4(i32x4 low, i32x4 high) {
496   return __builtin_wasm_narrow_u_i16x8_i32x4(low, high);
497   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.narrow.unsigned.v8i16.v4i32(
498   // WEBASSEMBLY-SAME: <4 x i32> %low, <4 x i32> %high)
499   // WEBASSEMBLY: ret
500 }
501 
502 i32x4 trunc_sat_s_zero_f64x2_i32x4(f64x2 x) {
503   return __builtin_wasm_trunc_sat_s_zero_f64x2_i32x4(x);
504   // WEBASSEMBLY: %0 = tail call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> %x)
505   // WEBASSEMBLY: %1 = shufflevector <2 x i32> %0, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
506   // WEBASSEMBLY: ret <4 x i32> %1
507 }
508 
509 u32x4 trunc_sat_u_zero_f64x2_i32x4(f64x2 x) {
510   return __builtin_wasm_trunc_sat_u_zero_f64x2_i32x4(x);
511   // WEBASSEMBLY: %0 = tail call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> %x)
512   // WEBASSEMBLY: %1 = shufflevector <2 x i32> %0, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
513   // WEBASSEMBLY: ret <4 x i32> %1
514 }
515 
516 i8x16 swizzle_i8x16(i8x16 x, i8x16 y) {
517   return __builtin_wasm_swizzle_i8x16(x, y);
518   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %x, <16 x i8> %y)
519 }
520 
521 i8x16 shuffle(i8x16 x, i8x16 y) {
522   return __builtin_wasm_shuffle_i8x16(x, y, 0, 1, 2, 3, 4, 5, 6, 7,
523                                       8, 9, 10, 11, 12, 13, 14, 15);
524   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.shuffle(<16 x i8> %x, <16 x i8> %y,
525   // WEBASSEMBLY-SAME: i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
526   // WEBASSEMBLY-SAME: i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14,
527   // WEBASSEMBLY-SAME: i32 15
528   // WEBASSEMBLY-NEXT: ret
529 }
530 
531 f32x4 madd_f32x4(f32x4 a, f32x4 b, f32x4 c) {
532   return __builtin_wasm_relaxed_madd_f32x4(a, b, c);
533   // WEBASSEMBLY: call <4 x float> @llvm.wasm.relaxed.madd.v4f32(
534   // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c)
535   // WEBASSEMBLY-NEXT: ret
536 }
537 
538 f32x4 nmadd_f32x4(f32x4 a, f32x4 b, f32x4 c) {
539   return __builtin_wasm_relaxed_nmadd_f32x4(a, b, c);
540   // WEBASSEMBLY: call <4 x float> @llvm.wasm.relaxed.nmadd.v4f32(
541   // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c)
542   // WEBASSEMBLY-NEXT: ret
543 }
544 
545 f64x2 madd_f64x2(f64x2 a, f64x2 b, f64x2 c) {
546   return __builtin_wasm_relaxed_madd_f64x2(a, b, c);
547   // WEBASSEMBLY: call <2 x double> @llvm.wasm.relaxed.madd.v2f64(
548   // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c)
549   // WEBASSEMBLY-NEXT: ret
550 }
551 
552 f64x2 nmadd_f64x2(f64x2 a, f64x2 b, f64x2 c) {
553   return __builtin_wasm_relaxed_nmadd_f64x2(a, b, c);
554   // WEBASSEMBLY: call <2 x double> @llvm.wasm.relaxed.nmadd.v2f64(
555   // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c)
556   // WEBASSEMBLY-NEXT: ret
557 }
558 
559 f16x8 madd_f16x8(f16x8 a, f16x8 b, f16x8 c) {
560   return __builtin_wasm_relaxed_madd_f16x8(a, b, c);
561   // WEBASSEMBLY: call <8 x half> @llvm.wasm.relaxed.madd.v8f16(
562   // WEBASSEMBLY-SAME: <8 x half> %a, <8 x half> %b, <8 x half> %c)
563   // WEBASSEMBLY-NEXT: ret
564 }
565 
566 f16x8 nmadd_f16x8(f16x8 a, f16x8 b, f16x8 c) {
567   return __builtin_wasm_relaxed_nmadd_f16x8(a, b, c);
568   // WEBASSEMBLY: call <8 x half> @llvm.wasm.relaxed.nmadd.v8f16(
569   // WEBASSEMBLY-SAME: <8 x half> %a, <8 x half> %b, <8 x half> %c)
570   // WEBASSEMBLY-NEXT: ret
571 }
572 
573 i8x16 laneselect_i8x16(i8x16 a, i8x16 b, i8x16 c) {
574   return __builtin_wasm_relaxed_laneselect_i8x16(a, b, c);
575   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.relaxed.laneselect.v16i8(
576   // WEBASSEMBLY-SAME: <16 x i8> %a, <16 x i8> %b, <16 x i8> %c)
577   // WEBASSEMBLY-NEXT: ret
578 }
579 
580 i16x8 laneselect_i16x8(i16x8 a, i16x8 b, i16x8 c) {
581   return __builtin_wasm_relaxed_laneselect_i16x8(a, b, c);
582   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.relaxed.laneselect.v8i16(
583   // WEBASSEMBLY-SAME: <8 x i16> %a, <8 x i16> %b, <8 x i16> %c)
584   // WEBASSEMBLY-NEXT: ret
585 }
586 
587 i32x4 laneselect_i32x4(i32x4 a, i32x4 b, i32x4 c) {
588   return __builtin_wasm_relaxed_laneselect_i32x4(a, b, c);
589   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.laneselect.v4i32(
590   // WEBASSEMBLY-SAME: <4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
591   // WEBASSEMBLY-NEXT: ret
592 }
593 
594 i64x2 laneselect_i64x2(i64x2 a, i64x2 b, i64x2 c) {
595   return __builtin_wasm_relaxed_laneselect_i64x2(a, b, c);
596   // WEBASSEMBLY: call <2 x i64> @llvm.wasm.relaxed.laneselect.v2i64(
597   // WEBASSEMBLY-SAME: <2 x i64> %a, <2 x i64> %b, <2 x i64> %c)
598   // WEBASSEMBLY-NEXT: ret
599 }
600 
601 i8x16 relaxed_swizzle_i8x16(i8x16 x, i8x16 y) {
602   return __builtin_wasm_relaxed_swizzle_i8x16(x, y);
603   // WEBASSEMBLY: call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> %x, <16 x i8> %y)
604 }
605 
606 f32x4 relaxed_min_f32x4(f32x4 a, f32x4 b) {
607   return __builtin_wasm_relaxed_min_f32x4(a, b);
608   // WEBASSEMBLY: call <4 x float> @llvm.wasm.relaxed.min.v4f32(
609   // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b)
610   // WEBASSEMBLY-NEXT: ret
611 }
612 
613 f32x4 relaxed_max_f32x4(f32x4 a, f32x4 b) {
614   return __builtin_wasm_relaxed_max_f32x4(a, b);
615   // WEBASSEMBLY: call <4 x float> @llvm.wasm.relaxed.max.v4f32(
616   // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b)
617   // WEBASSEMBLY-NEXT: ret
618 }
619 
620 f64x2 relaxed_min_f64x2(f64x2 a, f64x2 b) {
621   return __builtin_wasm_relaxed_min_f64x2(a, b);
622   // WEBASSEMBLY: call <2 x double> @llvm.wasm.relaxed.min.v2f64(
623   // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b)
624   // WEBASSEMBLY-NEXT: ret
625 }
626 
627 f64x2 relaxed_max_f64x2(f64x2 a, f64x2 b) {
628   return __builtin_wasm_relaxed_max_f64x2(a, b);
629   // WEBASSEMBLY: call <2 x double> @llvm.wasm.relaxed.max.v2f64(
630   // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b)
631   // WEBASSEMBLY-NEXT: ret
632 }
633 
634 i32x4 relaxed_trunc_s_i32x4_f32x4(f32x4 f) {
635   return __builtin_wasm_relaxed_trunc_s_i32x4_f32x4(f);
636   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.signed(<4 x float> %f)
637   // WEBASSEMBLY-NEXT: ret
638 }
639 
640 u32x4 relaxed_trunc_u_i32x4_f32x4(f32x4 f) {
641   return __builtin_wasm_relaxed_trunc_u_i32x4_f32x4(f);
642   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.unsigned(<4 x float> %f)
643   // WEBASSEMBLY-NEXT: ret
644 }
645 
646 i32x4 relaxed_trunc_s_zero_i32x4_f64x2(f64x2 x) {
647   return __builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2(x);
648   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.signed.zero(<2 x double> %x)
649   // WEBASSEMBLY-NEXT: ret
650 }
651 
652 u32x4 relaxed_trunc_u_zero_i32x4_f64x2(f64x2 x) {
653   return __builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2(x);
654   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.unsigned.zero(<2 x double> %x)
655   // WEBASSEMBLY-NEXT: ret
656 }
657 
658 i16x8 relaxed_q15mulr_s_i16x8(i16x8 a, i16x8 b) {
659   return __builtin_wasm_relaxed_q15mulr_s_i16x8(a, b);
660   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.relaxed.q15mulr.signed(
661   // WEBASSEMBLY-SAME: <8 x i16> %a, <8 x i16> %b)
662   // WEBASSEMBLY-NEXT: ret
663 }
664 
665 i16x8 dot_i8x16_i7x16_s_i16x8(i8x16 a, i8x16 b) {
666   return __builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8(a, b);
667   // WEBASSEMBLY: call <8 x i16> @llvm.wasm.relaxed.dot.i8x16.i7x16.signed(
668   // WEBASSEMBLY-SAME: <16 x i8> %a, <16 x i8> %b)
669   // WEBASSEMBLY-NEXT: ret
670 }
671 
672 i32x4 dot_i8x16_i7x16_add_s_i32x4(i8x16 a, i8x16 b, i32x4 c) {
673   return __builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4(a, b, c);
674   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.dot.i8x16.i7x16.add.signed(
675   // WEBASSEMBLY-SAME: <16 x i8> %a, <16 x i8> %b, <4 x i32> %c)
676   // WEBASSEMBLY-NEXT: ret
677 }
678 
679 f32x4 relaxed_dot_bf16x8_add_f32_f32x4(u16x8 a, u16x8 b, f32x4 c) {
680   return __builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4(a, b, c);
681   // WEBASSEMBLY: call <4 x float> @llvm.wasm.relaxed.dot.bf16x8.add.f32
682   // WEBASSEMBLY-SAME: <8 x i16> %a, <8 x i16> %b, <4 x float> %c)
683   // WEBASSEMBLY-NEXT: ret
684 }
685 
686 float load_f16_f32(__fp16 *addr) {
687   return __builtin_wasm_loadf16_f32(addr);
688   // WEBASSEMBLY: call float @llvm.wasm.loadf16.f32(ptr %{{.*}})
689 }
690 
691 void store_f16_f32(float val, __fp16 *addr) {
692   return __builtin_wasm_storef16_f32(val, addr);
693   // WEBASSEMBLY: tail call void @llvm.wasm.storef16.f32(float %val, ptr %{{.*}})
694   // WEBASSEMBLY-NEXT: ret
695 }
696 
697 f16x8 splat_f16x8(float a) {
698   // WEBASSEMBLY: %0 = tail call <8 x half> @llvm.wasm.splat.f16x8(float %a)
699   // WEBASSEMBLY-NEXT: ret <8 x half> %0
700   return __builtin_wasm_splat_f16x8(a);
701 }
702 
703 float extract_lane_f16x8(f16x8 a) {
704   // WEBASSEMBLY:  %0 = tail call float @llvm.wasm.extract.lane.f16x8(<8 x half> %a, i32 7)
705   // WEBASSEMBLY-NEXT: ret float %0
706   return __builtin_wasm_extract_lane_f16x8(a, 7);
707 }
708 
709 f16x8 replace_lane_f16x8(f16x8 a, float v) {
710   // WEBASSEMBLY:  %0 = tail call <8 x half> @llvm.wasm.replace.lane.f16x8(<8 x half> %a, i32 7, float %v)
711   // WEBASSEMBLY-NEXT: ret <8 x half> %0
712   return __builtin_wasm_replace_lane_f16x8(a, 7, v);
713 }
714 
715 f16x8 min_f16x8(f16x8 a, f16x8 b) {
716   // WEBASSEMBLY:  %0 = tail call <8 x half> @llvm.minimum.v8f16(<8 x half> %a, <8 x half> %b)
717   // WEBASSEMBLY-NEXT: ret <8 x half> %0
718   return __builtin_wasm_min_f16x8(a, b);
719 }
720 
721 f16x8 max_f16x8(f16x8 a, f16x8 b) {
722   // WEBASSEMBLY:  %0 = tail call <8 x half> @llvm.maximum.v8f16(<8 x half> %a, <8 x half> %b)
723   // WEBASSEMBLY-NEXT: ret <8 x half> %0
724   return __builtin_wasm_max_f16x8(a, b);
725 }
726 
727 f16x8 pmin_f16x8(f16x8 a, f16x8 b) {
728   // WEBASSEMBLY:  %0 = tail call <8 x half> @llvm.wasm.pmin.v8f16(<8 x half> %a, <8 x half> %b)
729   // WEBASSEMBLY-NEXT: ret <8 x half> %0
730   return __builtin_wasm_pmin_f16x8(a, b);
731 }
732 
733 f16x8 pmax_f16x8(f16x8 a, f16x8 b) {
734   // WEBASSEMBLY:  %0 = tail call <8 x half> @llvm.wasm.pmax.v8f16(<8 x half> %a, <8 x half> %b)
735   // WEBASSEMBLY-NEXT: ret <8 x half> %0
736   return __builtin_wasm_pmax_f16x8(a, b);
737 }
738 __externref_t externref_null() {
739   return __builtin_wasm_ref_null_extern();
740   // WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()
741   // WEBASSEMBLY-NEXT: ret
742 }
743 
744 void *tp (void) {
745   return __builtin_thread_pointer ();
746   // WEBASSEMBLY: call {{.*}} @llvm.thread.pointer()
747 }
748