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