15#include "llvm/ADT/APInt.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/IntrinsicsWebAssembly.h"
18#include "llvm/Support/ErrorHandling.h"
21using namespace CodeGen;
27 case WebAssembly::BI__builtin_wasm_memory_size: {
32 return Builder.CreateCall(Callee, I);
34 case WebAssembly::BI__builtin_wasm_memory_grow: {
40 return Builder.CreateCall(Callee, Args);
42 case WebAssembly::BI__builtin_wasm_tls_size: {
45 return Builder.CreateCall(Callee);
47 case WebAssembly::BI__builtin_wasm_tls_align: {
50 return Builder.CreateCall(Callee);
52 case WebAssembly::BI__builtin_wasm_tls_base: {
54 return Builder.CreateCall(Callee);
56 case WebAssembly::BI__builtin_wasm_throw: {
62 case WebAssembly::BI__builtin_wasm_rethrow: {
66 case WebAssembly::BI__builtin_wasm_memory_atomic_wait32: {
73 case WebAssembly::BI__builtin_wasm_memory_atomic_wait64: {
80 case WebAssembly::BI__builtin_wasm_memory_atomic_notify: {
86 case WebAssembly::BI__builtin_wasm_trunc_s_i32_f32:
87 case WebAssembly::BI__builtin_wasm_trunc_s_i32_f64:
88 case WebAssembly::BI__builtin_wasm_trunc_s_i64_f32:
89 case WebAssembly::BI__builtin_wasm_trunc_s_i64_f64: {
94 return Builder.CreateCall(Callee, {Src});
96 case WebAssembly::BI__builtin_wasm_trunc_u_i32_f32:
97 case WebAssembly::BI__builtin_wasm_trunc_u_i32_f64:
98 case WebAssembly::BI__builtin_wasm_trunc_u_i64_f32:
99 case WebAssembly::BI__builtin_wasm_trunc_u_i64_f64: {
104 return Builder.CreateCall(Callee, {Src});
106 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f32:
107 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f64:
108 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f32:
109 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f64:
110 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i16x8_f16x8:
111 case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32x4_f32x4: {
116 return Builder.CreateCall(Callee, {Src});
118 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f32:
119 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f64:
120 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f32:
121 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f64:
122 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i16x8_f16x8:
123 case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32x4_f32x4: {
128 return Builder.CreateCall(Callee, {Src});
130 case WebAssembly::BI__builtin_wasm_min_f32:
131 case WebAssembly::BI__builtin_wasm_min_f64:
132 case WebAssembly::BI__builtin_wasm_min_f16x8:
133 case WebAssembly::BI__builtin_wasm_min_f32x4:
134 case WebAssembly::BI__builtin_wasm_min_f64x2: {
139 return Builder.CreateCall(Callee, {LHS, RHS});
141 case WebAssembly::BI__builtin_wasm_max_f32:
142 case WebAssembly::BI__builtin_wasm_max_f64:
143 case WebAssembly::BI__builtin_wasm_max_f16x8:
144 case WebAssembly::BI__builtin_wasm_max_f32x4:
145 case WebAssembly::BI__builtin_wasm_max_f64x2: {
150 return Builder.CreateCall(Callee, {LHS, RHS});
152 case WebAssembly::BI__builtin_wasm_pmin_f16x8:
153 case WebAssembly::BI__builtin_wasm_pmin_f32x4:
154 case WebAssembly::BI__builtin_wasm_pmin_f64x2: {
159 return Builder.CreateCall(Callee, {LHS, RHS});
161 case WebAssembly::BI__builtin_wasm_pmax_f16x8:
162 case WebAssembly::BI__builtin_wasm_pmax_f32x4:
163 case WebAssembly::BI__builtin_wasm_pmax_f64x2: {
168 return Builder.CreateCall(Callee, {LHS, RHS});
170 case WebAssembly::BI__builtin_wasm_ceil_f16x8:
171 case WebAssembly::BI__builtin_wasm_floor_f16x8:
172 case WebAssembly::BI__builtin_wasm_trunc_f16x8:
173 case WebAssembly::BI__builtin_wasm_nearest_f16x8:
174 case WebAssembly::BI__builtin_wasm_ceil_f32x4:
175 case WebAssembly::BI__builtin_wasm_floor_f32x4:
176 case WebAssembly::BI__builtin_wasm_trunc_f32x4:
177 case WebAssembly::BI__builtin_wasm_nearest_f32x4:
178 case WebAssembly::BI__builtin_wasm_ceil_f64x2:
179 case WebAssembly::BI__builtin_wasm_floor_f64x2:
180 case WebAssembly::BI__builtin_wasm_trunc_f64x2:
181 case WebAssembly::BI__builtin_wasm_nearest_f64x2: {
184 case WebAssembly::BI__builtin_wasm_ceil_f16x8:
185 case WebAssembly::BI__builtin_wasm_ceil_f32x4:
186 case WebAssembly::BI__builtin_wasm_ceil_f64x2:
187 IntNo = Intrinsic::ceil;
189 case WebAssembly::BI__builtin_wasm_floor_f16x8:
190 case WebAssembly::BI__builtin_wasm_floor_f32x4:
191 case WebAssembly::BI__builtin_wasm_floor_f64x2:
192 IntNo = Intrinsic::floor;
194 case WebAssembly::BI__builtin_wasm_trunc_f16x8:
195 case WebAssembly::BI__builtin_wasm_trunc_f32x4:
196 case WebAssembly::BI__builtin_wasm_trunc_f64x2:
197 IntNo = Intrinsic::trunc;
199 case WebAssembly::BI__builtin_wasm_nearest_f16x8:
200 case WebAssembly::BI__builtin_wasm_nearest_f32x4:
201 case WebAssembly::BI__builtin_wasm_nearest_f64x2:
202 IntNo = Intrinsic::nearbyint;
205 llvm_unreachable(
"unexpected builtin ID");
211 case WebAssembly::BI__builtin_wasm_ref_null_extern: {
213 return Builder.CreateCall(Callee);
215 case WebAssembly::BI__builtin_wasm_ref_is_null_extern: {
218 return Builder.CreateCall(Callee, {Src});
220 case WebAssembly::BI__builtin_wasm_ref_null_func: {
222 return Builder.CreateCall(Callee);
224 case WebAssembly::BI__builtin_wasm_test_function_pointer_signature: {
230 assert(PtrTy &&
"Sema should have ensured this is a function pointer");
233 assert(FuncTy &&
"Sema should have ensured this is a function pointer");
246 llvm::FunctionType *LLVMFuncTy =
249 bool VarArg = LLVMFuncTy->isVarArg();
250 unsigned NParams = LLVMFuncTy->getNumParams();
251 std::vector<Value *> Args;
252 Args.reserve(NParams + 3 + VarArg);
254 Args.push_back(FuncRef);
257 llvm::Type *RetType = LLVMFuncTy->getReturnType();
258 if (!RetType->isVoidTy()) {
259 Args.push_back(PoisonValue::get(RetType));
263 Args.push_back(PoisonValue::get(llvm::Type::getTokenTy(
getLLVMContext())));
264 for (
unsigned i = 0; i < NParams; i++) {
265 Args.push_back(PoisonValue::get(LLVMFuncTy->getParamType(i)));
268 Args.push_back(PoisonValue::get(
Builder.getPtrTy()));
271 return Builder.CreateCall(Callee, Args);
273 case WebAssembly::BI__builtin_wasm_swizzle_i8x16: {
277 return Builder.CreateCall(Callee, {Src, Indices});
279 case WebAssembly::BI__builtin_wasm_abs_i8x16:
280 case WebAssembly::BI__builtin_wasm_abs_i16x8:
281 case WebAssembly::BI__builtin_wasm_abs_i32x4:
282 case WebAssembly::BI__builtin_wasm_abs_i64x2: {
285 Constant *
Zero = llvm::Constant::getNullValue(Vec->
getType());
287 return Builder.CreateSelect(ICmp, Neg, Vec,
"abs");
289 case WebAssembly::BI__builtin_wasm_avgr_u_i8x16:
290 case WebAssembly::BI__builtin_wasm_avgr_u_i16x8: {
295 return Builder.CreateCall(Callee, {LHS, RHS});
297 case WebAssembly::BI__builtin_wasm_q15mulr_sat_s_i16x8: {
301 return Builder.CreateCall(Callee, {LHS, RHS});
303 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_s_i16x8:
304 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_u_i16x8:
305 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_s_i32x4:
306 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_u_i32x4: {
310 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_s_i16x8:
311 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_s_i32x4:
312 IntNo = Intrinsic::wasm_extadd_pairwise_signed;
314 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_u_i16x8:
315 case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_u_i32x4:
316 IntNo = Intrinsic::wasm_extadd_pairwise_unsigned;
319 llvm_unreachable(
"unexpected builtin ID");
323 return Builder.CreateCall(Callee, Vec);
325 case WebAssembly::BI__builtin_wasm_bitselect: {
331 return Builder.CreateCall(Callee, {V1, V2,
C});
333 case WebAssembly::BI__builtin_wasm_dot_s_i32x4_i16x8: {
337 return Builder.CreateCall(Callee, {LHS, RHS});
339 case WebAssembly::BI__builtin_wasm_any_true_v128:
340 case WebAssembly::BI__builtin_wasm_all_true_i8x16:
341 case WebAssembly::BI__builtin_wasm_all_true_i16x8:
342 case WebAssembly::BI__builtin_wasm_all_true_i32x4:
343 case WebAssembly::BI__builtin_wasm_all_true_i64x2: {
346 case WebAssembly::BI__builtin_wasm_any_true_v128:
347 IntNo = Intrinsic::wasm_anytrue;
349 case WebAssembly::BI__builtin_wasm_all_true_i8x16:
350 case WebAssembly::BI__builtin_wasm_all_true_i16x8:
351 case WebAssembly::BI__builtin_wasm_all_true_i32x4:
352 case WebAssembly::BI__builtin_wasm_all_true_i64x2:
353 IntNo = Intrinsic::wasm_alltrue;
356 llvm_unreachable(
"unexpected builtin ID");
360 return Builder.CreateCall(Callee, {Vec});
362 case WebAssembly::BI__builtin_wasm_bitmask_i8x16:
363 case WebAssembly::BI__builtin_wasm_bitmask_i16x8:
364 case WebAssembly::BI__builtin_wasm_bitmask_i32x4:
365 case WebAssembly::BI__builtin_wasm_bitmask_i64x2: {
369 return Builder.CreateCall(Callee, {Vec});
371 case WebAssembly::BI__builtin_wasm_abs_f16x8:
372 case WebAssembly::BI__builtin_wasm_abs_f32x4:
373 case WebAssembly::BI__builtin_wasm_abs_f64x2: {
376 return Builder.CreateCall(Callee, {Vec});
378 case WebAssembly::BI__builtin_wasm_sqrt_f16x8:
379 case WebAssembly::BI__builtin_wasm_sqrt_f32x4:
380 case WebAssembly::BI__builtin_wasm_sqrt_f64x2: {
383 return Builder.CreateCall(Callee, {Vec});
385 case WebAssembly::BI__builtin_wasm_narrow_s_i8x16_i16x8:
386 case WebAssembly::BI__builtin_wasm_narrow_u_i8x16_i16x8:
387 case WebAssembly::BI__builtin_wasm_narrow_s_i16x8_i32x4:
388 case WebAssembly::BI__builtin_wasm_narrow_u_i16x8_i32x4: {
393 case WebAssembly::BI__builtin_wasm_narrow_s_i8x16_i16x8:
394 case WebAssembly::BI__builtin_wasm_narrow_s_i16x8_i32x4:
395 IntNo = Intrinsic::wasm_narrow_signed;
397 case WebAssembly::BI__builtin_wasm_narrow_u_i8x16_i16x8:
398 case WebAssembly::BI__builtin_wasm_narrow_u_i16x8_i32x4:
399 IntNo = Intrinsic::wasm_narrow_unsigned;
402 llvm_unreachable(
"unexpected builtin ID");
406 return Builder.CreateCall(Callee, {Low, High});
408 case WebAssembly::BI__builtin_wasm_trunc_sat_s_zero_f64x2_i32x4:
409 case WebAssembly::BI__builtin_wasm_trunc_sat_u_zero_f64x2_i32x4: {
413 case WebAssembly::BI__builtin_wasm_trunc_sat_s_zero_f64x2_i32x4:
414 IntNo = Intrinsic::fptosi_sat;
416 case WebAssembly::BI__builtin_wasm_trunc_sat_u_zero_f64x2_i32x4:
417 IntNo = Intrinsic::fptoui_sat;
420 llvm_unreachable(
"unexpected builtin ID");
422 llvm::Type *SrcT = Vec->
getType();
423 llvm::Type *TruncT = SrcT->getWithNewType(
Builder.getInt32Ty());
426 Value *Splat = Constant::getNullValue(TruncT);
427 return Builder.CreateShuffleVector(Trunc, Splat, {0, 1, 2, 3});
429 case WebAssembly::BI__builtin_wasm_shuffle_i8x16: {
435 std::optional<llvm::APSInt> LaneConst =
437 assert(LaneConst &&
"Constant arg isn't actually constant?");
438 Ops[OpIdx++] = llvm::ConstantInt::get(
getLLVMContext(), *LaneConst);
441 return Builder.CreateCall(Callee, Ops);
443 case WebAssembly::BI__builtin_wasm_relaxed_madd_f16x8:
444 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f16x8:
445 case WebAssembly::BI__builtin_wasm_relaxed_madd_f32x4:
446 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f32x4:
447 case WebAssembly::BI__builtin_wasm_relaxed_madd_f64x2:
448 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f64x2: {
454 case WebAssembly::BI__builtin_wasm_relaxed_madd_f16x8:
455 case WebAssembly::BI__builtin_wasm_relaxed_madd_f32x4:
456 case WebAssembly::BI__builtin_wasm_relaxed_madd_f64x2:
457 IntNo = Intrinsic::wasm_relaxed_madd;
459 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f16x8:
460 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f32x4:
461 case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f64x2:
462 IntNo = Intrinsic::wasm_relaxed_nmadd;
465 llvm_unreachable(
"unexpected builtin ID");
468 return Builder.CreateCall(Callee, {A, B,
C});
470 case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i8x16:
471 case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i16x8:
472 case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i32x4:
473 case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i64x2: {
479 return Builder.CreateCall(Callee, {A, B,
C});
481 case WebAssembly::BI__builtin_wasm_relaxed_swizzle_i8x16: {
485 return Builder.CreateCall(Callee, {Src, Indices});
487 case WebAssembly::BI__builtin_wasm_relaxed_min_f32x4:
488 case WebAssembly::BI__builtin_wasm_relaxed_max_f32x4:
489 case WebAssembly::BI__builtin_wasm_relaxed_min_f64x2:
490 case WebAssembly::BI__builtin_wasm_relaxed_max_f64x2: {
495 case WebAssembly::BI__builtin_wasm_relaxed_min_f32x4:
496 case WebAssembly::BI__builtin_wasm_relaxed_min_f64x2:
497 IntNo = Intrinsic::wasm_relaxed_min;
499 case WebAssembly::BI__builtin_wasm_relaxed_max_f32x4:
500 case WebAssembly::BI__builtin_wasm_relaxed_max_f64x2:
501 IntNo = Intrinsic::wasm_relaxed_max;
504 llvm_unreachable(
"unexpected builtin ID");
507 return Builder.CreateCall(Callee, {LHS, RHS});
509 case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
510 case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4:
511 case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2:
512 case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2: {
516 case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
517 IntNo = Intrinsic::wasm_relaxed_trunc_signed;
519 case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4:
520 IntNo = Intrinsic::wasm_relaxed_trunc_unsigned;
522 case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2:
523 IntNo = Intrinsic::wasm_relaxed_trunc_signed_zero;
525 case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2:
526 IntNo = Intrinsic::wasm_relaxed_trunc_unsigned_zero;
529 llvm_unreachable(
"unexpected builtin ID");
532 return Builder.CreateCall(Callee, {Vec});
534 case WebAssembly::BI__builtin_wasm_relaxed_q15mulr_s_i16x8: {
538 return Builder.CreateCall(Callee, {LHS, RHS});
540 case WebAssembly::BI__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8: {
545 return Builder.CreateCall(Callee, {LHS, RHS});
547 case WebAssembly::BI__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4: {
553 return Builder.CreateCall(Callee, {LHS, RHS, Acc});
555 case WebAssembly::BI__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4: {
561 return Builder.CreateCall(Callee, {LHS, RHS, Acc});
563 case WebAssembly::BI__builtin_wasm_loadf16_f32: {
568 case WebAssembly::BI__builtin_wasm_storef16_f32: {
574 case WebAssembly::BI__builtin_wasm_splat_f16x8: {
577 return Builder.CreateCall(Callee, {Val});
579 case WebAssembly::BI__builtin_wasm_extract_lane_f16x8: {
585 case WebAssembly::BI__builtin_wasm_replace_lane_f16x8: {
592 case WebAssembly::BI__builtin_wasm_table_get: {
603 "Unexpected reference type for __builtin_wasm_table_get");
604 return Builder.CreateCall(Callee, {Table, Index});
606 case WebAssembly::BI__builtin_wasm_table_set: {
618 "Unexpected reference type for __builtin_wasm_table_set");
619 return Builder.CreateCall(Callee, {Table, Index, Val});
621 case WebAssembly::BI__builtin_wasm_table_size: {
627 case WebAssembly::BI__builtin_wasm_table_grow: {
640 "Unexpected reference type for __builtin_wasm_table_grow");
642 return Builder.CreateCall(Callee, {Table, Val, NElems});
644 case WebAssembly::BI__builtin_wasm_table_fill: {
658 "Unexpected reference type for __builtin_wasm_table_fill");
660 return Builder.CreateCall(Callee, {Table, Index, Val, NElems});
662 case WebAssembly::BI__builtin_wasm_table_copy: {
672 return Builder.CreateCall(Callee, {TableX, TableY, SrcIdx, DstIdx, NElems});
Enumerates target-specific builtins in their own namespaces within namespace clang.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * ConvertType(QualType T)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::Value * EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, const CallExpr *E)
ASTContext & getContext() const
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
FunctionType - C99 6.7.5.3 - Function Declarators.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isWebAssemblyFuncrefType() const
Returns true if it is a WebAssembly Funcref Type.
bool isWebAssemblyExternrefType() const
Returns true if it is a WebAssembly Externref Type.
const T * getAs() const
Member-template getAs<specific type>'.
The JSON file list parser is used to communicate input to InstallAPI.
@ Vector
'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
Diagnostic wrappers for TextAPI types for error reporting.