Index: include/clang/Basic/BuiltinsWebAssembly.def =================================================================== --- include/clang/Basic/BuiltinsWebAssembly.def +++ include/clang/Basic/BuiltinsWebAssembly.def @@ -34,4 +34,9 @@ BUILTIN(__builtin_wasm_throw, "vUiv*", "r") BUILTIN(__builtin_wasm_rethrow, "v", "r") +// Atomic wait and wake. +BUILTIN(__builtin_wasm_atomic_wait_i32, "Uiv*iLLi", "n") +BUILTIN(__builtin_wasm_atomic_wait_i64, "Uiv*LLiLLi", "n") +BUILTIN(__builtin_wasm_atomic_wake, "ULLiv*LLi", "n") + #undef BUILTIN Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -12054,6 +12054,26 @@ Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); return Builder.CreateCall(Callee); } + case WebAssembly::BI__builtin_wasm_atomic_wait_i32: { + Value *Addr = EmitScalarExpr(E->getArg(0)); + Value *Expected = EmitScalarExpr(E->getArg(1)); + Value *Timeout = EmitScalarExpr(E->getArg(2)); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i32); + return Builder.CreateCall(Callee, {Addr, Expected, Timeout}); + } + case WebAssembly::BI__builtin_wasm_atomic_wait_i64: { + Value *Addr = EmitScalarExpr(E->getArg(0)); + Value *Expected = EmitScalarExpr(E->getArg(1)); + Value *Timeout = EmitScalarExpr(E->getArg(2)); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i64); + return Builder.CreateCall(Callee, {Addr, Expected, Timeout}); + } + case WebAssembly::BI__builtin_wasm_atomic_wake: { + Value *Addr = EmitScalarExpr(E->getArg(0)); + Value *WakeCount = EmitScalarExpr(E->getArg(1)); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wake); + return Builder.CreateCall(Callee, {Addr, WakeCount}); + } default: return nullptr; Index: test/CodeGen/builtins-wasm.c =================================================================== --- test/CodeGen/builtins-wasm.c +++ test/CodeGen/builtins-wasm.c @@ -50,3 +50,21 @@ // WEBASSEMBLY32: call void @llvm.wasm.rethrow() // WEBASSEMBLY64: call void @llvm.wasm.rethrow() } + +unsigned int f8(void *addr, int expected, long long timeout) { + return __builtin_wasm_atomic_wait_i32(addr, expected, timeout); +// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i8* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i8* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) +} + +unsigned int f9(void *addr, long long expected, long long timeout) { + return __builtin_wasm_atomic_wait_i64(addr, expected, timeout); +// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i8* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i8* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +} + +unsigned long long f10(void *addr, long long wake_count) { + return __builtin_wasm_atomic_wake(addr, wake_count); +// WEBASSEMBLY32: call i64 @llvm.wasm.atomic.wake(i8* %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i64 @llvm.wasm.atomic.wake(i8* %{{.*}}, i64 %{{.*}}) +}