Skip to content

Commit 8daef07

Browse files
committed
[WebAssembly] Add tests for weaker memory consistency orderings
Summary: Currently all wasm atomic memory access instructions are sequentially consistent, so even if LLVM IR specifies weaker orderings than that, we should upgrade them to sequential ordering and treat them in the same way. Reviewers: dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D49194 llvm-svn: 337854
1 parent 8db0bef commit 8daef07

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
2+
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
3+
4+
; Currently all wasm atomic memory access instructions are sequentially
5+
; consistent, so even if LLVM IR specifies weaker orderings than that, we
6+
; should upgrade them to sequential ordering and treat them in the same way.
7+
8+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
9+
target triple = "wasm32-unknown-unknown"
10+
11+
;===----------------------------------------------------------------------------
12+
; Atomic loads
13+
;===----------------------------------------------------------------------------
14+
15+
; The 'release' and 'acq_rel' orderings are not valid on load instructions.
16+
17+
; CHECK-LABEL: load_i32_unordered:
18+
; CHECK: i32.atomic.load $push0=, 0($0){{$}}
19+
; CHECK-NEXT: return $pop0{{$}}
20+
define i32 @load_i32_unordered(i32 *%p) {
21+
%v = load atomic i32, i32* %p unordered, align 4
22+
ret i32 %v
23+
}
24+
25+
; CHECK-LABEL: load_i32_monotonic:
26+
; CHECK: i32.atomic.load $push0=, 0($0){{$}}
27+
; CHECK-NEXT: return $pop0{{$}}
28+
define i32 @load_i32_monotonic(i32 *%p) {
29+
%v = load atomic i32, i32* %p monotonic, align 4
30+
ret i32 %v
31+
}
32+
33+
; CHECK-LABEL: load_i32_acquire:
34+
; CHECK: i32.atomic.load $push0=, 0($0){{$}}
35+
; CHECK-NEXT: return $pop0{{$}}
36+
define i32 @load_i32_acquire(i32 *%p) {
37+
%v = load atomic i32, i32* %p acquire, align 4
38+
ret i32 %v
39+
}
40+
41+
; CHECK-LABEL: load_i32_seq_cst:
42+
; CHECK: i32.atomic.load $push0=, 0($0){{$}}
43+
; CHECK-NEXT: return $pop0{{$}}
44+
define i32 @load_i32_seq_cst(i32 *%p) {
45+
%v = load atomic i32, i32* %p seq_cst, align 4
46+
ret i32 %v
47+
}
48+
49+
;===----------------------------------------------------------------------------
50+
; Atomic stores
51+
;===----------------------------------------------------------------------------
52+
53+
; The 'acquire' and 'acq_rel' orderings aren’t valid on store instructions.
54+
55+
; CHECK-LABEL: store_i32_unordered:
56+
; CHECK-NEXT: .param i32, i32{{$}}
57+
; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
58+
; CHECK-NEXT: return{{$}}
59+
define void @store_i32_unordered(i32 *%p, i32 %v) {
60+
store atomic i32 %v, i32* %p unordered, align 4
61+
ret void
62+
}
63+
64+
; CHECK-LABEL: store_i32_monotonic:
65+
; CHECK-NEXT: .param i32, i32{{$}}
66+
; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
67+
; CHECK-NEXT: return{{$}}
68+
define void @store_i32_monotonic(i32 *%p, i32 %v) {
69+
store atomic i32 %v, i32* %p monotonic, align 4
70+
ret void
71+
}
72+
73+
; CHECK-LABEL: store_i32_release:
74+
; CHECK-NEXT: .param i32, i32{{$}}
75+
; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
76+
; CHECK-NEXT: return{{$}}
77+
define void @store_i32_release(i32 *%p, i32 %v) {
78+
store atomic i32 %v, i32* %p release, align 4
79+
ret void
80+
}
81+
82+
; CHECK-LABEL: store_i32_seq_cst:
83+
; CHECK-NEXT: .param i32, i32{{$}}
84+
; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
85+
; CHECK-NEXT: return{{$}}
86+
define void @store_i32_seq_cst(i32 *%p, i32 %v) {
87+
store atomic i32 %v, i32* %p seq_cst, align 4
88+
ret void
89+
}
90+
91+
;===----------------------------------------------------------------------------
92+
; Atomic read-modify-writes
93+
;===----------------------------------------------------------------------------
94+
95+
; Out of several binary RMW instructions, here we test 'add' as an example.
96+
; The 'unordered' ordering is not valid on atomicrmw instructions.
97+
98+
; CHECK-LABEL: add_i32_monotonic:
99+
; CHECK-NEXT: .param i32, i32{{$}}
100+
; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
101+
; CHECK-NEXT: return $pop0{{$}}
102+
define i32 @add_i32_monotonic(i32* %p, i32 %v) {
103+
%old = atomicrmw add i32* %p, i32 %v monotonic
104+
ret i32 %old
105+
}
106+
107+
; CHECK-LABEL: add_i32_acquire:
108+
; CHECK-NEXT: .param i32, i32{{$}}
109+
; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
110+
; CHECK-NEXT: return $pop0{{$}}
111+
define i32 @add_i32_acquire(i32* %p, i32 %v) {
112+
%old = atomicrmw add i32* %p, i32 %v acquire
113+
ret i32 %old
114+
}
115+
116+
; CHECK-LABEL: add_i32_release:
117+
; CHECK-NEXT: .param i32, i32{{$}}
118+
; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
119+
; CHECK-NEXT: return $pop0{{$}}
120+
define i32 @add_i32_release(i32* %p, i32 %v) {
121+
%old = atomicrmw add i32* %p, i32 %v release
122+
ret i32 %old
123+
}
124+
125+
; CHECK-LABEL: add_i32_acq_rel:
126+
; CHECK-NEXT: .param i32, i32{{$}}
127+
; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
128+
; CHECK-NEXT: return $pop0{{$}}
129+
define i32 @add_i32_acq_rel(i32* %p, i32 %v) {
130+
%old = atomicrmw add i32* %p, i32 %v acq_rel
131+
ret i32 %old
132+
}
133+
134+
; CHECK-LABEL: add_i32_seq_cst:
135+
; CHECK-NEXT: .param i32, i32{{$}}
136+
; CHECK: i32.atomic.rmw.add $push0=, 0($0), $1{{$}}
137+
; CHECK-NEXT: return $pop0{{$}}
138+
define i32 @add_i32_seq_cst(i32* %p, i32 %v) {
139+
%old = atomicrmw add i32* %p, i32 %v seq_cst
140+
ret i32 %old
141+
}

0 commit comments

Comments
 (0)