From 2cc8473cc7639dcca7939e948ffd2a322a5e9db1 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 2 Aug 2018 21:44:40 +0000 Subject: [PATCH] [WebAssembly] Support for atomic.wait / atomic.wake builtins Summary: Add support for atomic.wait / atomic.wake builtins based on the Wasm thread proposal. Reviewers: dschuff Subscribers: sbc100, jgravelle-google, sunfish, cfe-commits Differential Revision: https://reviews.llvm.org/D49396 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338771 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/BuiltinsWebAssembly.def | 5 +++++ lib/CodeGen/CGBuiltin.cpp | 20 ++++++++++++++++++++ test/CodeGen/builtins-wasm.c | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index b3d877dced..45ce07292e 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -34,4 +34,9 @@ BUILTIN(__builtin_wasm_grow_memory, "zz", "n") BUILTIN(__builtin_wasm_throw, "vUiv*", "r") BUILTIN(__builtin_wasm_rethrow, "v", "r") +// Atomic wait and notify. +BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n") +BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n") +BUILTIN(__builtin_wasm_atomic_notify, "ULLii*LLi", "n") + #undef BUILTIN diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 4b6082aae5..c1959bdf17 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -12055,6 +12055,26 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 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_notify: { + Value *Addr = EmitScalarExpr(E->getArg(0)); + Value *Count = EmitScalarExpr(E->getArg(1)); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify); + return Builder.CreateCall(Callee, {Addr, Count}); + } default: return nullptr; diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c index 1b647b56d1..d1c5c303d4 100644 --- a/test/CodeGen/builtins-wasm.c +++ b/test/CodeGen/builtins-wasm.c @@ -50,3 +50,21 @@ void f7(void) { // WEBASSEMBLY32: call void @llvm.wasm.rethrow() // WEBASSEMBLY64: call void @llvm.wasm.rethrow() } + +int f8(int *addr, int expected, long long timeout) { + return __builtin_wasm_atomic_wait_i32(addr, expected, timeout); +// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) +} + +int f9(long long *addr, long long expected, long long timeout) { + return __builtin_wasm_atomic_wait_i64(addr, expected, timeout); +// WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +} + +unsigned long long f10(int *addr, long long count) { + return __builtin_wasm_atomic_notify(addr, count); +// WEBASSEMBLY32: call i64 @llvm.wasm.atomic.notify(i32* %{{.*}}, i64 %{{.*}}) +// WEBASSEMBLY64: call i64 @llvm.wasm.atomic.notify(i32* %{{.*}}, i64 %{{.*}}) +} -- 2.40.0