{"action":"created","issue":{"url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/59","repository_url":"https://api.github.com/repos/WebAssembly/tool-conventions","labels_url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/59/comments","events_url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/59/events","html_url":"https://github.com/WebAssembly/tool-conventions/issues/59","id":348112152,"node_id":"MDU6SXNzdWUzNDgxMTIxNTI=","number":59,"title":"Atomic fence support","user":{"login":"aheejin","id":8726997,"node_id":"MDQ6VXNlcjg3MjY5OTc=","avatar_url":"https://avatars1.githubusercontent.com/u/8726997?v=4","gravatar_id":"","url":"https://api.github.com/users/aheejin","html_url":"https://github.com/aheejin","followers_url":"https://api.github.com/users/aheejin/followers","following_url":"https://api.github.com/users/aheejin/following{/other_user}","gists_url":"https://api.github.com/users/aheejin/gists{/gist_id}","starred_url":"https://api.github.com/users/aheejin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aheejin/subscriptions","organizations_url":"https://api.github.com/users/aheejin/orgs","repos_url":"https://api.github.com/users/aheejin/repos","events_url":"https://api.github.com/users/aheejin/events{/privacy}","received_events_url":"https://api.github.com/users/aheejin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":25,"created_at":"2018-08-06T23:13:26Z","updated_at":"2018-08-24T01:02:49Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"C++ 11 provides [`std::atomic_signal_fence`](https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence) and [`std::atomic_thread_fence`](https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence), and LLVM IR's [`fence`](http://llvm.org/docs/LangRef.html#fence-instruction) instruction also takes a [`syncscope`](http://llvm.org/docs/LangRef.html#syncscope) argument, which can be either `\"singlethread\"` (for a single thread, such as signal handlers) or `\"<target-scope>\"` (for multiple threads). And there are people who use `asm volatile(\"\"::: \"memory\")` with a similar usage to fences. How do we support these fences in wasm? Some discussions have been going on in this [CL](https://reviews.llvm.org/D49194), but the CL itself was not very much related to the topic.\r\n\r\n---\r\n\r\n#### [`std::atomic_thread_fence`](https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence) / LLVM's `fence syncscope(\"<target-scope>\")`\r\nWasm does not have a fence instruction, and currently all atomic memory instructions are sequentially consistent, but we still need something because fences also order non-atomic instructions. I submitted a [CL](https://reviews.llvm.org/D50277) that converts a fence into a sequence of\r\n```\r\nget_global $__stack_pointer\r\ni32.atomic.rmw.or 0\r\n```\r\nwhich is basically an idempotent atomic RMW instruction.\r\n\r\n---\r\n\r\n#### [`std::atomic_signal_fence`](https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence) / LLVM's `fence syncscope(\"singlethread\")`\r\nCurrently [the fence CL](https://reviews.llvm.org/D50277) does not distinguish syncscopes, treating both of them the same way conservatively. But for fences that work only within a thread, we may not need to emit an atomic idempotent RMW instruction; preventing instruction reordering across it during the backend compilation (using a pseudo instruction or something) would be sufficient, and it can eventually be lowered down to 0 instruction. What do you think? \r\n\r\n---\r\n\r\n#### `asm volatile(\"\"::: \"memory\")`\r\nWe are currently doing nothing for this, but how about treating this as the same way as a signal fence, meaning it will become a pseudo instruction that prevents reordering within the compiler backend but eventually be converted to 0 instruction?"},"comment":{"url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/comments/415618947","html_url":"https://github.com/WebAssembly/tool-conventions/issues/59#issuecomment-415618947","issue_url":"https://api.github.com/repos/WebAssembly/tool-conventions/issues/59","id":415618947,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNTYxODk0Nw==","user":{"login":"aheejin","id":8726997,"node_id":"MDQ6VXNlcjg3MjY5OTc=","avatar_url":"https://avatars1.githubusercontent.com/u/8726997?v=4","gravatar_id":"","url":"https://api.github.com/users/aheejin","html_url":"https://github.com/aheejin","followers_url":"https://api.github.com/users/aheejin/followers","following_url":"https://api.github.com/users/aheejin/following{/other_user}","gists_url":"https://api.github.com/users/aheejin/gists{/gist_id}","starred_url":"https://api.github.com/users/aheejin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aheejin/subscriptions","organizations_url":"https://api.github.com/users/aheejin/orgs","repos_url":"https://api.github.com/users/aheejin/repos","events_url":"https://api.github.com/users/aheejin/events{/privacy}","received_events_url":"https://api.github.com/users/aheejin/received_events","type":"User","site_admin":false},"created_at":"2018-08-24T01:02:49Z","updated_at":"2018-08-24T01:02:49Z","author_association":"CONTRIBUTOR","body":"@sunfishcode \r\n> That suggests that the semantics of LLVM's fence, which go by the Standard, may be insufficient for such code. Even if it happens to survive the optimizer intact today, it would be more robust [0] to have the frontend translate it into something stronger, so that it has the semantics it needs throughout the entire compilation pipeline.\r\n\r\nIf we want to translate that to `atomicrmw` in clang, we are gonna have to use `load atomic` LLVM IR instruction, which does not provide stronger guarantee than LLVM seq_cst fence. Neither of them say anything about its relationship with non-atomic operations.\r\n\r\nEven if we come up with our own `atomicrmw` intrinsic or something, I don't think we can specify something stronger than seq_cst fence in terms of LLVM IR. All we can specify for that intrinsic is intrinsic properties, which should be from [the list of intrinsic properties](https://github.com/llvm-mirror/llvm/blob/db0f76949f25f76fc96b87b9a7b53d61c6639bb3/include/llvm/IR/Intrinsics.td#L23-L112). The reason `atomicrmw` wasm instruction works is [wasm seq_cst atomic provides stronger guarantees](https://github.com/WebAssembly/binaryen/pull/1094#issuecomment-316796667) than LLVM seq_cst atomics.\r\n\r\nSo as far as I understand, _if_ we want to be user friendly, emitting an `atomicrmw` in the backend seems to be the only way."}}
{"actor":{"display_login":"aheejin"}}