diff options
| author | Heejin Ahn <aheejin@gmail.com> | 2019-08-28 23:13:43 +0000 |
|---|---|---|
| committer | Heejin Ahn <aheejin@gmail.com> | 2019-08-28 23:13:43 +0000 |
| commit | d85fd5a3f42777bb53835a380b27a796262d434b (patch) | |
| tree | 0222962ce971572c41bd4ad23c7946166d3cbf5d /llvm/test/CodeGen/WebAssembly | |
| parent | 5be949e3d007ea0bf1979a483ce558d33eca5d6a (diff) | |
| download | bcm5719-llvm-d85fd5a3f42777bb53835a380b27a796262d434b.tar.gz bcm5719-llvm-d85fd5a3f42777bb53835a380b27a796262d434b.zip | |
[WebAssembly] Add atomic.fence instruction
Summary:
This adds `atomic.fence` instruction:
https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#fence-operator
And we now emit the new `atomic.fence` instruction for multithread
fences, rather than the prevous `atomic.rmw` hack.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, jfb, tlively, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66794
llvm-svn: 370272
Diffstat (limited to 'llvm/test/CodeGen/WebAssembly')
| -rw-r--r-- | llvm/test/CodeGen/WebAssembly/atomic-fence.ll | 23 | ||||
| -rw-r--r-- | llvm/test/CodeGen/WebAssembly/atomic-fence.mir | 68 |
2 files changed, 76 insertions, 15 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/atomic-fence.ll b/llvm/test/CodeGen/WebAssembly/atomic-fence.ll index 22084e48e27..43a1a66f976 100644 --- a/llvm/test/CodeGen/WebAssembly/atomic-fence.ll +++ b/llvm/test/CodeGen/WebAssembly/atomic-fence.ll @@ -1,19 +1,12 @@ ; RUN: llc < %s | FileCheck %s --check-prefix NOATOMIC -; RUN: not llc < %s -mtriple=wasm32-unknown-unknown -mattr=+atomics,+sign-ext 2>&1 | FileCheck %s --check-prefixes NOEMSCRIPTEN -; RUN: not llc < %s -mtriple=wasm32-unknown-wasi -mattr=+atomics,+sign-ext 2>&1 | FileCheck %s --check-prefixes NOEMSCRIPTEN -; RUN: llc < %s -mtriple=wasm32-unknown-emscripten -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+atomics,+sign-ext | FileCheck %s +; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+atomics | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -; NOEMSCRIPTEN: LLVM ERROR: ATOMIC_FENCE is not yet supported in non-emscripten OSes - -; A multithread fence turns into 'global.get $__stack_pointer' followed by an -; idempotent atomicrmw instruction. +; A multithread fence is lowered to an atomic.fence instruction. ; CHECK-LABEL: multithread_fence: -; CHECK: global.get $push[[SP:[0-9]+]]=, __stack_pointer -; CHECK-NEXT: i32.const $push[[ZERO:[0-9]+]]=, 0 -; CHECK-NEXT: i32.atomic.rmw.or $drop=, 0($pop[[SP]]), $pop[[ZERO]] +; CHECK: atomic.fence ; NOATOMIC-NOT: i32.atomic.rmw.or define void @multithread_fence() { fence seq_cst @@ -23,10 +16,9 @@ define void @multithread_fence() { ; Fences with weaker memory orderings than seq_cst should be treated the same ; because atomic memory access in wasm are sequentially consistent. ; CHECK-LABEL: multithread_weak_fence: -; CHECK: global.get $push{{.+}}=, __stack_pointer -; CHECK: i32.atomic.rmw.or -; CHECK: i32.atomic.rmw.or -; CHECK: i32.atomic.rmw.or +; CHECK: atomic.fence +; CHECK-NEXT: atomic.fence +; CHECK-NEXT: atomic.fence define void @multithread_weak_fence() { fence acquire fence release @@ -37,7 +29,8 @@ define void @multithread_weak_fence() { ; A singlethread fence becomes compiler_fence instruction, a pseudo instruction ; that acts as a compiler barrier. The barrier should not be emitted to .s file. ; CHECK-LABEL: singlethread_fence: -; CHECK-NOT: compiler_fence +; CHECK-NOT: compiler_fence +; CHECK-NOT: atomic_fence define void @singlethread_fence() { fence syncscope("singlethread") seq_cst fence syncscope("singlethread") acquire diff --git a/llvm/test/CodeGen/WebAssembly/atomic-fence.mir b/llvm/test/CodeGen/WebAssembly/atomic-fence.mir new file mode 100644 index 00000000000..46f38a52f30 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/atomic-fence.mir @@ -0,0 +1,68 @@ +# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-reg-stackify -run-pass wasm-explicit-locals %s -o - | FileCheck %s + +# In the two tests below, without compiler_fence or atomic.fence in between, +# atomic.notify and i32.add will be reordered by register stackify pass to meet +# 'call @foo''s requirements. But because we have fences between atomic.notify +# and i32.add, they cannot be reordered, and local.set and local.get are +# inserted to save and load atomic.notify's return value. + +--- | + target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" + target triple = "wasm32-unknown-unknown" + + declare void @foo(i32, i32) + define void @compiler_fence_test(i32) { + ret void + } + define void @atomic_fence_test(i32) { + ret void + } +... +--- +# CHECK-LABEL: name: compiler_fence_test +name: compiler_fence_test +liveins: + - { reg: '$arguments' } +tracksRegLiveness: true +body: | + bb.0: + ; CHECK: %[[REG:[0-9]+]]:i32 = ATOMIC_NOTIFY + ; CHECK: LOCAL_SET_I32 [[LOCAL:[0-9]+]], %[[REG]] + ; CHECK: COMPILER_FENCE + ; CHECK: ADD_I32 + ; CHECK: LOCAL_GET_I32 [[LOCAL]] + ; CHECK: CALL_VOID @foo + + liveins: $arguments + %0:i32 = CONST_I32 0, implicit-def $arguments + %1:i32 = ATOMIC_NOTIFY 2, 0, %0:i32, %0:i32, implicit-def $arguments + COMPILER_FENCE implicit-def $arguments + %2:i32 = ADD_I32 %0:i32, %0:i32, implicit-def $arguments + CALL_VOID @foo, %2:i32, %1:i32, implicit-def $arguments + RETURN_VOID implicit-def $arguments +... + +--- +# CHECK-LABEL: name: atomic_fence_test +name: atomic_fence_test +liveins: + - { reg: '$arguments' } +tracksRegLiveness: true +body: | + bb.0: + ; CHECK: %[[REG:[0-9]+]]:i32 = ATOMIC_NOTIFY + ; CHECK: LOCAL_SET_I32 [[LOCAL:[0-9]+]], %[[REG]] + ; CHECK: ATOMIC_FENCE + ; CHECK: ADD_I32 + ; CHECK: LOCAL_GET_I32 [[LOCAL]] + ; CHECK: CALL_VOID @foo + + liveins: $arguments + %0:i32 = CONST_I32 0, implicit-def $arguments + %1:i32 = ATOMIC_NOTIFY 2, 0, %0:i32, %0:i32, implicit-def $arguments + ATOMIC_FENCE 0, implicit-def $arguments + %2:i32 = ADD_I32 %0:i32, %0:i32, implicit-def $arguments + CALL_VOID @foo, %2:i32, %1:i32, implicit-def $arguments + RETURN_VOID implicit-def $arguments +... + |

