Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll

Issue 2504253002: [Subzero][MIPS] Implements atomic intrinsics for MIPS32 (Closed)
Patch Set: Included lit tests and formated source code Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringMIPS32.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 ; This tests each of the supported NaCl atomic instructions for every 1 ; This tests each of the supported NaCl atomic instructions for every
2 ; size allowed. 2 ; size allowed.
3 3
4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ 4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \
5 ; RUN: -allow-externally-defined-symbols | FileCheck %s 5 ; RUN: -allow-externally-defined-symbols | FileCheck %s
6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ 6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \
7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s 7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s
8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \ 8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \
9 ; RUN: -allow-externally-defined-symbols | FileCheck %s 9 ; RUN: -allow-externally-defined-symbols | FileCheck %s
10 10
11 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \ 11 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
12 ; RUN: --target arm32 -i %s --args -O2 \ 12 ; RUN: --target arm32 -i %s --args -O2 \
13 ; RUN: -allow-externally-defined-symbols \ 13 ; RUN: -allow-externally-defined-symbols \
14 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \ 14 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
15 ; RUN: --check-prefix=ARM32 15 ; RUN: --check-prefix=ARM32
16 16
17 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \ 17 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
18 ; RUN: --target arm32 -i %s --args -O2 \ 18 ; RUN: --target arm32 -i %s --args -O2 \
19 ; RUN: -allow-externally-defined-symbols \ 19 ; RUN: -allow-externally-defined-symbols \
20 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \ 20 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
21 ; RUN: --check-prefix=ARM32O2 21 ; RUN: --check-prefix=ARM32O2
22 22
23 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \ 23 ; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
24 ; RUN: --target arm32 -i %s --args -Om1 \ 24 ; RUN: --target arm32 -i %s --args -Om1 \
25 ; RUN: -allow-externally-defined-symbols \ 25 ; RUN: -allow-externally-defined-symbols \
26 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \ 26 ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
27 ; RUN: --check-prefix=ARM32 27 ; RUN: --check-prefix=ARM32
28 28
29 ; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i --filetype=asm \
Jim Stichnoth 2016/11/18 20:15:15 80-col, here and below
30 ; RUN: --target mips32 -i %s --args -O2 \
31 ; RUN: -allow-externally-defined-symbols \
32 ; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \
33 ; RUN: --check-prefix=MIPS32O2 --check-prefix=MIPS32
34
35 ; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i --filetype=asm \
36 ; RUN: --target mips32 -i %s --args -Om1 \
37 ; RUN: -allow-externally-defined-symbols \
38 ; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \
39 ; RUN: --check-prefix=MIPS32OM1 --check-prefix=MIPS32
40
29 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) 41 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
30 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) 42 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
31 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) 43 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32)
32 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) 44 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
33 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32) 45 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32)
34 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32) 46 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32)
35 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) 47 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
36 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) 48 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
37 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) 49 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
38 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32) 50 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
(...skipping 30 matching lines...) Expand all
69 %i2 = sub i8 %i, 0 81 %i2 = sub i8 %i, 0
70 %r = zext i8 %i2 to i32 82 %r = zext i8 %i2 to i32
71 ret i32 %r 83 ret i32 %r
72 } 84 }
73 ; CHECK-LABEL: test_atomic_load_8 85 ; CHECK-LABEL: test_atomic_load_8
74 ; CHECK: mov {{.*}},DWORD 86 ; CHECK: mov {{.*}},DWORD
75 ; CHECK: mov {{.*}},BYTE 87 ; CHECK: mov {{.*}},BYTE
76 ; ARM32-LABEL: test_atomic_load_8 88 ; ARM32-LABEL: test_atomic_load_8
77 ; ARM32: ldrb r{{[0-9]+}}, [r{{[0-9]+}} 89 ; ARM32: ldrb r{{[0-9]+}}, [r{{[0-9]+}}
78 ; ARM32: dmb 90 ; ARM32: dmb
91 ; MIPS32-LABEL: test_atomic_load_8
92 ; MIPS32: lb
93 ; MIPS32: sync
79 94
80 define internal i32 @test_atomic_load_16(i32 %iptr) { 95 define internal i32 @test_atomic_load_16(i32 %iptr) {
81 entry: 96 entry:
82 %ptr = inttoptr i32 %iptr to i16* 97 %ptr = inttoptr i32 %iptr to i16*
83 %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6) 98 %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6)
84 %i2 = sub i16 %i, 0 99 %i2 = sub i16 %i, 0
85 %r = zext i16 %i2 to i32 100 %r = zext i16 %i2 to i32
86 ret i32 %r 101 ret i32 %r
87 } 102 }
88 ; CHECK-LABEL: test_atomic_load_16 103 ; CHECK-LABEL: test_atomic_load_16
89 ; CHECK: mov {{.*}},DWORD 104 ; CHECK: mov {{.*}},DWORD
90 ; CHECK: mov {{.*}},WORD 105 ; CHECK: mov {{.*}},WORD
91 ; ARM32-LABEL: test_atomic_load_16 106 ; ARM32-LABEL: test_atomic_load_16
92 ; ARM32: ldrh r{{[0-9]+}}, [r{{[0-9]+}} 107 ; ARM32: ldrh r{{[0-9]+}}, [r{{[0-9]+}}
93 ; ARM32: dmb 108 ; ARM32: dmb
109 ; MIPS32-LABEL: test_atomic_load_16
110 ; MIPS32: lh
111 ; MIPS32: sync
94 112
95 define internal i32 @test_atomic_load_32(i32 %iptr) { 113 define internal i32 @test_atomic_load_32(i32 %iptr) {
96 entry: 114 entry:
97 %ptr = inttoptr i32 %iptr to i32* 115 %ptr = inttoptr i32 %iptr to i32*
98 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6) 116 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
99 ret i32 %r 117 ret i32 %r
100 } 118 }
101 ; CHECK-LABEL: test_atomic_load_32 119 ; CHECK-LABEL: test_atomic_load_32
102 ; CHECK: mov {{.*}},DWORD 120 ; CHECK: mov {{.*}},DWORD
103 ; CHECK: mov {{.*}},DWORD 121 ; CHECK: mov {{.*}},DWORD
104 ; ARM32-LABEL: test_atomic_load_32 122 ; ARM32-LABEL: test_atomic_load_32
105 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}} 123 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}}
106 ; ARM32: dmb 124 ; ARM32: dmb
125 ; MIPS32-LABEL: test_atomic_load_32
126 ; MIPS32: lw
127 ; MIPS32: sync
107 128
108 define internal i64 @test_atomic_load_64(i32 %iptr) { 129 define internal i64 @test_atomic_load_64(i32 %iptr) {
109 entry: 130 entry:
110 %ptr = inttoptr i32 %iptr to i64* 131 %ptr = inttoptr i32 %iptr to i64*
111 %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6) 132 %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
112 ret i64 %r 133 ret i64 %r
113 } 134 }
114 ; CHECK-LABEL: test_atomic_load_64 135 ; CHECK-LABEL: test_atomic_load_64
115 ; CHECK: movq x{{.*}},QWORD 136 ; CHECK: movq x{{.*}},QWORD
116 ; CHECK: movq QWORD {{.*}},x{{.*}} 137 ; CHECK: movq QWORD {{.*}},x{{.*}}
117 ; ARM32-LABEL: test_atomic_load_64 138 ; ARM32-LABEL: test_atomic_load_64
118 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}} 139 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}
119 ; ARM32: dmb 140 ; ARM32: dmb
141 ; MIPS32-LABEL: test_atomic_load_64
142 ; MIPS32: lw
143 ; MIPS32: lw
144 ; MIPS32: sync
120 145
121 define internal i32 @test_atomic_load_32_with_arith(i32 %iptr) { 146 define internal i32 @test_atomic_load_32_with_arith(i32 %iptr) {
122 entry: 147 entry:
123 br label %next 148 br label %next
124 149
125 next: 150 next:
126 %ptr = inttoptr i32 %iptr to i32* 151 %ptr = inttoptr i32 %iptr to i32*
127 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6) 152 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
128 %r2 = sub i32 32, %r 153 %r2 = sub i32 32, %r
129 ret i32 %r2 154 ret i32 %r2
130 } 155 }
131 ; CHECK-LABEL: test_atomic_load_32_with_arith 156 ; CHECK-LABEL: test_atomic_load_32_with_arith
132 ; CHECK: mov {{.*}},DWORD 157 ; CHECK: mov {{.*}},DWORD
133 ; The next instruction may be a separate load or folded into an add. 158 ; The next instruction may be a separate load or folded into an add.
134 ; 159 ;
135 ; In O2 mode, we know that the load and sub are going to be fused. 160 ; In O2 mode, we know that the load and sub are going to be fused.
136 ; O2-LABEL: test_atomic_load_32_with_arith 161 ; O2-LABEL: test_atomic_load_32_with_arith
137 ; O2: mov {{.*}},DWORD 162 ; O2: mov {{.*}},DWORD
138 ; O2: sub {{.*}},DWORD 163 ; O2: sub {{.*}},DWORD
139 ; ARM32-LABEL: test_atomic_load_32_with_arith 164 ; ARM32-LABEL: test_atomic_load_32_with_arith
140 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}} 165 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}}
141 ; ARM32: dmb 166 ; ARM32: dmb
167 ; MIPS32-LABEL: test_atomic_load_32_with_arith
168 ; MIPS32: lw
169 ; MIPS32: sync
142 170
143 define internal i32 @test_atomic_load_32_ignored(i32 %iptr) { 171 define internal i32 @test_atomic_load_32_ignored(i32 %iptr) {
144 entry: 172 entry:
145 %ptr = inttoptr i32 %iptr to i32* 173 %ptr = inttoptr i32 %iptr to i32*
146 %ignored = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6) 174 %ignored = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
147 ret i32 0 175 ret i32 0
148 } 176 }
149 ; CHECK-LABEL: test_atomic_load_32_ignored 177 ; CHECK-LABEL: test_atomic_load_32_ignored
150 ; CHECK: mov {{.*}},DWORD 178 ; CHECK: mov {{.*}},DWORD
151 ; CHECK: mov {{.*}},DWORD 179 ; CHECK: mov {{.*}},DWORD
152 ; O2-LABEL: test_atomic_load_32_ignored 180 ; O2-LABEL: test_atomic_load_32_ignored
153 ; O2: mov {{.*}},DWORD 181 ; O2: mov {{.*}},DWORD
154 ; O2: mov {{.*}},DWORD 182 ; O2: mov {{.*}},DWORD
155 ; ARM32-LABEL: test_atomic_load_32_ignored 183 ; ARM32-LABEL: test_atomic_load_32_ignored
156 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}} 184 ; ARM32: ldr r{{[0-9]+}}, [r{{[0-9]+}}
157 ; ARM32: dmb 185 ; ARM32: dmb
186 ; MIPS32-LABEL: test_atomic_load_32_ignored
187 ; MIPS32: lw
188 ; MIPS32: sync
158 189
159 define internal i64 @test_atomic_load_64_ignored(i32 %iptr) { 190 define internal i64 @test_atomic_load_64_ignored(i32 %iptr) {
160 entry: 191 entry:
161 %ptr = inttoptr i32 %iptr to i64* 192 %ptr = inttoptr i32 %iptr to i64*
162 %ignored = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6) 193 %ignored = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
163 ret i64 0 194 ret i64 0
164 } 195 }
165 ; CHECK-LABEL: test_atomic_load_64_ignored 196 ; CHECK-LABEL: test_atomic_load_64_ignored
166 ; CHECK: movq x{{.*}},QWORD 197 ; CHECK: movq x{{.*}},QWORD
167 ; CHECK: movq QWORD {{.*}},x{{.*}} 198 ; CHECK: movq QWORD {{.*}},x{{.*}}
168 ; ARM32-LABEL: test_atomic_load_64_ignored 199 ; ARM32-LABEL: test_atomic_load_64_ignored
169 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}} 200 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}
170 ; ARM32: dmb 201 ; ARM32: dmb
202 ; MIPS32-LABEL: test_atomic_load_64_ignored
203 ; MIPS32: lw
204 ; MIPS32: lw
205 ; MIPS32: sync
171 206
172 ;;; Store 207 ;;; Store
173 208
174 define internal void @test_atomic_store_8(i32 %iptr, i32 %v) { 209 define internal void @test_atomic_store_8(i32 %iptr, i32 %v) {
175 entry: 210 entry:
176 %truncv = trunc i32 %v to i8 211 %truncv = trunc i32 %v to i8
177 %ptr = inttoptr i32 %iptr to i8* 212 %ptr = inttoptr i32 %iptr to i8*
178 call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6) 213 call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6)
179 ret void 214 ret void
180 } 215 }
181 ; CHECK-LABEL: test_atomic_store_8 216 ; CHECK-LABEL: test_atomic_store_8
182 ; CHECK: mov BYTE 217 ; CHECK: mov BYTE
183 ; CHECK: mfence 218 ; CHECK: mfence
184 ; ARM32-LABEL: test_atomic_store_8 219 ; ARM32-LABEL: test_atomic_store_8
185 ; ARM32: dmb 220 ; ARM32: dmb
186 ; ARM32: strb r{{[0-9]+}}, [r{{[0-9]+}} 221 ; ARM32: strb r{{[0-9]+}}, [r{{[0-9]+}}
187 ; ARM32: dmb 222 ; ARM32: dmb
223 ; MIPS32-LABEL: test_atomic_store_8
224 ; MIPS32: sync
225 ; MIPS32: sb
226 ; MIPS32: sync
188 227
189 define internal void @test_atomic_store_16(i32 %iptr, i32 %v) { 228 define internal void @test_atomic_store_16(i32 %iptr, i32 %v) {
190 entry: 229 entry:
191 %truncv = trunc i32 %v to i16 230 %truncv = trunc i32 %v to i16
192 %ptr = inttoptr i32 %iptr to i16* 231 %ptr = inttoptr i32 %iptr to i16*
193 call void @llvm.nacl.atomic.store.i16(i16 %truncv, i16* %ptr, i32 6) 232 call void @llvm.nacl.atomic.store.i16(i16 %truncv, i16* %ptr, i32 6)
194 ret void 233 ret void
195 } 234 }
196 ; CHECK-LABEL: test_atomic_store_16 235 ; CHECK-LABEL: test_atomic_store_16
197 ; CHECK: mov WORD 236 ; CHECK: mov WORD
198 ; CHECK: mfence 237 ; CHECK: mfence
199 ; ARM32-LABEL: test_atomic_store_16 238 ; ARM32-LABEL: test_atomic_store_16
200 ; ARM32: dmb 239 ; ARM32: dmb
201 ; ARM32: strh r{{[0-9]+}}, [r{{[0-9]+}} 240 ; ARM32: strh r{{[0-9]+}}, [r{{[0-9]+}}
202 ; ARM32: dmb 241 ; ARM32: dmb
242 ; MIPS32-LABEL: test_atomic_store_16
243 ; MIPS32: sync
244 ; MIPS32: sh
245 ; MIPS32: sync
203 246
204 define internal void @test_atomic_store_32(i32 %iptr, i32 %v) { 247 define internal void @test_atomic_store_32(i32 %iptr, i32 %v) {
205 entry: 248 entry:
206 %ptr = inttoptr i32 %iptr to i32* 249 %ptr = inttoptr i32 %iptr to i32*
207 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6) 250 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6)
208 ret void 251 ret void
209 } 252 }
210 ; CHECK-LABEL: test_atomic_store_32 253 ; CHECK-LABEL: test_atomic_store_32
211 ; CHECK: mov DWORD 254 ; CHECK: mov DWORD
212 ; CHECK: mfence 255 ; CHECK: mfence
213 ; ARM32-LABEL: test_atomic_store_32 256 ; ARM32-LABEL: test_atomic_store_32
214 ; ARM32: dmb 257 ; ARM32: dmb
215 ; ARM32: str r{{[0-9]+}}, [r{{[0-9]+}} 258 ; ARM32: str r{{[0-9]+}}, [r{{[0-9]+}}
216 ; ARM32: dmb 259 ; ARM32: dmb
260 ; MIPS32-LABEL: test_atomic_store_32
261 ; MIPS32: sync
262 ; MIPS32: sw
263 ; MIPS32: sync
217 264
218 define internal void @test_atomic_store_64(i32 %iptr, i64 %v) { 265 define internal void @test_atomic_store_64(i32 %iptr, i64 %v) {
219 entry: 266 entry:
220 %ptr = inttoptr i32 %iptr to i64* 267 %ptr = inttoptr i32 %iptr to i64*
221 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6) 268 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6)
222 ret void 269 ret void
223 } 270 }
224 ; CHECK-LABEL: test_atomic_store_64 271 ; CHECK-LABEL: test_atomic_store_64
225 ; CHECK: movq x{{.*}},QWORD 272 ; CHECK: movq x{{.*}},QWORD
226 ; CHECK: movq QWORD {{.*}},x{{.*}} 273 ; CHECK: movq QWORD {{.*}},x{{.*}}
227 ; CHECK: mfence 274 ; CHECK: mfence
228 ; ARM32-LABEL: test_atomic_store_64 275 ; ARM32-LABEL: test_atomic_store_64
229 ; ARM32: dmb 276 ; ARM32: dmb
230 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] 277 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]]
231 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] 278 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]]
232 ; ARM32: cmp [[S]], #0 279 ; ARM32: cmp [[S]], #0
233 ; ARM32: bne 280 ; ARM32: bne
234 ; ARM32: dmb 281 ; ARM32: dmb
282 ; MIPS32-LABEL: test_atomic_store_64
283 ; MIPS32: sync
284 ; MIPS32: sw
285 ; MIPS32: sw
286 ; MIPS32: sync
235 287
236 define internal void @test_atomic_store_64_const(i32 %iptr) { 288 define internal void @test_atomic_store_64_const(i32 %iptr) {
237 entry: 289 entry:
238 %ptr = inttoptr i32 %iptr to i64* 290 %ptr = inttoptr i32 %iptr to i64*
239 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) 291 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6)
240 ret void 292 ret void
241 } 293 }
242 ; CHECK-LABEL: test_atomic_store_64_const 294 ; CHECK-LABEL: test_atomic_store_64_const
243 ; CHECK: mov {{.*}},0x73ce2ff2 295 ; CHECK: mov {{.*}},0x73ce2ff2
244 ; CHECK: mov {{.*}},0xb3a 296 ; CHECK: mov {{.*}},0xb3a
245 ; CHECK: movq x{{.*}},QWORD 297 ; CHECK: movq x{{.*}},QWORD
246 ; CHECK: movq QWORD {{.*}},x{{.*}} 298 ; CHECK: movq QWORD {{.*}},x{{.*}}
247 ; CHECK: mfence 299 ; CHECK: mfence
248 ; ARM32-LABEL: test_atomic_store_64_const 300 ; ARM32-LABEL: test_atomic_store_64_const
249 ; ARM32: movw [[T0:r[0-9]+]], #12274 301 ; ARM32: movw [[T0:r[0-9]+]], #12274
250 ; ARM32: movt [[T0]], #29646 302 ; ARM32: movt [[T0]], #29646
251 ; ARM32: movw r{{[0-9]+}}, #2874 303 ; ARM32: movw r{{[0-9]+}}, #2874
252 ; ARM32: dmb 304 ; ARM32: dmb
253 ; ARM32: .L[[RETRY:.*]]: 305 ; ARM32: .L[[RETRY:.*]]:
254 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] 306 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]]
255 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] 307 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]]
256 ; ARM32: cmp [[S]], #0 308 ; ARM32: cmp [[S]], #0
257 ; ARM32: bne .L[[RETRY]] 309 ; ARM32: bne .L[[RETRY]]
258 ; ARM32: dmb 310 ; ARM32: dmb
311 ; MIPS32-LABEL: test_atomic_store_64_const
312 ; MIPS32: sync
313 ; MIPS32: lui {{.*}}, 29646
314 ; MIPS32: ori {{.*}},{{.*}}, 12274
315 ; MIPS32: addiu {{.*}}, $zero, 2874
316 ; MIPS32: sw
317 ; MIPS32: sw
318 ; MIPS32: sync
259 319
260 ;;; RMW 320 ;;; RMW
261 321
262 ;; add 322 ;; add
263 323
264 define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) { 324 define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) {
265 entry: 325 entry:
266 %trunc = trunc i32 %v to i8 326 %trunc = trunc i32 %v to i8
267 %ptr = inttoptr i32 %iptr to i8* 327 %ptr = inttoptr i32 %iptr to i8*
268 ; "1" is an atomic add, and "6" is sequential consistency. 328 ; "1" is an atomic add, and "6" is sequential consistency.
269 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6) 329 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6)
270 %a_ext = zext i8 %a to i32 330 %a_ext = zext i8 %a to i32
271 ret i32 %a_ext 331 ret i32 %a_ext
272 } 332 }
273 ; CHECK-LABEL: test_atomic_rmw_add_8 333 ; CHECK-LABEL: test_atomic_rmw_add_8
274 ; CHECK: lock xadd BYTE {{.*}},[[REG:.*]] 334 ; CHECK: lock xadd BYTE {{.*}},[[REG:.*]]
275 ; CHECK: {{mov|movzx}} {{.*}},[[REG]] 335 ; CHECK: {{mov|movzx}} {{.*}},[[REG]]
276 ; ARM32-LABEL: test_atomic_rmw_add_8 336 ; ARM32-LABEL: test_atomic_rmw_add_8
277 ; ARM32: dmb 337 ; ARM32: dmb
278 ; ARM32: ldrexb 338 ; ARM32: ldrexb
279 ; ARM32: add 339 ; ARM32: add
280 ; ARM32: strexb 340 ; ARM32: strexb
281 ; ARM32: bne 341 ; ARM32: bne
282 ; ARM32: dmb 342 ; ARM32: dmb
343 ; MIPS32-LABEL: test_atomic_rmw_add_8
344 ; MIPS32: sync
345 ; MIPS32: addiu {{.*}}, $zero, -4
346 ; MIPS32: and
347 ; MIPS32: andi {{.*}}, {{.*}}, 3
348 ; MIPS32: sll {{.*}}, {{.*}}, 3
349 ; MIPS32: ori {{.*}}, $zero, 255
350 ; MIPS32: sllv
351 ; MIPS32: nor
352 ; MIPS32: sllv
353 ; MIPS32: ll
354 ; MIPS32: addu
355 ; MIPS32: and
356 ; MIPS32: and
357 ; MIPS32: or
358 ; MIPS32: sc
359 ; MIPS32: beq {{.*}}, $zero, {{.*}}
360 ; MIPS32: and
361 ; MIPS32: srlv
362 ; MIPS32: sll {{.*}}, {{.*}}, 24
363 ; MIPS32: sra {{.*}}, {{.*}}, 24
364 ; MIPS32: sync
283 365
284 define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) { 366 define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) {
285 entry: 367 entry:
286 %trunc = trunc i32 %v to i16 368 %trunc = trunc i32 %v to i16
287 %ptr = inttoptr i32 %iptr to i16* 369 %ptr = inttoptr i32 %iptr to i16*
288 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6) 370 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6)
289 %a_ext = zext i16 %a to i32 371 %a_ext = zext i16 %a to i32
290 ret i32 %a_ext 372 ret i32 %a_ext
291 } 373 }
292 ; CHECK-LABEL: test_atomic_rmw_add_16 374 ; CHECK-LABEL: test_atomic_rmw_add_16
293 ; CHECK: lock xadd WORD {{.*}},[[REG:.*]] 375 ; CHECK: lock xadd WORD {{.*}},[[REG:.*]]
294 ; CHECK: {{mov|movzx}} {{.*}},[[REG]] 376 ; CHECK: {{mov|movzx}} {{.*}},[[REG]]
295 ; ARM32-LABEL: test_atomic_rmw_add_16 377 ; ARM32-LABEL: test_atomic_rmw_add_16
296 ; ARM32: dmb 378 ; ARM32: dmb
297 ; ARM32: ldrexh 379 ; ARM32: ldrexh
298 ; ARM32: add 380 ; ARM32: add
299 ; ARM32: strexh 381 ; ARM32: strexh
300 ; ARM32: bne 382 ; ARM32: bne
301 ; ARM32: dmb 383 ; ARM32: dmb
384 ; MIPS32-LABEL: test_atomic_rmw_add_16
385 ; MIPS32: sync
386 ; MIPS32: addiu {{.*}}, $zero, -4
387 ; MIPS32: and
388 ; MIPS32: andi {{.*}}, {{.*}}, 3
389 ; MIPS32: sll {{.*}}, {{.*}}, 3
390 ; MIPS32: ori {{.*}}, {{.*}}, 65535
391 ; MIPS32: sllv
392 ; MIPS32: nor
393 ; MIPS32: sllv
394 ; MIPS32: ll
395 ; MIPS32: addu
396 ; MIPS32: and
397 ; MIPS32: and
398 ; MIPS32: or
399 ; MIPS32: sc
400 ; MIPS32: beq {{.*}}, $zero, {{.*}}
401 ; MIPS32: and
402 ; MIPS32: srlv
403 ; MIPS32: sll {{.*}}, {{.*}}, 16
404 ; MIPS32: sra {{.*}}, {{.*}}, 16
405 ; MIPS32: sync
302 406
303 define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) { 407 define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) {
304 entry: 408 entry:
305 %ptr = inttoptr i32 %iptr to i32* 409 %ptr = inttoptr i32 %iptr to i32*
306 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) 410 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
307 ret i32 %a 411 ret i32 %a
308 } 412 }
309 ; CHECK-LABEL: test_atomic_rmw_add_32 413 ; CHECK-LABEL: test_atomic_rmw_add_32
310 ; CHECK: lock xadd DWORD {{.*}},[[REG:.*]] 414 ; CHECK: lock xadd DWORD {{.*}},[[REG:.*]]
311 ; CHECK: mov {{.*}},[[REG]] 415 ; CHECK: mov {{.*}},[[REG]]
312 ; ARM32-LABEL: test_atomic_rmw_add_32 416 ; ARM32-LABEL: test_atomic_rmw_add_32
313 ; ARM32: dmb 417 ; ARM32: dmb
314 ; ARM32: ldrex 418 ; ARM32: ldrex
315 ; ARM32: add 419 ; ARM32: add
316 ; ARM32: strex 420 ; ARM32: strex
317 ; ARM32: bne 421 ; ARM32: bne
318 ; ARM32: dmb 422 ; ARM32: dmb
423 ; MIPS32-LABEL: test_atomic_rmw_add_32
424 ; MIPS32: sync
425 ; MIPS32: ll
426 ; MIPS32: addu
427 ; MIPS32: sc
428 ; MIPS32: beq {{.*}}, $zero, {{.*}}
429 ; MIPS32: sync
319 430
320 define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) { 431 define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) {
321 entry: 432 entry:
322 %ptr = inttoptr i32 %iptr to i64* 433 %ptr = inttoptr i32 %iptr to i64*
323 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) 434 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6)
324 ret i64 %a 435 ret i64 %a
325 } 436 }
326 ; CHECK-LABEL: test_atomic_rmw_add_64 437 ; CHECK-LABEL: test_atomic_rmw_add_64
327 ; CHECK: push ebx 438 ; CHECK: push ebx
328 ; CHECK: mov eax,DWORD PTR [{{.*}}] 439 ; CHECK: mov eax,DWORD PTR [{{.*}}]
(...skipping 10 matching lines...) Expand all
339 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} 450 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}
340 ; CHECK: jne [[LABEL]] 451 ; CHECK: jne [[LABEL]]
341 ; ARM32-LABEL: test_atomic_rmw_add_64 452 ; ARM32-LABEL: test_atomic_rmw_add_64
342 ; ARM32: dmb 453 ; ARM32: dmb
343 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 454 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
344 ; ARM32: adds 455 ; ARM32: adds
345 ; ARM32: adc 456 ; ARM32: adc
346 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 457 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
347 ; ARM32: bne 458 ; ARM32: bne
348 ; ARM32: dmb 459 ; ARM32: dmb
460 ; MIPS32-LABEL: test_atomic_rmw_add_64
461 ; MIPS32: sync
462 ; MIPS32: ll
463 ; MIPS32: addu
464 ; MIPS32: sltu
465 ; MIPS32: sc
466 ; MIPS32: beq {{.*}}, $zero, {{.*}}
467 ; MIPS32: ll
468 ; MIPS32: addu
469 ; MIPS32: addu
470 ; MIPS32: sc
471 ; MIPS32: beq {{.*}}, $zero, {{.*}}
472 ; MIPS32: sync
349 473
350 ; Same test as above, but with a global address to test FakeUse issues. 474 ; Same test as above, but with a global address to test FakeUse issues.
351 define internal i64 @test_atomic_rmw_add_64_global(i64 %v) { 475 define internal i64 @test_atomic_rmw_add_64_global(i64 %v) {
352 entry: 476 entry:
353 %ptr = bitcast [8 x i8]* @SzGlobal64 to i64* 477 %ptr = bitcast [8 x i8]* @SzGlobal64 to i64*
354 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) 478 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6)
355 ret i64 %a 479 ret i64 %a
356 } 480 }
357 ; CHECK-LABEL: test_atomic_rmw_add_64_global 481 ; CHECK-LABEL: test_atomic_rmw_add_64_global
358 ; ARM32-LABEL: test_atomic_rmw_add_64_global 482 ; ARM32-LABEL: test_atomic_rmw_add_64_global
359 ; ARM32: dmb 483 ; ARM32: dmb
360 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 484 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
361 ; ARM32: adds 485 ; ARM32: adds
362 ; ARM32: adc 486 ; ARM32: adc
363 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 487 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
364 ; ARM32: bne 488 ; ARM32: bne
365 ; ARM32: dmb 489 ; ARM32: dmb
490 ; MIPS32-LABEL: test_atomic_rmw_add_64_global
491 ; MIPS32: sync
492 ; MIPS32: ll
493 ; MIPS32: addu
494 ; MIPS32: sltu
495 ; MIPS32: sc
496 ; MIPS32: beq {{.*}}, $zero, {{.*}}
497 ; MIPS32: ll
498 ; MIPS32: addu
499 ; MIPS32: addu
500 ; MIPS32: sc
501 ; MIPS32: beq {{.*}}, $zero, {{.*}}
502 ; MIPS32: sync
366 503
367 ; Test with some more register pressure. When we have an alloca, ebp is 504 ; Test with some more register pressure. When we have an alloca, ebp is
368 ; used to manage the stack frame, so it cannot be used as a register either. 505 ; used to manage the stack frame, so it cannot be used as a register either.
369 declare void @use_ptr(i32 %iptr) 506 declare void @use_ptr(i32 %iptr)
370 507
371 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) { 508 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) {
372 entry: 509 entry:
373 br label %eblock ; Disable alloca optimization 510 br label %eblock ; Disable alloca optimization
374 eblock: 511 eblock:
375 %alloca_ptr = alloca i8, i32 16, align 16 512 %alloca_ptr = alloca i8, i32 16, align 16
(...skipping 21 matching lines...) Expand all
397 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] 534 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i]
398 ; CHECK: call {{.*}} R_{{.*}} use_ptr 535 ; CHECK: call {{.*}} R_{{.*}} use_ptr
399 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca 536 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca
400 ; ARM32: dmb 537 ; ARM32: dmb
401 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 538 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
402 ; ARM32: adds 539 ; ARM32: adds
403 ; ARM32: adc 540 ; ARM32: adc
404 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 541 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
405 ; ARM32: bne 542 ; ARM32: bne
406 ; ARM32: dmb 543 ; ARM32: dmb
544 ; MIPS32-LABEL: test_atomic_rmw_add_64_alloca
545 ; MIPS32: sync
546 ; MIPS32: ll
547 ; MIPS32: addu
548 ; MIPS32: sltu
549 ; MIPS32: sc
550 ; MIPS32: beq {{.*}}, $zero, {{.*}}
551 ; MIPS32: ll
552 ; MIPS32: addu
553 ; MIPS32: addu
554 ; MIPS32: sc
555 ; MIPS32: beq {{.*}}, $zero, {{.*}}
556 ; MIPS32: sync
407 557
408 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) { 558 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) {
409 entry: 559 entry:
410 %ptr = inttoptr i32 %iptr to i32* 560 %ptr = inttoptr i32 %iptr to i32*
411 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) 561 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
412 ret i32 %v 562 ret i32 %v
413 } 563 }
414 ; Technically this could use "lock add" instead of "lock xadd", if liveness 564 ; Technically this could use "lock add" instead of "lock xadd", if liveness
415 ; tells us that the destination variable is dead. 565 ; tells us that the destination variable is dead.
416 ; CHECK-LABEL: test_atomic_rmw_add_32_ignored 566 ; CHECK-LABEL: test_atomic_rmw_add_32_ignored
417 ; CHECK: lock xadd DWORD {{.*}},[[REG:.*]] 567 ; CHECK: lock xadd DWORD {{.*}},[[REG:.*]]
418 ; ARM32-LABEL: test_atomic_rmw_add_32_ignored 568 ; ARM32-LABEL: test_atomic_rmw_add_32_ignored
419 ; ARM32: dmb 569 ; ARM32: dmb
420 ; ARM32: ldrex 570 ; ARM32: ldrex
421 ; ARM32: add 571 ; ARM32: add
422 ; ARM32: strex 572 ; ARM32: strex
423 ; ARM32: bne 573 ; ARM32: bne
424 ; ARM32: dmb 574 ; ARM32: dmb
575 ; MIPS32-LABEL: test_atomic_rmw_add_32_ignored
576 ; MIPS32: sync
577 ; MIPS32: ll
578 ; MIPS32: addu
579 ; MIPS32: sc
580 ; MIPS32: beq {{.*}}, $zero, {{.*}}
581 ; MIPS32: sync
425 582
426 ; Atomic RMW 64 needs to be expanded into its own loop. 583 ; Atomic RMW 64 needs to be expanded into its own loop.
427 ; Make sure that works w/ non-trivial function bodies. 584 ; Make sure that works w/ non-trivial function bodies.
428 define internal i64 @test_atomic_rmw_add_64_loop(i32 %iptr, i64 %v) { 585 define internal i64 @test_atomic_rmw_add_64_loop(i32 %iptr, i64 %v) {
429 entry: 586 entry:
430 %x = icmp ult i64 %v, 100 587 %x = icmp ult i64 %v, 100
431 br i1 %x, label %err, label %loop 588 br i1 %x, label %err, label %loop
432 589
433 loop: 590 loop:
434 %v_next = phi i64 [ %v, %entry ], [ %next, %loop ] 591 %v_next = phi i64 [ %v, %entry ], [ %next, %loop ]
(...skipping 20 matching lines...) Expand all
455 ; CHECK: jne [[LABEL]] 612 ; CHECK: jne [[LABEL]]
456 ; ARM32-LABEL: test_atomic_rmw_add_64_loop 613 ; ARM32-LABEL: test_atomic_rmw_add_64_loop
457 ; ARM32: dmb 614 ; ARM32: dmb
458 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 615 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
459 ; ARM32: adds 616 ; ARM32: adds
460 ; ARM32: adc 617 ; ARM32: adc
461 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 618 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
462 ; ARM32: bne 619 ; ARM32: bne
463 ; ARM32: dmb 620 ; ARM32: dmb
464 ; ARM32: b 621 ; ARM32: b
622 ; MIPS32-LABEL: test_atomic_rmw_add_64_loop
623 ; MIPS32: sync
624 ; MIPS32: ll
625 ; MIPS32: addu
626 ; MIPS32: sltu
627 ; MIPS32: sc
628 ; MIPS32: beq {{.*}}, $zero, {{.*}}
629 ; MIPS32: ll
630 ; MIPS32: addu
631 ; MIPS32: addu
632 ; MIPS32: sc
633 ; MIPS32: beq {{.*}}, $zero, {{.*}}
634 ; MIPS32: sync
465 635
466 ;; sub 636 ;; sub
467 637
468 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { 638 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) {
469 entry: 639 entry:
470 %trunc = trunc i32 %v to i8 640 %trunc = trunc i32 %v to i8
471 %ptr = inttoptr i32 %iptr to i8* 641 %ptr = inttoptr i32 %iptr to i8*
472 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i8* %ptr, i8 %trunc, i32 6) 642 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i8* %ptr, i8 %trunc, i32 6)
473 %a_ext = zext i8 %a to i32 643 %a_ext = zext i8 %a to i32
474 ret i32 %a_ext 644 ret i32 %a_ext
475 } 645 }
476 ; CHECK-LABEL: test_atomic_rmw_sub_8 646 ; CHECK-LABEL: test_atomic_rmw_sub_8
477 ; CHECK: neg [[REG:.*]] 647 ; CHECK: neg [[REG:.*]]
478 ; CHECK: lock xadd BYTE {{.*}},[[REG]] 648 ; CHECK: lock xadd BYTE {{.*}},[[REG]]
479 ; CHECK: {{mov|movzx}} {{.*}},[[REG]] 649 ; CHECK: {{mov|movzx}} {{.*}},[[REG]]
480 ; ARM32-LABEL: test_atomic_rmw_sub_8 650 ; ARM32-LABEL: test_atomic_rmw_sub_8
481 ; ARM32: dmb 651 ; ARM32: dmb
482 ; ARM32: ldrexb 652 ; ARM32: ldrexb
483 ; ARM32: sub 653 ; ARM32: sub
484 ; ARM32: strexb 654 ; ARM32: strexb
485 ; ARM32: bne 655 ; ARM32: bne
486 ; ARM32: dmb 656 ; ARM32: dmb
657 ; MIPS32-LABEL: test_atomic_rmw_sub_8
658 ; MIPS32: sync
659 ; MIPS32: addiu {{.*}}, $zero, -4
660 ; MIPS32: and
661 ; MIPS32: andi {{.*}}, {{.*}}, 3
662 ; MIPS32: sll {{.*}}, {{.*}}, 3
663 ; MIPS32: ori {{.*}}, $zero, 255
664 ; MIPS32: sllv
665 ; MIPS32: nor
666 ; MIPS32: sllv
667 ; MIPS32: ll
668 ; MIPS32: subu
669 ; MIPS32: and
670 ; MIPS32: and
671 ; MIPS32: or
672 ; MIPS32: sc
673 ; MIPS32: beq {{.*}}, $zero, {{.*}}
674 ; MIPS32: and
675 ; MIPS32: srlv
676 ; MIPS32: sll {{.*}}, {{.*}}, 24
677 ; MIPS32: sra {{.*}}, {{.*}}, 24
678 ; MIPS32: sync
487 679
488 define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) { 680 define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) {
489 entry: 681 entry:
490 %trunc = trunc i32 %v to i16 682 %trunc = trunc i32 %v to i16
491 %ptr = inttoptr i32 %iptr to i16* 683 %ptr = inttoptr i32 %iptr to i16*
492 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i16* %ptr, i16 %trunc, i32 6) 684 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i16* %ptr, i16 %trunc, i32 6)
493 %a_ext = zext i16 %a to i32 685 %a_ext = zext i16 %a to i32
494 ret i32 %a_ext 686 ret i32 %a_ext
495 } 687 }
496 ; CHECK-LABEL: test_atomic_rmw_sub_16 688 ; CHECK-LABEL: test_atomic_rmw_sub_16
497 ; CHECK: neg [[REG:.*]] 689 ; CHECK: neg [[REG:.*]]
498 ; CHECK: lock xadd WORD {{.*}},[[REG]] 690 ; CHECK: lock xadd WORD {{.*}},[[REG]]
499 ; CHECK: {{mov|movzx}} {{.*}},[[REG]] 691 ; CHECK: {{mov|movzx}} {{.*}},[[REG]]
500 ; ARM32-LABEL: test_atomic_rmw_sub_16 692 ; ARM32-LABEL: test_atomic_rmw_sub_16
501 ; ARM32: dmb 693 ; ARM32: dmb
502 ; ARM32: ldrexh 694 ; ARM32: ldrexh
503 ; ARM32: sub 695 ; ARM32: sub
504 ; ARM32: strexh 696 ; ARM32: strexh
505 ; ARM32: bne 697 ; ARM32: bne
506 ; ARM32: dmb 698 ; ARM32: dmb
699 ; MIPS32-LABEL: test_atomic_rmw_sub_16
700 ; MIPS32: sync
701 ; MIPS32: addiu {{.*}}, $zero, -4
702 ; MIPS32: and
703 ; MIPS32: andi {{.*}}, {{.*}}, 3
704 ; MIPS32: sll {{.*}}, {{.*}}, 3
705 ; MIPS32: ori {{.*}}, {{.*}}, 65535
706 ; MIPS32: sllv
707 ; MIPS32: nor
708 ; MIPS32: sllv
709 ; MIPS32: ll
710 ; MIPS32: subu
711 ; MIPS32: and
712 ; MIPS32: and
713 ; MIPS32: or
714 ; MIPS32: sc
715 ; MIPS32: beq {{.*}}, $zero, {{.*}}
716 ; MIPS32: and
717 ; MIPS32: srlv
718 ; MIPS32: sll {{.*}}, {{.*}}, 16
719 ; MIPS32: sra {{.*}}, {{.*}}, 16
720 ; MIPS32: sync
507 721
508 define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) { 722 define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) {
509 entry: 723 entry:
510 %ptr = inttoptr i32 %iptr to i32* 724 %ptr = inttoptr i32 %iptr to i32*
511 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) 725 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6)
512 ret i32 %a 726 ret i32 %a
513 } 727 }
514 ; CHECK-LABEL: test_atomic_rmw_sub_32 728 ; CHECK-LABEL: test_atomic_rmw_sub_32
515 ; CHECK: neg [[REG:.*]] 729 ; CHECK: neg [[REG:.*]]
516 ; CHECK: lock xadd DWORD {{.*}},[[REG]] 730 ; CHECK: lock xadd DWORD {{.*}},[[REG]]
517 ; CHECK: mov {{.*}},[[REG]] 731 ; CHECK: mov {{.*}},[[REG]]
518 ; ARM32-LABEL: test_atomic_rmw_sub_32 732 ; ARM32-LABEL: test_atomic_rmw_sub_32
519 ; ARM32: dmb 733 ; ARM32: dmb
520 ; ARM32: ldrex 734 ; ARM32: ldrex
521 ; ARM32: sub 735 ; ARM32: sub
522 ; ARM32: strex 736 ; ARM32: strex
523 ; ARM32: bne 737 ; ARM32: bne
524 ; ARM32: dmb 738 ; ARM32: dmb
739 ; MIPS32-LABEL: test_atomic_rmw_sub_32
740 ; MIPS32: sync
741 ; MIPS32: ll
742 ; MIPS32: subu
743 ; MIPS32: sc
744 ; MIPS32: beq {{.*}}, $zero, {{.*}}
745 ; MIPS32: sync
525 746
526 define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) { 747 define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) {
527 entry: 748 entry:
528 %ptr = inttoptr i32 %iptr to i64* 749 %ptr = inttoptr i32 %iptr to i64*
529 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i64* %ptr, i64 %v, i32 6) 750 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i64* %ptr, i64 %v, i32 6)
530 ret i64 %a 751 ret i64 %a
531 } 752 }
532 ; CHECK-LABEL: test_atomic_rmw_sub_64 753 ; CHECK-LABEL: test_atomic_rmw_sub_64
533 ; CHECK: push ebx 754 ; CHECK: push ebx
534 ; CHECK: mov eax,DWORD PTR [{{.*}}] 755 ; CHECK: mov eax,DWORD PTR [{{.*}}]
535 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] 756 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4]
536 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax 757 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax
537 ; CHECK: sub ebx,{{.*e.[^x]}} 758 ; CHECK: sub ebx,{{.*e.[^x]}}
538 ; CHECK: mov ecx,edx 759 ; CHECK: mov ecx,edx
539 ; CHECK: sbb ecx,{{.*e.[^x]}} 760 ; CHECK: sbb ecx,{{.*e.[^x]}}
540 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} 761 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}
541 ; CHECK: jne [[LABEL]] 762 ; CHECK: jne [[LABEL]]
542 ; ARM32-LABEL: test_atomic_rmw_sub_64 763 ; ARM32-LABEL: test_atomic_rmw_sub_64
543 ; ARM32: dmb 764 ; ARM32: dmb
544 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 765 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
545 ; ARM32: subs 766 ; ARM32: subs
546 ; ARM32: sbc 767 ; ARM32: sbc
547 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 768 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
548 ; ARM32: bne 769 ; ARM32: bne
549 ; ARM32: dmb 770 ; ARM32: dmb
771 ; MIPS32-LABEL: test_atomic_rmw_sub_64
772 ; MIPS32: sync
773 ; MIPS32: ll
774 ; MIPS32: subu
775 ; MIPS32: sltu
776 ; MIPS32: sc
777 ; MIPS32: beq {{.*}}, $zero, {{.*}}
778 ; MIPS32: ll
779 ; MIPS32: addu
780 ; MIPS32: subu
781 ; MIPS32: sc
782 ; MIPS32: beq {{.*}}, $zero, {{.*}}
783 ; MIPS32: sync
550 784
551 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) { 785 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) {
552 entry: 786 entry:
553 %ptr = inttoptr i32 %iptr to i32* 787 %ptr = inttoptr i32 %iptr to i32*
554 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) 788 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6)
555 ret i32 %v 789 ret i32 %v
556 } 790 }
557 ; Could use "lock sub" instead of "neg; lock xadd" 791 ; Could use "lock sub" instead of "neg; lock xadd"
558 ; CHECK-LABEL: test_atomic_rmw_sub_32_ignored 792 ; CHECK-LABEL: test_atomic_rmw_sub_32_ignored
559 ; CHECK: neg [[REG:.*]] 793 ; CHECK: neg [[REG:.*]]
560 ; CHECK: lock xadd DWORD {{.*}},[[REG]] 794 ; CHECK: lock xadd DWORD {{.*}},[[REG]]
561 ; ARM32-LABEL: test_atomic_rmw_sub_32_ignored 795 ; ARM32-LABEL: test_atomic_rmw_sub_32_ignored
562 ; ARM32: dmb 796 ; ARM32: dmb
563 ; ARM32: ldrex 797 ; ARM32: ldrex
564 ; ARM32: sub 798 ; ARM32: sub
565 ; ARM32: strex 799 ; ARM32: strex
566 ; ARM32: bne 800 ; ARM32: bne
567 ; ARM32: dmb 801 ; ARM32: dmb
802 ; MIPS32-LABEL: test_atomic_rmw_sub_32_ignored
803 ; MIPS32: sync
804 ; MIPS32: ll
805 ; MIPS32: subu
806 ; MIPS32: sc
807 ; MIPS32: beq {{.*}}, $zero, {{.*}}
808 ; MIPS32: sync
568 809
569 ;; or 810 ;; or
570 811
571 define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) { 812 define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) {
572 entry: 813 entry:
573 %trunc = trunc i32 %v to i8 814 %trunc = trunc i32 %v to i8
574 %ptr = inttoptr i32 %iptr to i8* 815 %ptr = inttoptr i32 %iptr to i8*
575 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) 816 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6)
576 %a_ext = zext i8 %a to i32 817 %a_ext = zext i8 %a to i32
577 ret i32 %a_ext 818 ret i32 %a_ext
578 } 819 }
579 ; CHECK-LABEL: test_atomic_rmw_or_8 820 ; CHECK-LABEL: test_atomic_rmw_or_8
580 ; CHECK: mov al,BYTE PTR 821 ; CHECK: mov al,BYTE PTR
581 ; Dest cannot be eax here, because eax is used for the old value. Also want 822 ; Dest cannot be eax here, because eax is used for the old value. Also want
582 ; to make sure that cmpxchg's source is the same register. 823 ; to make sure that cmpxchg's source is the same register.
583 ; CHECK: or [[REG:[^a].]] 824 ; CHECK: or [[REG:[^a].]]
584 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]] 825 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]]
585 ; CHECK: jne 826 ; CHECK: jne
586 ; ARM32-LABEL: test_atomic_rmw_or_8 827 ; ARM32-LABEL: test_atomic_rmw_or_8
587 ; ARM32: dmb 828 ; ARM32: dmb
588 ; ARM32: ldrexb 829 ; ARM32: ldrexb
589 ; ARM32: orr 830 ; ARM32: orr
590 ; ARM32: strexb 831 ; ARM32: strexb
591 ; ARM32: bne 832 ; ARM32: bne
592 ; ARM32: dmb 833 ; ARM32: dmb
834 ; MIPS32-LABEL: test_atomic_rmw_or_8
835 ; MIPS32: sync
836 ; MIPS32: addiu {{.*}}, $zero, -4
837 ; MIPS32: and
838 ; MIPS32: andi {{.*}}, {{.*}}, 3
839 ; MIPS32: sll {{.*}}, {{.*}}, 3
840 ; MIPS32: ori {{.*}}, $zero, 255
841 ; MIPS32: sllv
842 ; MIPS32: nor
843 ; MIPS32: sllv
844 ; MIPS32: ll
845 ; MIPS32: or
846 ; MIPS32: and
847 ; MIPS32: and
848 ; MIPS32: or
849 ; MIPS32: sc
850 ; MIPS32: beq {{.*}}, $zero, {{.*}}
851 ; MIPS32: and
852 ; MIPS32: srlv
853 ; MIPS32: sll {{.*}}, {{.*}}, 24
854 ; MIPS32: sra {{.*}}, {{.*}}, 24
855 ; MIPS32: sync
593 856
594 ; Same test as above, but with a global address to test FakeUse issues. 857 ; Same test as above, but with a global address to test FakeUse issues.
595 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) { 858 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) {
596 entry: 859 entry:
597 %trunc = trunc i32 %v to i8 860 %trunc = trunc i32 %v to i8
598 %ptr = bitcast [1 x i8]* @SzGlobal8 to i8* 861 %ptr = bitcast [1 x i8]* @SzGlobal8 to i8*
599 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) 862 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6)
600 %a_ext = zext i8 %a to i32 863 %a_ext = zext i8 %a to i32
601 ret i32 %a_ext 864 ret i32 %a_ext
602 } 865 }
603 ; CHECK-LABEL: test_atomic_rmw_or_8_global 866 ; CHECK-LABEL: test_atomic_rmw_or_8_global
604 ; ARM32-LABEL: test_atomic_rmw_or_8_global 867 ; ARM32-LABEL: test_atomic_rmw_or_8_global
605 ; ARM32: dmb 868 ; ARM32: dmb
606 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8 869 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8
607 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8 870 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8
608 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} 871 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
609 ; ARM32: orr 872 ; ARM32: orr
610 ; ARM32: strexb 873 ; ARM32: strexb
611 ; ARM32: bne 874 ; ARM32: bne
612 ; ARM32: dmb 875 ; ARM32: dmb
876 ; MIPS32-LABEL: test_atomic_rmw_or_8_global
877 ; MIPS32: sync
878 ; MIPS32: addiu {{.*}}, $zero, -4
879 ; MIPS32: and
880 ; MIPS32: andi {{.*}}, {{.*}}, 3
881 ; MIPS32: sll {{.*}}, {{.*}}, 3
882 ; MIPS32: ori {{.*}}, $zero, 255
883 ; MIPS32: sllv
884 ; MIPS32: nor
885 ; MIPS32: sllv
886 ; MIPS32: ll
887 ; MIPS32: or
888 ; MIPS32: and
889 ; MIPS32: and
890 ; MIPS32: or
891 ; MIPS32: sc
892 ; MIPS32: beq {{.*}}, $zero, {{.*}}
893 ; MIPS32: and
894 ; MIPS32: srlv
895 ; MIPS32: sll {{.*}}, {{.*}}, 24
896 ; MIPS32: sra {{.*}}, {{.*}}, 24
897 ; MIPS32: sync
613 898
614 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { 899 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) {
615 entry: 900 entry:
616 %trunc = trunc i32 %v to i16 901 %trunc = trunc i32 %v to i16
617 %ptr = inttoptr i32 %iptr to i16* 902 %ptr = inttoptr i32 %iptr to i16*
618 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) 903 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6)
619 %a_ext = zext i16 %a to i32 904 %a_ext = zext i16 %a to i32
620 ret i32 %a_ext 905 ret i32 %a_ext
621 } 906 }
622 ; CHECK-LABEL: test_atomic_rmw_or_16 907 ; CHECK-LABEL: test_atomic_rmw_or_16
623 ; CHECK: mov ax,WORD PTR 908 ; CHECK: mov ax,WORD PTR
624 ; CHECK: or [[REG:[^a].]] 909 ; CHECK: or [[REG:[^a].]]
625 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],[[REG]] 910 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],[[REG]]
626 ; CHECK: jne 911 ; CHECK: jne
627 ; ARM32-LABEL: test_atomic_rmw_or_16 912 ; ARM32-LABEL: test_atomic_rmw_or_16
628 ; ARM32: dmb 913 ; ARM32: dmb
629 ; ARM32: ldrexh 914 ; ARM32: ldrexh
630 ; ARM32: orr 915 ; ARM32: orr
631 ; ARM32: strexh 916 ; ARM32: strexh
632 ; ARM32: bne 917 ; ARM32: bne
633 ; ARM32: dmb 918 ; ARM32: dmb
919 ; MIPS32-LABEL: test_atomic_rmw_or_16
920 ; MIPS32: sync
921 ; MIPS32: addiu {{.*}}, $zero, -4
922 ; MIPS32: and
923 ; MIPS32: andi {{.*}}, {{.*}}, 3
924 ; MIPS32: sll {{.*}}, {{.*}}, 3
925 ; MIPS32: ori {{.*}}, {{.*}}, 65535
926 ; MIPS32: sllv
927 ; MIPS32: nor
928 ; MIPS32: sllv
929 ; MIPS32: ll
930 ; MIPS32: or
931 ; MIPS32: and
932 ; MIPS32: and
933 ; MIPS32: or
934 ; MIPS32: sc
935 ; MIPS32: beq {{.*}}, $zero, {{.*}}
936 ; MIPS32: and
937 ; MIPS32: srlv
938 ; MIPS32: sll {{.*}}, {{.*}}, 16
939 ; MIPS32: sra {{.*}}, {{.*}}, 16
940 ; MIPS32: sync
634 941
635 ; Same test as above, but with a global address to test FakeUse issues. 942 ; Same test as above, but with a global address to test FakeUse issues.
636 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) { 943 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) {
637 entry: 944 entry:
638 %trunc = trunc i32 %v to i16 945 %trunc = trunc i32 %v to i16
639 %ptr = bitcast [2 x i8]* @SzGlobal16 to i16* 946 %ptr = bitcast [2 x i8]* @SzGlobal16 to i16*
640 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) 947 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6)
641 %a_ext = zext i16 %a to i32 948 %a_ext = zext i16 %a to i32
642 ret i32 %a_ext 949 ret i32 %a_ext
643 } 950 }
644 ; CHECK-LABEL: test_atomic_rmw_or_16_global 951 ; CHECK-LABEL: test_atomic_rmw_or_16_global
645 ; ARM32-LABEL: test_atomic_rmw_or_16_global 952 ; ARM32-LABEL: test_atomic_rmw_or_16_global
646 ; ARM32: dmb 953 ; ARM32: dmb
647 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16 954 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16
648 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16 955 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16
649 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} 956 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
650 ; ARM32: orr 957 ; ARM32: orr
651 ; ARM32: strexh 958 ; ARM32: strexh
652 ; ARM32: bne 959 ; ARM32: bne
653 ; ARM32: dmb 960 ; ARM32: dmb
961 ; MIPS32-LABEL: test_atomic_rmw_or_16_global
962 ; MIPS32: sync
963 ; MIPS32: addiu {{.*}}, $zero, -4
964 ; MIPS32: and
965 ; MIPS32: andi {{.*}}, {{.*}}, 3
966 ; MIPS32: sll {{.*}}, {{.*}}, 3
967 ; MIPS32: ori {{.*}}, {{.*}}, 65535
968 ; MIPS32: sllv
969 ; MIPS32: nor
970 ; MIPS32: sllv
971 ; MIPS32: ll
972 ; MIPS32: or
973 ; MIPS32: and
974 ; MIPS32: and
975 ; MIPS32: or
976 ; MIPS32: sc
977 ; MIPS32: beq {{.*}}, $zero, {{.*}}
978 ; MIPS32: and
979 ; MIPS32: srlv
980 ; MIPS32: sll {{.*}}, {{.*}}, 16
981 ; MIPS32: sra {{.*}}, {{.*}}, 16
982 ; MIPS32: sync
654 983
655 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { 984 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) {
656 entry: 985 entry:
657 %ptr = inttoptr i32 %iptr to i32* 986 %ptr = inttoptr i32 %iptr to i32*
658 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) 987 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
659 ret i32 %a 988 ret i32 %a
660 } 989 }
661 ; CHECK-LABEL: test_atomic_rmw_or_32 990 ; CHECK-LABEL: test_atomic_rmw_or_32
662 ; CHECK: mov eax,DWORD PTR 991 ; CHECK: mov eax,DWORD PTR
663 ; CHECK: or [[REG:e[^a].]] 992 ; CHECK: or [[REG:e[^a].]]
664 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],[[REG]] 993 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],[[REG]]
665 ; CHECK: jne 994 ; CHECK: jne
666 ; ARM32-LABEL: test_atomic_rmw_or_32 995 ; ARM32-LABEL: test_atomic_rmw_or_32
667 ; ARM32: dmb 996 ; ARM32: dmb
668 ; ARM32: ldrex 997 ; ARM32: ldrex
669 ; ARM32: orr 998 ; ARM32: orr
670 ; ARM32: strex 999 ; ARM32: strex
671 ; ARM32: bne 1000 ; ARM32: bne
672 ; ARM32: dmb 1001 ; ARM32: dmb
1002 ; MIPS32-LABEL: test_atomic_rmw_or_32
1003 ; MIPS32: sync
1004 ; MIPS32: ll
1005 ; MIPS32: or
1006 ; MIPS32: sc
1007 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1008 ; MIPS32: sync
673 1009
674 ; Same test as above, but with a global address to test FakeUse issues. 1010 ; Same test as above, but with a global address to test FakeUse issues.
675 define internal i32 @test_atomic_rmw_or_32_global(i32 %v) { 1011 define internal i32 @test_atomic_rmw_or_32_global(i32 %v) {
676 entry: 1012 entry:
677 %ptr = bitcast [4 x i8]* @SzGlobal32 to i32* 1013 %ptr = bitcast [4 x i8]* @SzGlobal32 to i32*
678 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) 1014 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
679 ret i32 %a 1015 ret i32 %a
680 } 1016 }
681 ; CHECK-LABEL: test_atomic_rmw_or_32_global 1017 ; CHECK-LABEL: test_atomic_rmw_or_32_global
682 ; ARM32-LABEL: test_atomic_rmw_or_32_global 1018 ; ARM32-LABEL: test_atomic_rmw_or_32_global
683 ; ARM32: dmb 1019 ; ARM32: dmb
684 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32 1020 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32
685 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32 1021 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32
686 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} 1022 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
687 ; ARM32: orr 1023 ; ARM32: orr
688 ; ARM32: strex 1024 ; ARM32: strex
689 ; ARM32: bne 1025 ; ARM32: bne
690 ; ARM32: dmb 1026 ; ARM32: dmb
1027 ; MIPS32-LABEL: test_atomic_rmw_or_32_global
1028 ; MIPS32: sync
1029 ; MIPS32: ll
1030 ; MIPS32: or
1031 ; MIPS32: sc
1032 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1033 ; MIPS32: sync
691 1034
692 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { 1035 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) {
693 entry: 1036 entry:
694 %ptr = inttoptr i32 %iptr to i64* 1037 %ptr = inttoptr i32 %iptr to i64*
695 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) 1038 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6)
696 ret i64 %a 1039 ret i64 %a
697 } 1040 }
698 ; CHECK-LABEL: test_atomic_rmw_or_64 1041 ; CHECK-LABEL: test_atomic_rmw_or_64
699 ; CHECK: push ebx 1042 ; CHECK: push ebx
700 ; CHECK: mov eax,DWORD PTR [{{.*}}] 1043 ; CHECK: mov eax,DWORD PTR [{{.*}}]
701 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] 1044 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4]
702 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax 1045 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax
703 ; CHECK: or ebx,{{.*e.[^x]}} 1046 ; CHECK: or ebx,{{.*e.[^x]}}
704 ; CHECK: mov ecx,edx 1047 ; CHECK: mov ecx,edx
705 ; CHECK: or ecx,{{.*e.[^x]}} 1048 ; CHECK: or ecx,{{.*e.[^x]}}
706 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} 1049 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}
707 ; CHECK: jne [[LABEL]] 1050 ; CHECK: jne [[LABEL]]
708 ; ARM32-LABEL: test_atomic_rmw_or_64 1051 ; ARM32-LABEL: test_atomic_rmw_or_64
709 ; ARM32: dmb 1052 ; ARM32: dmb
710 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1053 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
711 ; ARM32: orr 1054 ; ARM32: orr
712 ; ARM32: orr 1055 ; ARM32: orr
713 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1056 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
714 ; ARM32: bne 1057 ; ARM32: bne
715 ; ARM32: dmb 1058 ; ARM32: dmb
1059 ; MIPS32-LABEL: test_atomic_rmw_or_64
1060 ; MIPS32: sync
1061 ; MIPS32: ll
1062 ; MIPS32: or
1063 ; MIPS32: sc
1064 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1065 ; MIPS32: ll
1066 ; MIPS32: or
1067 ; MIPS32: sc
1068 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1069 ; MIPS32: sync
716 1070
717 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) { 1071 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) {
718 entry: 1072 entry:
719 %ptr = inttoptr i32 %iptr to i32* 1073 %ptr = inttoptr i32 %iptr to i32*
720 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) 1074 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
721 ret i32 %v 1075 ret i32 %v
722 } 1076 }
723 ; CHECK-LABEL: test_atomic_rmw_or_32_ignored 1077 ; CHECK-LABEL: test_atomic_rmw_or_32_ignored
724 ; Could just "lock or", if we inspect the liveness information first. 1078 ; Could just "lock or", if we inspect the liveness information first.
725 ; Would also need a way to introduce "lock"'edness to binary 1079 ; Would also need a way to introduce "lock"'edness to binary
726 ; operators without introducing overhead on the more common binary ops. 1080 ; operators without introducing overhead on the more common binary ops.
727 ; CHECK: mov eax,DWORD PTR 1081 ; CHECK: mov eax,DWORD PTR
728 ; CHECK: or [[REG:e[^a].]] 1082 ; CHECK: or [[REG:e[^a].]]
729 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],[[REG]] 1083 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],[[REG]]
730 ; CHECK: jne 1084 ; CHECK: jne
731 ; ARM32-LABEL: test_atomic_rmw_or_32_ignored 1085 ; ARM32-LABEL: test_atomic_rmw_or_32_ignored
732 ; ARM32: dmb 1086 ; ARM32: dmb
733 ; ARM32: ldrex 1087 ; ARM32: ldrex
734 ; ARM32: orr 1088 ; ARM32: orr
735 ; ARM32: strex 1089 ; ARM32: strex
736 ; ARM32: bne 1090 ; ARM32: bne
737 ; ARM32: dmb 1091 ; ARM32: dmb
1092 ; MIPS32-LABEL: test_atomic_rmw_or_32_ignored
1093 ; MIPS32: sync
1094 ; MIPS32: ll
1095 ; MIPS32: or
1096 ; MIPS32: sc
1097 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1098 ; MIPS32: sync
738 1099
739 ;; and 1100 ;; and
740 1101
741 define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) { 1102 define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) {
742 entry: 1103 entry:
743 %trunc = trunc i32 %v to i8 1104 %trunc = trunc i32 %v to i8
744 %ptr = inttoptr i32 %iptr to i8* 1105 %ptr = inttoptr i32 %iptr to i8*
745 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i8* %ptr, i8 %trunc, i32 6) 1106 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i8* %ptr, i8 %trunc, i32 6)
746 %a_ext = zext i8 %a to i32 1107 %a_ext = zext i8 %a to i32
747 ret i32 %a_ext 1108 ret i32 %a_ext
748 } 1109 }
749 ; CHECK-LABEL: test_atomic_rmw_and_8 1110 ; CHECK-LABEL: test_atomic_rmw_and_8
750 ; CHECK: mov al,BYTE PTR 1111 ; CHECK: mov al,BYTE PTR
751 ; CHECK: and [[REG:[^a].]] 1112 ; CHECK: and [[REG:[^a].]]
752 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]] 1113 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]]
753 ; CHECK: jne 1114 ; CHECK: jne
754 ; ARM32-LABEL: test_atomic_rmw_and_8 1115 ; ARM32-LABEL: test_atomic_rmw_and_8
755 ; ARM32: dmb 1116 ; ARM32: dmb
756 ; ARM32: ldrexb 1117 ; ARM32: ldrexb
757 ; ARM32: and 1118 ; ARM32: and
758 ; ARM32: strexb 1119 ; ARM32: strexb
759 ; ARM32: bne 1120 ; ARM32: bne
760 ; ARM32: dmb 1121 ; ARM32: dmb
1122 ; MIPS32-LABEL: test_atomic_rmw_and_8
1123 ; MIPS32: sync
1124 ; MIPS32: addiu {{.*}}, $zero, -4
1125 ; MIPS32: and
1126 ; MIPS32: andi {{.*}}, {{.*}}, 3
1127 ; MIPS32: sll {{.*}}, {{.*}}, 3
1128 ; MIPS32: ori {{.*}}, $zero, 255
1129 ; MIPS32: sllv
1130 ; MIPS32: nor
1131 ; MIPS32: sllv
1132 ; MIPS32: ll
1133 ; MIPS32: and
1134 ; MIPS32: and
1135 ; MIPS32: and
1136 ; MIPS32: or
1137 ; MIPS32: sc
1138 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1139 ; MIPS32: and
1140 ; MIPS32: srlv
1141 ; MIPS32: sll {{.*}}, {{.*}}, 24
1142 ; MIPS32: sra {{.*}}, {{.*}}, 24
1143 ; MIPS32: sync
761 1144
762 define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) { 1145 define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) {
763 entry: 1146 entry:
764 %trunc = trunc i32 %v to i16 1147 %trunc = trunc i32 %v to i16
765 %ptr = inttoptr i32 %iptr to i16* 1148 %ptr = inttoptr i32 %iptr to i16*
766 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i16* %ptr, i16 %trunc, i32 6) 1149 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i16* %ptr, i16 %trunc, i32 6)
767 %a_ext = zext i16 %a to i32 1150 %a_ext = zext i16 %a to i32
768 ret i32 %a_ext 1151 ret i32 %a_ext
769 } 1152 }
770 ; CHECK-LABEL: test_atomic_rmw_and_16 1153 ; CHECK-LABEL: test_atomic_rmw_and_16
771 ; CHECK: mov ax,WORD PTR 1154 ; CHECK: mov ax,WORD PTR
772 ; CHECK: and 1155 ; CHECK: and
773 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}] 1156 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}]
774 ; CHECK: jne 1157 ; CHECK: jne
775 ; ARM32-LABEL: test_atomic_rmw_and_16 1158 ; ARM32-LABEL: test_atomic_rmw_and_16
776 ; ARM32: dmb 1159 ; ARM32: dmb
777 ; ARM32: ldrexh 1160 ; ARM32: ldrexh
778 ; ARM32: and 1161 ; ARM32: and
779 ; ARM32: strexh 1162 ; ARM32: strexh
780 ; ARM32: bne 1163 ; ARM32: bne
781 ; ARM32: dmb 1164 ; ARM32: dmb
1165 ; MIPS32-LABEL: test_atomic_rmw_and_16
1166 ; MIPS32: sync
1167 ; MIPS32: addiu {{.*}}, $zero, -4
1168 ; MIPS32: and
1169 ; MIPS32: andi {{.*}}, {{.*}}, 3
1170 ; MIPS32: sll {{.*}}, {{.*}}, 3
1171 ; MIPS32: ori {{.*}}, {{.*}}, 65535
1172 ; MIPS32: sllv
1173 ; MIPS32: nor
1174 ; MIPS32: sllv
1175 ; MIPS32: ll
1176 ; MIPS32: and
1177 ; MIPS32: and
1178 ; MIPS32: and
1179 ; MIPS32: or
1180 ; MIPS32: sc
1181 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1182 ; MIPS32: and
1183 ; MIPS32: srlv
1184 ; MIPS32: sll {{.*}}, {{.*}}, 16
1185 ; MIPS32: sra {{.*}}, {{.*}}, 16
1186 ; MIPS32: sync
782 1187
783 define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) { 1188 define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) {
784 entry: 1189 entry:
785 %ptr = inttoptr i32 %iptr to i32* 1190 %ptr = inttoptr i32 %iptr to i32*
786 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) 1191 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6)
787 ret i32 %a 1192 ret i32 %a
788 } 1193 }
789 ; CHECK-LABEL: test_atomic_rmw_and_32 1194 ; CHECK-LABEL: test_atomic_rmw_and_32
790 ; CHECK: mov eax,DWORD PTR 1195 ; CHECK: mov eax,DWORD PTR
791 ; CHECK: and 1196 ; CHECK: and
792 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] 1197 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
793 ; CHECK: jne 1198 ; CHECK: jne
794 ; ARM32-LABEL: test_atomic_rmw_and_32 1199 ; ARM32-LABEL: test_atomic_rmw_and_32
795 ; ARM32: dmb 1200 ; ARM32: dmb
796 ; ARM32: ldrex 1201 ; ARM32: ldrex
797 ; ARM32: and 1202 ; ARM32: and
798 ; ARM32: strex 1203 ; ARM32: strex
799 ; ARM32: bne 1204 ; ARM32: bne
800 ; ARM32: dmb 1205 ; ARM32: dmb
1206 ; MIPS32-LABEL: test_atomic_rmw_and_32
1207 ; MIPS32: sync
1208 ; MIPS32: ll
1209 ; MIPS32: and
1210 ; MIPS32: sc
1211 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1212 ; MIPS32: sync
801 1213
802 define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) { 1214 define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) {
803 entry: 1215 entry:
804 %ptr = inttoptr i32 %iptr to i64* 1216 %ptr = inttoptr i32 %iptr to i64*
805 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i64* %ptr, i64 %v, i32 6) 1217 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i64* %ptr, i64 %v, i32 6)
806 ret i64 %a 1218 ret i64 %a
807 } 1219 }
808 ; CHECK-LABEL: test_atomic_rmw_and_64 1220 ; CHECK-LABEL: test_atomic_rmw_and_64
809 ; CHECK: push ebx 1221 ; CHECK: push ebx
810 ; CHECK: mov eax,DWORD PTR [{{.*}}] 1222 ; CHECK: mov eax,DWORD PTR [{{.*}}]
811 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] 1223 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4]
812 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax 1224 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax
813 ; CHECK: and ebx,{{.*e.[^x]}} 1225 ; CHECK: and ebx,{{.*e.[^x]}}
814 ; CHECK: mov ecx,edx 1226 ; CHECK: mov ecx,edx
815 ; CHECK: and ecx,{{.*e.[^x]}} 1227 ; CHECK: and ecx,{{.*e.[^x]}}
816 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} 1228 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}
817 ; CHECK: jne [[LABEL]] 1229 ; CHECK: jne [[LABEL]]
818 ; ARM32-LABEL: test_atomic_rmw_and_64 1230 ; ARM32-LABEL: test_atomic_rmw_and_64
819 ; ARM32: dmb 1231 ; ARM32: dmb
820 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1232 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
821 ; ARM32: and 1233 ; ARM32: and
822 ; ARM32: and 1234 ; ARM32: and
823 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1235 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
824 ; ARM32: bne 1236 ; ARM32: bne
825 ; ARM32: dmb 1237 ; ARM32: dmb
1238 ; MIPS32-LABEL: test_atomic_rmw_and_64
1239 ; MIPS32: sync
1240 ; MIPS32: ll
1241 ; MIPS32: and
1242 ; MIPS32: sc
1243 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1244 ; MIPS32: ll
1245 ; MIPS32: and
1246 ; MIPS32: sc
1247 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1248 ; MIPS32: sync
826 1249
827 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) { 1250 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) {
828 entry: 1251 entry:
829 %ptr = inttoptr i32 %iptr to i32* 1252 %ptr = inttoptr i32 %iptr to i32*
830 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) 1253 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6)
831 ret i32 %v 1254 ret i32 %v
832 } 1255 }
833 ; CHECK-LABEL: test_atomic_rmw_and_32_ignored 1256 ; CHECK-LABEL: test_atomic_rmw_and_32_ignored
834 ; Could just "lock and" 1257 ; Could just "lock and"
835 ; CHECK: mov eax,DWORD PTR 1258 ; CHECK: mov eax,DWORD PTR
836 ; CHECK: and 1259 ; CHECK: and
837 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] 1260 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
838 ; CHECK: jne 1261 ; CHECK: jne
839 ; ARM32-LABEL: test_atomic_rmw_and_32_ignored 1262 ; ARM32-LABEL: test_atomic_rmw_and_32_ignored
840 ; ARM32: dmb 1263 ; ARM32: dmb
841 ; ARM32: ldrex 1264 ; ARM32: ldrex
842 ; ARM32: and 1265 ; ARM32: and
843 ; ARM32: strex 1266 ; ARM32: strex
844 ; ARM32: bne 1267 ; ARM32: bne
845 ; ARM32: dmb 1268 ; ARM32: dmb
1269 ; MIPS32-LABEL: test_atomic_rmw_and_32_ignored
1270 ; MIPS32: sync
1271 ; MIPS32: ll
1272 ; MIPS32: and
1273 ; MIPS32: sc
1274 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1275 ; MIPS32: sync
846 1276
847 ;; xor 1277 ;; xor
848 1278
849 define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) { 1279 define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) {
850 entry: 1280 entry:
851 %trunc = trunc i32 %v to i8 1281 %trunc = trunc i32 %v to i8
852 %ptr = inttoptr i32 %iptr to i8* 1282 %ptr = inttoptr i32 %iptr to i8*
853 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i8* %ptr, i8 %trunc, i32 6) 1283 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i8* %ptr, i8 %trunc, i32 6)
854 %a_ext = zext i8 %a to i32 1284 %a_ext = zext i8 %a to i32
855 ret i32 %a_ext 1285 ret i32 %a_ext
856 } 1286 }
857 ; CHECK-LABEL: test_atomic_rmw_xor_8 1287 ; CHECK-LABEL: test_atomic_rmw_xor_8
858 ; CHECK: mov al,BYTE PTR 1288 ; CHECK: mov al,BYTE PTR
859 ; CHECK: xor [[REG:[^a].]] 1289 ; CHECK: xor [[REG:[^a].]]
860 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]] 1290 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],[[REG]]
861 ; CHECK: jne 1291 ; CHECK: jne
862 ; ARM32-LABEL: test_atomic_rmw_xor_8 1292 ; ARM32-LABEL: test_atomic_rmw_xor_8
863 ; ARM32: dmb 1293 ; ARM32: dmb
864 ; ARM32: ldrexb 1294 ; ARM32: ldrexb
865 ; ARM32: eor 1295 ; ARM32: eor
866 ; ARM32: strexb 1296 ; ARM32: strexb
867 ; ARM32: bne 1297 ; ARM32: bne
868 ; ARM32: dmb 1298 ; ARM32: dmb
1299 ; MIPS32-LABEL: test_atomic_rmw_xor_8
1300 ; MIPS32: sync
1301 ; MIPS32: addiu {{.*}}, $zero, -4
1302 ; MIPS32: and
1303 ; MIPS32: andi {{.*}}, {{.*}}, 3
1304 ; MIPS32: sll {{.*}}, {{.*}}, 3
1305 ; MIPS32: ori {{.*}}, $zero, 255
1306 ; MIPS32: sllv
1307 ; MIPS32: nor
1308 ; MIPS32: sllv
1309 ; MIPS32: ll
1310 ; MIPS32: xor
1311 ; MIPS32: and
1312 ; MIPS32: and
1313 ; MIPS32: or
1314 ; MIPS32: sc
1315 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1316 ; MIPS32: and
1317 ; MIPS32: srlv
1318 ; MIPS32: sll {{.*}}, {{.*}}, 24
1319 ; MIPS32: sra {{.*}}, {{.*}}, 24
1320 ; MIPS32: sync
869 1321
870 define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) { 1322 define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) {
871 entry: 1323 entry:
872 %trunc = trunc i32 %v to i16 1324 %trunc = trunc i32 %v to i16
873 %ptr = inttoptr i32 %iptr to i16* 1325 %ptr = inttoptr i32 %iptr to i16*
874 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i16* %ptr, i16 %trunc, i32 6) 1326 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i16* %ptr, i16 %trunc, i32 6)
875 %a_ext = zext i16 %a to i32 1327 %a_ext = zext i16 %a to i32
876 ret i32 %a_ext 1328 ret i32 %a_ext
877 } 1329 }
878 ; CHECK-LABEL: test_atomic_rmw_xor_16 1330 ; CHECK-LABEL: test_atomic_rmw_xor_16
879 ; CHECK: mov ax,WORD PTR 1331 ; CHECK: mov ax,WORD PTR
880 ; CHECK: xor 1332 ; CHECK: xor
881 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}] 1333 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}]
882 ; CHECK: jne 1334 ; CHECK: jne
883 ; ARM32-LABEL: test_atomic_rmw_xor_16 1335 ; ARM32-LABEL: test_atomic_rmw_xor_16
884 ; ARM32: dmb 1336 ; ARM32: dmb
885 ; ARM32: ldrexh 1337 ; ARM32: ldrexh
886 ; ARM32: eor 1338 ; ARM32: eor
887 ; ARM32: strexh 1339 ; ARM32: strexh
888 ; ARM32: bne 1340 ; ARM32: bne
889 ; ARM32: dmb 1341 ; ARM32: dmb
1342 ; MIPS32-LABEL: test_atomic_rmw_xor_16
1343 ; MIPS32: sync
1344 ; MIPS32: addiu {{.*}}, $zero, -4
1345 ; MIPS32: and
1346 ; MIPS32: andi {{.*}}, {{.*}}, 3
1347 ; MIPS32: sll {{.*}}, {{.*}}, 3
1348 ; MIPS32: ori {{.*}}, {{.*}}, 65535
1349 ; MIPS32: sllv
1350 ; MIPS32: nor
1351 ; MIPS32: sllv
1352 ; MIPS32: ll
1353 ; MIPS32: xor
1354 ; MIPS32: and
1355 ; MIPS32: and
1356 ; MIPS32: or
1357 ; MIPS32: sc
1358 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1359 ; MIPS32: and
1360 ; MIPS32: srlv
1361 ; MIPS32: sll {{.*}}, {{.*}}, 16
1362 ; MIPS32: sra {{.*}}, {{.*}}, 16
1363 ; MIPS32: sync
890 1364
891 define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) { 1365 define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) {
892 entry: 1366 entry:
893 %ptr = inttoptr i32 %iptr to i32* 1367 %ptr = inttoptr i32 %iptr to i32*
894 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) 1368 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6)
895 ret i32 %a 1369 ret i32 %a
896 } 1370 }
897 ; CHECK-LABEL: test_atomic_rmw_xor_32 1371 ; CHECK-LABEL: test_atomic_rmw_xor_32
898 ; CHECK: mov eax,DWORD PTR 1372 ; CHECK: mov eax,DWORD PTR
899 ; CHECK: xor 1373 ; CHECK: xor
900 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] 1374 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
901 ; CHECK: jne 1375 ; CHECK: jne
902 ; ARM32-LABEL: test_atomic_rmw_xor_32 1376 ; ARM32-LABEL: test_atomic_rmw_xor_32
903 ; ARM32: dmb 1377 ; ARM32: dmb
904 ; ARM32: ldrex 1378 ; ARM32: ldrex
905 ; ARM32: eor 1379 ; ARM32: eor
906 ; ARM32: strex 1380 ; ARM32: strex
907 ; ARM32: bne 1381 ; ARM32: bne
908 ; ARM32: dmb 1382 ; ARM32: dmb
1383 ; MIPS32-LABEL: test_atomic_rmw_xor_32
1384 ; MIPS32: sync
1385 ; MIPS32: ll
1386 ; MIPS32: xor
1387 ; MIPS32: sc
1388 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1389 ; MIPS32: sync
909 1390
910 define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) { 1391 define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) {
911 entry: 1392 entry:
912 %ptr = inttoptr i32 %iptr to i64* 1393 %ptr = inttoptr i32 %iptr to i64*
913 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i64* %ptr, i64 %v, i32 6) 1394 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i64* %ptr, i64 %v, i32 6)
914 ret i64 %a 1395 ret i64 %a
915 } 1396 }
916 ; CHECK-LABEL: test_atomic_rmw_xor_64 1397 ; CHECK-LABEL: test_atomic_rmw_xor_64
917 ; CHECK: push ebx 1398 ; CHECK: push ebx
918 ; CHECK: mov eax,DWORD PTR [{{.*}}] 1399 ; CHECK: mov eax,DWORD PTR [{{.*}}]
919 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] 1400 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4]
920 ; CHECK: mov ebx,eax 1401 ; CHECK: mov ebx,eax
921 ; CHECK: or ebx,{{.*e.[^x]}} 1402 ; CHECK: or ebx,{{.*e.[^x]}}
922 ; CHECK: mov ecx,edx 1403 ; CHECK: mov ecx,edx
923 ; CHECK: or ecx,{{.*e.[^x]}} 1404 ; CHECK: or ecx,{{.*e.[^x]}}
924 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} 1405 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}
925 ; CHECK: jne 1406 ; CHECK: jne
926 ; ARM32-LABEL: test_atomic_rmw_xor_64 1407 ; ARM32-LABEL: test_atomic_rmw_xor_64
927 ; ARM32: dmb 1408 ; ARM32: dmb
928 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1409 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
929 ; ARM32: eor 1410 ; ARM32: eor
930 ; ARM32: eor 1411 ; ARM32: eor
931 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] 1412 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}]
932 ; ARM32: bne 1413 ; ARM32: bne
933 ; ARM32: dmb 1414 ; ARM32: dmb
1415 ; MIPS32-LABEL: test_atomic_rmw_xor_64
1416 ; MIPS32: sync
1417 ; MIPS32: ll
1418 ; MIPS32: xor
1419 ; MIPS32: sc
1420 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1421 ; MIPS32: ll
1422 ; MIPS32: xor
1423 ; MIPS32: sc
1424 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1425 ; MIPS32: sync
934 1426
935 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) { 1427 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) {
936 entry: 1428 entry:
937 %ptr = inttoptr i32 %iptr to i32* 1429 %ptr = inttoptr i32 %iptr to i32*
938 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) 1430 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6)
939 ret i32 %v 1431 ret i32 %v
940 } 1432 }
941 ; CHECK-LABEL: test_atomic_rmw_xor_32_ignored 1433 ; CHECK-LABEL: test_atomic_rmw_xor_32_ignored
942 ; CHECK: mov eax,DWORD PTR 1434 ; CHECK: mov eax,DWORD PTR
943 ; CHECK: xor 1435 ; CHECK: xor
944 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] 1436 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
945 ; CHECK: jne 1437 ; CHECK: jne
946 ; ARM32-LABEL: test_atomic_rmw_xor_32_ignored 1438 ; ARM32-LABEL: test_atomic_rmw_xor_32_ignored
947 ; ARM32: dmb 1439 ; ARM32: dmb
948 ; ARM32: ldrex 1440 ; ARM32: ldrex
949 ; ARM32: eor 1441 ; ARM32: eor
950 ; ARM32: strex 1442 ; ARM32: strex
951 ; ARM32: bne 1443 ; ARM32: bne
952 ; ARM32: dmb 1444 ; ARM32: dmb
1445 ; MIPS32-LABEL: test_atomic_rmw_xor_32_ignored
1446 ; MIPS32: sync
1447 ; MIPS32: ll
1448 ; MIPS32: xor
1449 ; MIPS32: sc
1450 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1451 ; MIPS32: sync
953 1452
954 ;; exchange 1453 ;; exchange
955 1454
956 define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) { 1455 define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) {
957 entry: 1456 entry:
958 %trunc = trunc i32 %v to i8 1457 %trunc = trunc i32 %v to i8
959 %ptr = inttoptr i32 %iptr to i8* 1458 %ptr = inttoptr i32 %iptr to i8*
960 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i8* %ptr, i8 %trunc, i32 6) 1459 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i8* %ptr, i8 %trunc, i32 6)
961 %a_ext = zext i8 %a to i32 1460 %a_ext = zext i8 %a to i32
962 ret i32 %a_ext 1461 ret i32 %a_ext
963 } 1462 }
964 ; CHECK-LABEL: test_atomic_rmw_xchg_8 1463 ; CHECK-LABEL: test_atomic_rmw_xchg_8
965 ; CHECK: xchg BYTE PTR {{.*}},[[REG:.*]] 1464 ; CHECK: xchg BYTE PTR {{.*}},[[REG:.*]]
966 ; ARM32-LABEL: test_atomic_rmw_xchg_8 1465 ; ARM32-LABEL: test_atomic_rmw_xchg_8
967 ; ARM32: dmb 1466 ; ARM32: dmb
968 ; ARM32: ldrexb 1467 ; ARM32: ldrexb
969 ; ARM32: strexb 1468 ; ARM32: strexb
970 ; ARM32: cmp 1469 ; ARM32: cmp
971 ; ARM32: bne 1470 ; ARM32: bne
972 ; ARM32: dmb 1471 ; ARM32: dmb
1472 ; MIPS32-LABEL: test_atomic_rmw_xchg_8
1473 ; MIPS32: sync
1474 ; MIPS32: addiu {{.*}}, $zero, -4
1475 ; MIPS32: and
1476 ; MIPS32: andi {{.*}}, {{.*}}, 3
1477 ; MIPS32: sll {{.*}}, {{.*}}, 3
1478 ; MIPS32: ori {{.*}}, $zero, 255
1479 ; MIPS32: sllv
1480 ; MIPS32: nor
1481 ; MIPS32: sllv
1482 ; MIPS32: ll
1483 ; MIPS32: and
1484 ; MIPS32: or
1485 ; MIPS32: sc
1486 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1487 ; MIPS32: and
1488 ; MIPS32: srlv
1489 ; MIPS32: sll {{.*}}, {{.*}}, 24
1490 ; MIPS32: sra {{.*}}, {{.*}}, 24
1491 ; MIPS32: sync
973 1492
974 define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) { 1493 define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) {
975 entry: 1494 entry:
976 %trunc = trunc i32 %v to i16 1495 %trunc = trunc i32 %v to i16
977 %ptr = inttoptr i32 %iptr to i16* 1496 %ptr = inttoptr i32 %iptr to i16*
978 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i16* %ptr, i16 %trunc, i32 6) 1497 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i16* %ptr, i16 %trunc, i32 6)
979 %a_ext = zext i16 %a to i32 1498 %a_ext = zext i16 %a to i32
980 ret i32 %a_ext 1499 ret i32 %a_ext
981 } 1500 }
982 ; CHECK-LABEL: test_atomic_rmw_xchg_16 1501 ; CHECK-LABEL: test_atomic_rmw_xchg_16
983 ; CHECK: xchg WORD PTR {{.*}},[[REG:.*]] 1502 ; CHECK: xchg WORD PTR {{.*}},[[REG:.*]]
984 ; ARM32-LABEL: test_atomic_rmw_xchg_16 1503 ; ARM32-LABEL: test_atomic_rmw_xchg_16
985 ; ARM32: dmb 1504 ; ARM32: dmb
986 ; ARM32: ldrexh 1505 ; ARM32: ldrexh
987 ; ARM32: strexh 1506 ; ARM32: strexh
988 ; ARM32: cmp 1507 ; ARM32: cmp
989 ; ARM32: bne 1508 ; ARM32: bne
990 ; ARM32: dmb 1509 ; ARM32: dmb
1510 ; MIPS32-LABEL: test_atomic_rmw_xchg_16
1511 ; MIPS32: sync
1512 ; MIPS32: addiu {{.*}}, $zero, -4
1513 ; MIPS32: and
1514 ; MIPS32: andi {{.*}}, {{.*}}, 3
1515 ; MIPS32: sll {{.*}}, {{.*}}, 3
1516 ; MIPS32: ori {{.*}}, {{.*}}, 65535
1517 ; MIPS32: sllv
1518 ; MIPS32: nor
1519 ; MIPS32: sllv
1520 ; MIPS32: ll
1521 ; MIPS32: and
1522 ; MIPS32: or
1523 ; MIPS32: sc
1524 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1525 ; MIPS32: and
1526 ; MIPS32: srlv
1527 ; MIPS32: sll {{.*}}, {{.*}}, 16
1528 ; MIPS32: sra {{.*}}, {{.*}}, 16
1529 ; MIPS32: sync
991 1530
992 define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) { 1531 define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) {
993 entry: 1532 entry:
994 %ptr = inttoptr i32 %iptr to i32* 1533 %ptr = inttoptr i32 %iptr to i32*
995 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6) 1534 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6)
996 ret i32 %a 1535 ret i32 %a
997 } 1536 }
998 ; CHECK-LABEL: test_atomic_rmw_xchg_32 1537 ; CHECK-LABEL: test_atomic_rmw_xchg_32
999 ; CHECK: xchg DWORD PTR {{.*}},[[REG:.*]] 1538 ; CHECK: xchg DWORD PTR {{.*}},[[REG:.*]]
1000 ; ARM32-LABEL: test_atomic_rmw_xchg_32 1539 ; ARM32-LABEL: test_atomic_rmw_xchg_32
1001 ; ARM32: dmb 1540 ; ARM32: dmb
1002 ; ARM32: ldrex 1541 ; ARM32: ldrex
1003 ; ARM32: strex 1542 ; ARM32: strex
1004 ; ARM32: cmp 1543 ; ARM32: cmp
1005 ; ARM32: bne 1544 ; ARM32: bne
1006 ; ARM32: dmb 1545 ; ARM32: dmb
1546 ; MIPS32-LABEL: test_atomic_rmw_xchg_32
1547 ; MIPS32: sync
1548 ; MIPS32: ll
1549 ; MIPS32: move
1550 ; MIPS32: sc
1551 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1552 ; MIPS32: sync
1007 1553
1008 define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) { 1554 define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) {
1009 entry: 1555 entry:
1010 %ptr = inttoptr i32 %iptr to i64* 1556 %ptr = inttoptr i32 %iptr to i64*
1011 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i64* %ptr, i64 %v, i32 6) 1557 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i64* %ptr, i64 %v, i32 6)
1012 ret i64 %a 1558 ret i64 %a
1013 } 1559 }
1014 ; CHECK-LABEL: test_atomic_rmw_xchg_64 1560 ; CHECK-LABEL: test_atomic_rmw_xchg_64
1015 ; CHECK: push ebx 1561 ; CHECK: push ebx
1016 ; CHECK-DAG: mov edx 1562 ; CHECK-DAG: mov edx
1017 ; CHECK-DAG: mov eax 1563 ; CHECK-DAG: mov eax
1018 ; CHECK-DAG: mov ecx 1564 ; CHECK-DAG: mov ecx
1019 ; CHECK-DAG: mov ebx 1565 ; CHECK-DAG: mov ebx
1020 ; CHECK: lock cmpxchg8b QWORD PTR [{{e.[^x]}} 1566 ; CHECK: lock cmpxchg8b QWORD PTR [{{e.[^x]}}
1021 ; CHECK: jne 1567 ; CHECK: jne
1022 ; ARM32-LABEL: test_atomic_rmw_xchg_64 1568 ; ARM32-LABEL: test_atomic_rmw_xchg_64
1023 ; ARM32: dmb 1569 ; ARM32: dmb
1024 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} 1570 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}}
1025 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} 1571 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
1026 ; ARM32: cmp 1572 ; ARM32: cmp
1027 ; ARM32: bne 1573 ; ARM32: bne
1028 ; ARM32: dmb 1574 ; ARM32: dmb
1575 ; MIPS32-LABEL: test_atomic_rmw_xchg_64
1576 ; MIPS32: sync
1577 ; MIPS32: ll
1578 ; MIPS32: move
1579 ; MIPS32: sc
1580 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1581 ; MIPS32: ll
1582 ; MIPS32: move
1583 ; MIPS32: sc
1584 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1585 ; MIPS32: sync
1029 1586
1030 define internal i32 @test_atomic_rmw_xchg_32_ignored(i32 %iptr, i32 %v) { 1587 define internal i32 @test_atomic_rmw_xchg_32_ignored(i32 %iptr, i32 %v) {
1031 entry: 1588 entry:
1032 %ptr = inttoptr i32 %iptr to i32* 1589 %ptr = inttoptr i32 %iptr to i32*
1033 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6) 1590 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6)
1034 ret i32 %v 1591 ret i32 %v
1035 } 1592 }
1036 ; In this case, ignoring the return value doesn't help. The xchg is 1593 ; In this case, ignoring the return value doesn't help. The xchg is
1037 ; used to do an atomic store. 1594 ; used to do an atomic store.
1038 ; CHECK-LABEL: test_atomic_rmw_xchg_32_ignored 1595 ; CHECK-LABEL: test_atomic_rmw_xchg_32_ignored
1039 ; CHECK: xchg DWORD PTR {{.*}},[[REG:.*]] 1596 ; CHECK: xchg DWORD PTR {{.*}},[[REG:.*]]
1040 ; ARM32-LABEL: test_atomic_rmw_xchg_32_ignored 1597 ; ARM32-LABEL: test_atomic_rmw_xchg_32_ignored
1041 ; ARM32: dmb 1598 ; ARM32: dmb
1042 ; ARM32: ldrex 1599 ; ARM32: ldrex
1043 ; ARM32: strex 1600 ; ARM32: strex
1044 ; ARM32: cmp 1601 ; ARM32: cmp
1045 ; ARM32: bne 1602 ; ARM32: bne
1046 ; ARM32: dmb 1603 ; ARM32: dmb
1604 ; MIPS32-LABEL: test_atomic_rmw_xchg_32_ignored
1605 ; MIPS32: sync
1606 ; MIPS32: ll
1607 ; MIPS32: move
1608 ; MIPS32: sc
1609 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1610 ; MIPS32: sync
1047 1611
1048 ;;;; Cmpxchg 1612 ;;;; Cmpxchg
1049 1613
1050 define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, 1614 define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected,
1051 i32 %desired) { 1615 i32 %desired) {
1052 entry: 1616 entry:
1053 %trunc_exp = trunc i32 %expected to i8 1617 %trunc_exp = trunc i32 %expected to i8
1054 %trunc_des = trunc i32 %desired to i8 1618 %trunc_des = trunc i32 %desired to i8
1055 %ptr = inttoptr i32 %iptr to i8* 1619 %ptr = inttoptr i32 %iptr to i8*
1056 %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp, 1620 %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp,
1057 i8 %trunc_des, i32 6, i32 6) 1621 i8 %trunc_des, i32 6, i32 6)
1058 %old_ext = zext i8 %old to i32 1622 %old_ext = zext i8 %old to i32
1059 ret i32 %old_ext 1623 ret i32 %old_ext
1060 } 1624 }
1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 1625 ; CHECK-LABEL: test_atomic_cmpxchg_8
1062 ; CHECK: mov eax,{{.*}} 1626 ; CHECK: mov eax,{{.*}}
1063 ; Need to check that eax isn't used as the address register or the desired. 1627 ; Need to check that eax isn't used as the address register or the desired.
1064 ; since it is already used as the *expected* register. 1628 ; since it is already used as the *expected* register.
1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l 1629 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l
1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 1630 ; ARM32-LABEL: test_atomic_cmpxchg_8
1067 ; ARM32: dmb 1631 ; ARM32: dmb
1068 ; ARM32: ldrexb [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1632 ; ARM32: ldrexb [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1069 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #24 1633 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #24
1070 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #24 1634 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #24
1071 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1635 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1072 ; ARM32: strexbeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1636 ; ARM32: strexbeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1073 ; ARM32: cmp [[SUCCESS]], #0 1637 ; ARM32: cmp [[SUCCESS]], #0
1074 ; ARM32: bne 1638 ; ARM32: bne
1075 ; ARM32: dmb 1639 ; ARM32: dmb
1640 ; MIPS32-LABEL: test_atomic_cmpxchg_8
1641 ; MIPS32: sync
1642 ; MIPS32: addiu {{.*}}, $zero, -4
1643 ; MIPS32: and
1644 ; MIPS32: andi {{.*}}, {{.*}}, 3
1645 ; MIPS32: sll {{.*}}, {{.*}}, 3
1646 ; MIPS32: ori {{.*}}, $zero, 255
1647 ; MIPS32: sllv
1648 ; MIPS32: nor
1649 ; MIPS32: andi {{.*}}, {{.*}}, 255
1650 ; MIPS32: sllv
1651 ; MIPS32: andi {{.*}}, {{.*}}, 255
1652 ; MIPS32: sllv
1653 ; MIPS32: ll
1654 ; MIPS32: and
1655 ; MIPS32: bne
1656 ; MIPS32: and
1657 ; MIPS32: or
1658 ; MIPS32: sc
1659 ; MIPS32: beq $zero, {{.*}}, {{.*}}
1660 ; MIPS32: srlv
1661 ; MIPS32: sll {{.*}}, {{.*}}, 24
1662 ; MIPS32: sra {{.*}}, {{.*}}, 24
1663 ; MIPS32: sync
1076 1664
1077 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, 1665 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected,
1078 i32 %desired) { 1666 i32 %desired) {
1079 entry: 1667 entry:
1080 %trunc_exp = trunc i32 %expected to i16 1668 %trunc_exp = trunc i32 %expected to i16
1081 %trunc_des = trunc i32 %desired to i16 1669 %trunc_des = trunc i32 %desired to i16
1082 %ptr = inttoptr i32 %iptr to i16* 1670 %ptr = inttoptr i32 %iptr to i16*
1083 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, 1671 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp,
1084 i16 %trunc_des, i32 6, i32 6) 1672 i16 %trunc_des, i32 6, i32 6)
1085 %old_ext = zext i16 %old to i32 1673 %old_ext = zext i16 %old to i32
1086 ret i32 %old_ext 1674 ret i32 %old_ext
1087 } 1675 }
1088 ; CHECK-LABEL: test_atomic_cmpxchg_16 1676 ; CHECK-LABEL: test_atomic_cmpxchg_16
1089 ; CHECK: mov {{ax|eax}},{{.*}} 1677 ; CHECK: mov {{ax|eax}},{{.*}}
1090 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x 1678 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x
1091 ; ARM32-LABEL: test_atomic_cmpxchg_16 1679 ; ARM32-LABEL: test_atomic_cmpxchg_16
1092 ; ARM32: dmb 1680 ; ARM32: dmb
1093 ; ARM32: ldrexh [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1681 ; ARM32: ldrexh [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1094 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #16 1682 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #16
1095 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #16 1683 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #16
1096 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1684 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1097 ; ARM32: strexheq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1685 ; ARM32: strexheq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1098 ; ARM32: cmp [[SUCCESS]], #0 1686 ; ARM32: cmp [[SUCCESS]], #0
1099 ; ARM32: bne 1687 ; ARM32: bne
1100 ; ARM32: dmb 1688 ; ARM32: dmb
1689 ; MIPS32-LABEL: test_atomic_cmpxchg_16
1690 ; MIPS32: sync
1691 ; MIPS32: addiu {{.*}}, $zero, -4
1692 ; MIPS32: and
1693 ; MIPS32: andi {{.*}}, {{.*}}, 3
1694 ; MIPS32: sll {{.*}}, {{.*}}, 3
1695 ; MIPS32: ori {{.*}}, {{.*}}, 65535
1696 ; MIPS32: sllv
1697 ; MIPS32: nor
1698 ; MIPS32: andi {{.*}}, {{.*}}, 65535
1699 ; MIPS32: sllv
1700 ; MIPS32: andi {{.*}}, {{.*}}, 65535
1701 ; MIPS32: sllv
1702 ; MIPS32: ll
1703 ; MIPS32: and
1704 ; MIPS32: bne
1705 ; MIPS32: and
1706 ; MIPS32: or
1707 ; MIPS32: sc
1708 ; MIPS32: beq $zero, {{.*}}, {{.*}}
1709 ; MIPS32: srlv
1710 ; MIPS32: sll {{.*}}, {{.*}}, 16
1711 ; MIPS32: sra {{.*}}, {{.*}}, 16
1712 ; MIPS32: sync
1101 1713
1102 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, 1714 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected,
1103 i32 %desired) { 1715 i32 %desired) {
1104 entry: 1716 entry:
1105 %ptr = inttoptr i32 %iptr to i32* 1717 %ptr = inttoptr i32 %iptr to i32*
1106 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 1718 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
1107 i32 %desired, i32 6, i32 6) 1719 i32 %desired, i32 6, i32 6)
1108 ret i32 %old 1720 ret i32 %old
1109 } 1721 }
1110 ; CHECK-LABEL: test_atomic_cmpxchg_32 1722 ; CHECK-LABEL: test_atomic_cmpxchg_32
1111 ; CHECK: mov eax,{{.*}} 1723 ; CHECK: mov eax,{{.*}}
1112 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} 1724 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}}
1113 ; ARM32-LABEL: test_atomic_cmpxchg_32 1725 ; ARM32-LABEL: test_atomic_cmpxchg_32
1114 ; ARM32: dmb 1726 ; ARM32: dmb
1115 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1727 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1116 ; ARM32: cmp [[V]], {{r[0-9]+}} 1728 ; ARM32: cmp [[V]], {{r[0-9]+}}
1117 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1729 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1118 ; ARM32: strexeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1730 ; ARM32: strexeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1119 ; ARM32: cmp [[SUCCESS]], #0 1731 ; ARM32: cmp [[SUCCESS]], #0
1120 ; ARM32: bne 1732 ; ARM32: bne
1121 ; ARM32: dmb 1733 ; ARM32: dmb
1734 ; MIPS32-LABEL: test_atomic_cmpxchg_32
1735 ; MIPS32: sync
1736 ; MIPS32: ll
1737 ; MIPS32: bne
1738 ; MIPS32: sc
1739 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1740 ; MIPS32: sync
1122 1741
1123 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, 1742 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected,
1124 i64 %desired) { 1743 i64 %desired) {
1125 entry: 1744 entry:
1126 %ptr = inttoptr i32 %iptr to i64* 1745 %ptr = inttoptr i32 %iptr to i64*
1127 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, 1746 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
1128 i64 %desired, i32 6, i32 6) 1747 i64 %desired, i32 6, i32 6)
1129 ret i64 %old 1748 ret i64 %old
1130 } 1749 }
1131 ; CHECK-LABEL: test_atomic_cmpxchg_64 1750 ; CHECK-LABEL: test_atomic_cmpxchg_64
1132 ; CHECK: push ebx 1751 ; CHECK: push ebx
1133 ; CHECK-DAG: mov edx 1752 ; CHECK-DAG: mov edx
1134 ; CHECK-DAG: mov eax 1753 ; CHECK-DAG: mov eax
1135 ; CHECK-DAG: mov ecx 1754 ; CHECK-DAG: mov ecx
1136 ; CHECK-DAG: mov ebx 1755 ; CHECK-DAG: mov ebx
1137 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] 1756 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0]
1138 ; edx and eax are already the return registers, so they don't actually 1757 ; edx and eax are already the return registers, so they don't actually
1139 ; need to be reshuffled via movs. The next test stores the result 1758 ; need to be reshuffled via movs. The next test stores the result
1140 ; somewhere, so in that case they do need to be mov'ed. 1759 ; somewhere, so in that case they do need to be mov'ed.
1141 ; ARM32-LABEL: test_atomic_cmpxchg_64 1760 ; ARM32-LABEL: test_atomic_cmpxchg_64
1142 ; ARM32: dmb 1761 ; ARM32: dmb
1143 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1762 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1144 ; ARM32: cmp [[V0]], {{r[0-9]+}} 1763 ; ARM32: cmp [[V0]], {{r[0-9]+}}
1145 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} 1764 ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
1146 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1765 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1147 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1766 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1148 ; ARM32: cmp [[SUCCESS]], #0 1767 ; ARM32: cmp [[SUCCESS]], #0
1149 ; ARM32: bne 1768 ; ARM32: bne
1150 ; ARM32: dmb 1769 ; ARM32: dmb
1770 ; MIPS32-LABEL: test_atomic_cmpxchg_64
1771 ; MIPS32: sync
1772 ; MIPS32: ll
1773 ; MIPS32: bne
1774 ; MIPS32: sc
1775 ; MIPS32: beq
1776 ; MIPS32: ll
1777 ; MIPS32: bne
1778 ; MIPS32: sc
1779 ; MIPS32: beq
1780 ; MIPS32: sync
1781
1151 1782
1152 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { 1783 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) {
1153 entry: 1784 entry:
1154 %ptr = inttoptr i32 %iptr to i64* 1785 %ptr = inttoptr i32 %iptr to i64*
1155 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, 1786 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef,
1156 i64 %desired, i32 6, i32 6) 1787 i64 %desired, i32 6, i32 6)
1157 ret i64 %old 1788 ret i64 %old
1158 } 1789 }
1159 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef 1790 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef
1160 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] 1791 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0]
1161 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef 1792 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef
1162 ; ARM32: mov r{{[0-9]+}}, #0 1793 ; ARM32: mov r{{[0-9]+}}, #0
1163 ; ARM32: mov r{{[0-9]+}}, #0 1794 ; ARM32: mov r{{[0-9]+}}, #0
1164 ; ARM32: dmb 1795 ; ARM32: dmb
1165 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1796 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1166 ; ARM32: cmp [[V0]], {{r[0-9]+}} 1797 ; ARM32: cmp [[V0]], {{r[0-9]+}}
1167 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} 1798 ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
1168 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1799 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1169 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1800 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1170 ; ARM32: cmp [[SUCCESS]], #0 1801 ; ARM32: cmp [[SUCCESS]], #0
1171 ; ARM32: bne 1802 ; ARM32: bne
1172 ; ARM32: dmb 1803 ; ARM32: dmb
1804 ; MIPS32-LABEL: test_atomic_cmpxchg_64_undef
1805 ; MIPS32: sync
1806 ; MIPS32: ll
1807 ; MIPS32: bne
1808 ; MIPS32: sc
1809 ; MIPS32: beq
1810 ; MIPS32: ll
1811 ; MIPS32: bne
1812 ; MIPS32: sc
1813 ; MIPS32: beq
1814 ; MIPS32: sync
1173 1815
1174 ; Test a case where %old really does need to be copied out of edx:eax. 1816 ; Test a case where %old really does need to be copied out of edx:eax.
1175 define internal void @test_atomic_cmpxchg_64_store( 1817 define internal void @test_atomic_cmpxchg_64_store(
1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { 1818 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) {
1177 entry: 1819 entry:
1178 %ptr = inttoptr i32 %iptr to i64* 1820 %ptr = inttoptr i32 %iptr to i64*
1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, 1821 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
1180 i64 %desired, i32 6, i32 6) 1822 i64 %desired, i32 6, i32 6)
1181 %__6 = inttoptr i32 %ret_iptr to i64* 1823 %__6 = inttoptr i32 %ret_iptr to i64*
1182 store i64 %old, i64* %__6, align 1 1824 store i64 %old, i64* %__6, align 1
(...skipping 13 matching lines...) Expand all
1196 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1838 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1197 ; ARM32: cmp [[V0]], {{r[0-9]+}} 1839 ; ARM32: cmp [[V0]], {{r[0-9]+}}
1198 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} 1840 ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
1199 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1841 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1200 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1842 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1201 ; ARM32: cmp [[SUCCESS]], #0 1843 ; ARM32: cmp [[SUCCESS]], #0
1202 ; ARM32: bne 1844 ; ARM32: bne
1203 ; ARM32: dmb 1845 ; ARM32: dmb
1204 ; ARM32: str 1846 ; ARM32: str
1205 ; ARM32: str 1847 ; ARM32: str
1848 ; MIPS32-LABEL: test_atomic_cmpxchg_64_store
1849 ; MIPS32: sync
1850 ; MIPS32: ll
1851 ; MIPS32: bne
1852 ; MIPS32: sc
1853 ; MIPS32: beq
1854 ; MIPS32: ll
1855 ; MIPS32: bne
1856 ; MIPS32: sc
1857 ; MIPS32: beq
1858 ; MIPS32: sync
1859
1206 1860
1207 ; Test with some more register pressure. When we have an alloca, ebp is 1861 ; Test with some more register pressure. When we have an alloca, ebp is
1208 ; used to manage the stack frame, so it cannot be used as a register either. 1862 ; used to manage the stack frame, so it cannot be used as a register either.
1209 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, 1863 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected,
1210 i64 %desired) { 1864 i64 %desired) {
1211 entry: 1865 entry:
1212 br label %eblock ; Disable alloca optimization 1866 br label %eblock ; Disable alloca optimization
1213 eblock: 1867 eblock:
1214 %alloca_ptr = alloca i8, i32 16, align 16 1868 %alloca_ptr = alloca i8, i32 16, align 16
1215 %ptr = inttoptr i32 %iptr to i64* 1869 %ptr = inttoptr i32 %iptr to i64*
(...skipping 23 matching lines...) Expand all
1239 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca 1893 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca
1240 ; ARM32: dmb 1894 ; ARM32: dmb
1241 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1895 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1242 ; ARM32: cmp [[V0]], {{r[0-9]+}} 1896 ; ARM32: cmp [[V0]], {{r[0-9]+}}
1243 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} 1897 ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
1244 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1898 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1245 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} 1899 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
1246 ; ARM32: cmp [[SUCCESS]], #0 1900 ; ARM32: cmp [[SUCCESS]], #0
1247 ; ARM32: bne 1901 ; ARM32: bne
1248 ; ARM32: dmb 1902 ; ARM32: dmb
1903 ; MIPS32-LABEL: test_atomic_cmpxchg_64_alloca
1904 ; MIPS32: sync
1905 ; MIPS32: ll
1906 ; MIPS32: bne
1907 ; MIPS32: sc
1908 ; MIPS32: beq
1909 ; MIPS32: ll
1910 ; MIPS32: bne
1911 ; MIPS32: sc
1912 ; MIPS32: beq
1913 ; MIPS32: sync
1249 1914
1250 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, 1915 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected,
1251 i32 %desired) { 1916 i32 %desired) {
1252 entry: 1917 entry:
1253 %ptr = inttoptr i32 %iptr to i32* 1918 %ptr = inttoptr i32 %iptr to i32*
1254 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 1919 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
1255 i32 %desired, i32 6, i32 6) 1920 i32 %desired, i32 6, i32 6)
1256 ret i32 0 1921 ret i32 0
1257 } 1922 }
1258 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored 1923 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored
1259 ; CHECK: mov eax,{{.*}} 1924 ; CHECK: mov eax,{{.*}}
1260 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] 1925 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
1261 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored 1926 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored
1262 ; ARM32: dmb 1927 ; ARM32: dmb
1263 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1928 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1264 ; ARM32: cmp [[V]], {{r[0-9]+}} 1929 ; ARM32: cmp [[V]], {{r[0-9]+}}
1265 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1930 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1266 ; ARM32: strexeq [[SUCCESS]] 1931 ; ARM32: strexeq [[SUCCESS]]
1267 ; ARM32: cmp [[SUCCESS]], #0 1932 ; ARM32: cmp [[SUCCESS]], #0
1268 ; ARM32: bne 1933 ; ARM32: bne
1269 ; ARM32: dmb 1934 ; ARM32: dmb
1935 ; MIPS32-LABEL: test_atomic_cmpxchg_32_ignored
1936 ; MIPS32: sync
1937 ; MIPS32: ll
1938 ; MIPS32: bne
1939 ; MIPS32: sc
1940 ; MIPS32: beq {{.*}}, $zero, {{.*}}
1941 ; MIPS32: sync
1270 1942
1271 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, 1943 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected,
1272 i64 %desired) { 1944 i64 %desired) {
1273 entry: 1945 entry:
1274 %ptr = inttoptr i32 %iptr to i64* 1946 %ptr = inttoptr i32 %iptr to i64*
1275 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, 1947 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
1276 i64 %desired, i32 6, i32 6) 1948 i64 %desired, i32 6, i32 6)
1277 ret i64 0 1949 ret i64 0
1278 } 1950 }
1279 ; CHECK-LABEL: test_atomic_cmpxchg_64_ignored 1951 ; CHECK-LABEL: test_atomic_cmpxchg_64_ignored
1280 ; CHECK: push ebx 1952 ; CHECK: push ebx
1281 ; CHECK-DAG: mov edx 1953 ; CHECK-DAG: mov edx
1282 ; CHECK-DAG: mov eax 1954 ; CHECK-DAG: mov eax
1283 ; CHECK-DAG: mov ecx 1955 ; CHECK-DAG: mov ecx
1284 ; CHECK-DAG: mov ebx 1956 ; CHECK-DAG: mov ebx
1285 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] 1957 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0]
1286 ; ARM32-LABEL: test_atomic_cmpxchg_64_ignored 1958 ; ARM32-LABEL: test_atomic_cmpxchg_64_ignored
1287 ; ARM32: dmb 1959 ; ARM32: dmb
1288 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} 1960 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
1289 ; ARM32: cmp [[V0]], {{r[0-9]+}} 1961 ; ARM32: cmp [[V0]], {{r[0-9]+}}
1290 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} 1962 ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
1291 ; ARM32: movne [[SUCCESS:r[0-9]+]], 1963 ; ARM32: movne [[SUCCESS:r[0-9]+]],
1292 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} 1964 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
1293 ; ARM32: cmp [[SUCCESS]], #0 1965 ; ARM32: cmp [[SUCCESS]], #0
1294 ; ARM32: bne 1966 ; ARM32: bne
1295 ; ARM32: dmb 1967 ; ARM32: dmb
1968 ; MIPS32-LABEL: test_atomic_cmpxchg_64_ignored
1969 ; MIPS32: sync
1970 ; MIPS32: ll
1971 ; MIPS32: bne
1972 ; MIPS32: sc
1973 ; MIPS32: beq
1974 ; MIPS32: ll
1975 ; MIPS32: bne
1976 ; MIPS32: sc
1977 ; MIPS32: beq
1978 ; MIPS32: sync
1296 1979
1297 ;;;; Fence and is-lock-free. 1980 ;;;; Fence and is-lock-free.
1298 1981
1299 define internal void @test_atomic_fence() { 1982 define internal void @test_atomic_fence() {
1300 entry: 1983 entry:
1301 call void @llvm.nacl.atomic.fence(i32 6) 1984 call void @llvm.nacl.atomic.fence(i32 6)
1302 ret void 1985 ret void
1303 } 1986 }
1304 ; CHECK-LABEL: test_atomic_fence 1987 ; CHECK-LABEL: test_atomic_fence
1305 ; CHECK: mfence 1988 ; CHECK: mfence
1306 ; ARM32-LABEL: test_atomic_fence 1989 ; ARM32-LABEL: test_atomic_fence
1307 ; ARM32: dmb sy 1990 ; ARM32: dmb sy
1991 ; MIPS32-LABEL: test_atomic_fence
1992 ; MIPS32: sync
1308 1993
1309 define internal void @test_atomic_fence_all() { 1994 define internal void @test_atomic_fence_all() {
1310 entry: 1995 entry:
1311 call void @llvm.nacl.atomic.fence.all() 1996 call void @llvm.nacl.atomic.fence.all()
1312 ret void 1997 ret void
1313 } 1998 }
1314 ; CHECK-LABEL: test_atomic_fence_all 1999 ; CHECK-LABEL: test_atomic_fence_all
1315 ; CHECK: mfence 2000 ; CHECK: mfence
1316 ; ARM32-LABEL: test_atomic_fence_all 2001 ; ARM32-LABEL: test_atomic_fence_all
1317 ; ARM32: dmb sy 2002 ; ARM32: dmb sy
2003 ; MIPS32-LABEL: test_atomic_fence_all
2004 ; MIPS32: sync
1318 2005
1319 define internal i32 @test_atomic_is_lock_free(i32 %iptr) { 2006 define internal i32 @test_atomic_is_lock_free(i32 %iptr) {
1320 entry: 2007 entry:
1321 %ptr = inttoptr i32 %iptr to i8* 2008 %ptr = inttoptr i32 %iptr to i8*
1322 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr) 2009 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
1323 %r = zext i1 %i to i32 2010 %r = zext i1 %i to i32
1324 ret i32 %r 2011 ret i32 %r
1325 } 2012 }
1326 ; CHECK-LABEL: test_atomic_is_lock_free 2013 ; CHECK-LABEL: test_atomic_is_lock_free
1327 ; CHECK: mov {{.*}},0x1 2014 ; CHECK: mov {{.*}},0x1
1328 ; ARM32-LABEL: test_atomic_is_lock_free 2015 ; ARM32-LABEL: test_atomic_is_lock_free
1329 ; ARM32: mov {{.*}}, #1 2016 ; ARM32: mov {{.*}}, #1
2017 ; MIPS32-LABEL: test_atomic_is_lock_free
2018 ; MIPS32: addiu {{.*}}, $zero, 1
1330 2019
1331 define internal i32 @test_not_lock_free(i32 %iptr) { 2020 define internal i32 @test_not_lock_free(i32 %iptr) {
1332 entry: 2021 entry:
1333 %ptr = inttoptr i32 %iptr to i8* 2022 %ptr = inttoptr i32 %iptr to i8*
1334 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 7, i8* %ptr) 2023 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 7, i8* %ptr)
1335 %r = zext i1 %i to i32 2024 %r = zext i1 %i to i32
1336 ret i32 %r 2025 ret i32 %r
1337 } 2026 }
1338 ; CHECK-LABEL: test_not_lock_free 2027 ; CHECK-LABEL: test_not_lock_free
1339 ; CHECK: mov {{.*}},0x0 2028 ; CHECK: mov {{.*}},0x0
1340 ; ARM32-LABEL: test_not_lock_free 2029 ; ARM32-LABEL: test_not_lock_free
1341 ; ARM32: mov {{.*}}, #0 2030 ; ARM32: mov {{.*}}, #0
2031 ; MIPS32-LABEL: test_not_lock_free
2032 ; MIPS32: addiu {{.*}}, $zero, 0
1342 2033
1343 define internal i32 @test_atomic_is_lock_free_ignored(i32 %iptr) { 2034 define internal i32 @test_atomic_is_lock_free_ignored(i32 %iptr) {
1344 entry: 2035 entry:
1345 %ptr = inttoptr i32 %iptr to i8* 2036 %ptr = inttoptr i32 %iptr to i8*
1346 %ignored = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr) 2037 %ignored = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
1347 ret i32 0 2038 ret i32 0
1348 } 2039 }
1349 ; CHECK-LABEL: test_atomic_is_lock_free_ignored 2040 ; CHECK-LABEL: test_atomic_is_lock_free_ignored
1350 ; CHECK: mov {{.*}},0x0 2041 ; CHECK: mov {{.*}},0x0
1351 ; This can get optimized out, because it's side-effect-free. 2042 ; This can get optimized out, because it's side-effect-free.
1352 ; O2-LABEL: test_atomic_is_lock_free_ignored 2043 ; O2-LABEL: test_atomic_is_lock_free_ignored
1353 ; O2-NOT: mov {{.*}}, 1 2044 ; O2-NOT: mov {{.*}}, 1
1354 ; O2: mov {{.*}},0x0 2045 ; O2: mov {{.*}},0x0
1355 ; ARM32O2-LABEL: test_atomic_is_lock_free_ignored 2046 ; ARM32O2-LABEL: test_atomic_is_lock_free_ignored
1356 ; ARM32O2-NOT: mov {{.*}}, #1 2047 ; ARM32O2-NOT: mov {{.*}}, #1
1357 ; ARM32O2: mov {{.*}}, #0 2048 ; ARM32O2: mov {{.*}}, #0
2049 ; MIPS32O2-LABEL: test_atomic_is_lock_free
2050 ; MIPS32O2-NOT: addiu {{.*}}, $zero, 1
2051 ; MIPS32O2: addiu {{.*}}, $zero, 0
1358 2052
1359 ; TODO(jvoung): at some point we can take advantage of the 2053 ; TODO(jvoung): at some point we can take advantage of the
1360 ; fact that nacl.atomic.is.lock.free will resolve to a constant 2054 ; fact that nacl.atomic.is.lock.free will resolve to a constant
1361 ; (which adds DCE opportunities). Once we optimize, the test expectations 2055 ; (which adds DCE opportunities). Once we optimize, the test expectations
1362 ; for this case should change. 2056 ; for this case should change.
1363 define internal i32 @test_atomic_is_lock_free_can_dce(i32 %iptr, i32 %x, 2057 define internal i32 @test_atomic_is_lock_free_can_dce(i32 %iptr, i32 %x,
1364 i32 %y) { 2058 i32 %y) {
1365 entry: 2059 entry:
1366 %ptr = inttoptr i32 %iptr to i8* 2060 %ptr = inttoptr i32 %iptr to i8*
1367 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr) 2061 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 br i1 %cmp, label %done, label %body 2155 br i1 %cmp, label %done, label %body
1462 done: 2156 done:
1463 ret void 2157 ret void
1464 } 2158 }
1465 ; O2-LABEL: test_cmpxchg8b_regalloc 2159 ; O2-LABEL: test_cmpxchg8b_regalloc
1466 ;;; eax and some other register will be used in the cmpxchg instruction. 2160 ;;; eax and some other register will be used in the cmpxchg instruction.
1467 ; O2: lock cmpxchg8b QWORD PTR 2161 ; O2: lock cmpxchg8b QWORD PTR
1468 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. 2162 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable.
1469 ; O2-NOT: ,{{eax|ecx|edx|ebx}} 2163 ; O2-NOT: ,{{eax|ecx|edx|ebx}}
1470 ; O2: pop ebx 2164 ; O2: pop ebx
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698