Chromium Code Reviews| 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 |