OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |