| 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 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) | 239 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) |
| 240 ret void | 240 ret void |
| 241 } | 241 } |
| 242 ; CHECK-LABEL: test_atomic_store_64_const | 242 ; CHECK-LABEL: test_atomic_store_64_const |
| 243 ; CHECK: mov {{.*}},0x73ce2ff2 | 243 ; CHECK: mov {{.*}},0x73ce2ff2 |
| 244 ; CHECK: mov {{.*}},0xb3a | 244 ; CHECK: mov {{.*}},0xb3a |
| 245 ; CHECK: movq x{{.*}},QWORD | 245 ; CHECK: movq x{{.*}},QWORD |
| 246 ; CHECK: movq QWORD {{.*}},x{{.*}} | 246 ; CHECK: movq QWORD {{.*}},x{{.*}} |
| 247 ; CHECK: mfence | 247 ; CHECK: mfence |
| 248 ; ARM32-LABEL: test_atomic_store_64_const | 248 ; ARM32-LABEL: test_atomic_store_64_const |
| 249 ; ARM32: dmb | |
| 250 ; ARM32: movw [[T0:r[0-9]+]], #12274 | 249 ; ARM32: movw [[T0:r[0-9]+]], #12274 |
| 251 ; ARM32: movt [[T0]], #29646 | 250 ; ARM32: movt [[T0]], #29646 |
| 252 ; ARM32: movw r{{[0-9]+}}, #2874 | 251 ; ARM32: movw r{{[0-9]+}}, #2874 |
| 252 ; ARM32: dmb |
| 253 ; ARM32: .L[[RETRY:.*]]: | 253 ; ARM32: .L[[RETRY:.*]]: |
| 254 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] | 254 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [[MEM:.*]] |
| 255 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] | 255 ; ARM32: strexd [[S:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}, [[MEM]] |
| 256 ; ARM32: cmp [[S]], #0 | 256 ; ARM32: cmp [[S]], #0 |
| 257 ; ARM32: bne .L[[RETRY]] | 257 ; ARM32: bne .L[[RETRY]] |
| 258 ; ARM32: dmb | 258 ; ARM32: dmb |
| 259 | 259 |
| 260 ;;; RMW | 260 ;;; RMW |
| 261 | 261 |
| 262 ;; add | 262 ;; add |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 ; CHECK: adc ecx,{{.*e.[^x]}} | 335 ; CHECK: adc ecx,{{.*e.[^x]}} |
| 336 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). | 336 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). |
| 337 ; It can be esi, edi, or ebp though, for example (so we need to be careful | 337 ; It can be esi, edi, or ebp though, for example (so we need to be careful |
| 338 ; about rejecting eb* and ed*.) | 338 ; about rejecting eb* and ed*.) |
| 339 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 339 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 340 ; CHECK: jne [[LABEL]] | 340 ; CHECK: jne [[LABEL]] |
| 341 ; ARM32-LABEL: test_atomic_rmw_add_64 | 341 ; ARM32-LABEL: test_atomic_rmw_add_64 |
| 342 ; ARM32: dmb | 342 ; ARM32: dmb |
| 343 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 343 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 344 ; ARM32: adds | 344 ; ARM32: adds |
| 345 ; ARM32-NEXT: adc | 345 ; ARM32: adc |
| 346 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 346 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 347 ; ARM32: bne | 347 ; ARM32: bne |
| 348 ; ARM32: dmb | 348 ; ARM32: dmb |
| 349 | 349 |
| 350 ; Same test as above, but with a global address to test FakeUse issues. | 350 ; 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) { | 351 define internal i64 @test_atomic_rmw_add_64_global(i64 %v) { |
| 352 entry: | 352 entry: |
| 353 %ptr = bitcast [8 x i8]* @SzGlobal64 to i64* | 353 %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) | 354 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) |
| 355 ret i64 %a | 355 ret i64 %a |
| 356 } | 356 } |
| 357 ; CHECK-LABEL: test_atomic_rmw_add_64_global | 357 ; CHECK-LABEL: test_atomic_rmw_add_64_global |
| 358 ; ARM32-LABEL: test_atomic_rmw_add_64_global | 358 ; ARM32-LABEL: test_atomic_rmw_add_64_global |
| 359 ; ARM32: dmb | 359 ; ARM32: dmb |
| 360 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 360 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 361 ; ARM32: adds | 361 ; ARM32: adds |
| 362 ; ARM32-NEXT: adc | 362 ; ARM32: adc |
| 363 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 363 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 364 ; ARM32: bne | 364 ; ARM32: bne |
| 365 ; ARM32: dmb | 365 ; ARM32: dmb |
| 366 | 366 |
| 367 ; Test with some more register pressure. When we have an alloca, ebp is | 367 ; 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. | 368 ; used to manage the stack frame, so it cannot be used as a register either. |
| 369 declare void @use_ptr(i32 %iptr) | 369 declare void @use_ptr(i32 %iptr) |
| 370 | 370 |
| 371 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) { | 371 define internal i64 @test_atomic_rmw_add_64_alloca(i32 %iptr, i64 %v) { |
| 372 entry: | 372 entry: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 393 ; It also cannot be ebp since we use that for alloca. Also make sure it's | 393 ; It also cannot be ebp since we use that for alloca. Also make sure it's |
| 394 ; not esp, since that's the stack pointer and mucking with it will break | 394 ; not esp, since that's the stack pointer and mucking with it will break |
| 395 ; the later use_ptr function call. | 395 ; the later use_ptr function call. |
| 396 ; That pretty much leaves esi, or edi as the only viable registers. | 396 ; That pretty much leaves esi, or edi as the only viable registers. |
| 397 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] | 397 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] |
| 398 ; CHECK: call {{.*}} R_{{.*}} use_ptr | 398 ; CHECK: call {{.*}} R_{{.*}} use_ptr |
| 399 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca | 399 ; ARM32-LABEL: test_atomic_rmw_add_64_alloca |
| 400 ; ARM32: dmb | 400 ; ARM32: dmb |
| 401 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 401 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 402 ; ARM32: adds | 402 ; ARM32: adds |
| 403 ; ARM32-NEXT: adc | 403 ; ARM32: adc |
| 404 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 404 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 405 ; ARM32: bne | 405 ; ARM32: bne |
| 406 ; ARM32: dmb | 406 ; ARM32: dmb |
| 407 | 407 |
| 408 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) { | 408 define internal i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) { |
| 409 entry: | 409 entry: |
| 410 %ptr = inttoptr i32 %iptr to i32* | 410 %ptr = inttoptr i32 %iptr to i32* |
| 411 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) | 411 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) |
| 412 ret i32 %v | 412 ret i32 %v |
| 413 } | 413 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 450 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
| 451 ; CHECK: add ebx,{{.*e.[^x]}} | 451 ; CHECK: add ebx,{{.*e.[^x]}} |
| 452 ; CHECK: mov ecx,edx | 452 ; CHECK: mov ecx,edx |
| 453 ; CHECK: adc ecx,{{.*e.[^x]}} | 453 ; CHECK: adc ecx,{{.*e.[^x]}} |
| 454 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 454 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 455 ; CHECK: jne [[LABEL]] | 455 ; CHECK: jne [[LABEL]] |
| 456 ; ARM32-LABEL: test_atomic_rmw_add_64_loop | 456 ; ARM32-LABEL: test_atomic_rmw_add_64_loop |
| 457 ; ARM32: dmb | 457 ; ARM32: dmb |
| 458 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 458 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 459 ; ARM32: adds | 459 ; ARM32: adds |
| 460 ; ARM32-NEXT: adc | 460 ; ARM32: adc |
| 461 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 461 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 462 ; ARM32: bne | 462 ; ARM32: bne |
| 463 ; ARM32: dmb | 463 ; ARM32: dmb |
| 464 ; ARM32: b | 464 ; ARM32: b |
| 465 | 465 |
| 466 ;; sub | 466 ;; sub |
| 467 | 467 |
| 468 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { | 468 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { |
| 469 entry: | 469 entry: |
| 470 %trunc = trunc i32 %v to i8 | 470 %trunc = trunc i32 %v to i8 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 536 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
| 537 ; CHECK: sub ebx,{{.*e.[^x]}} | 537 ; CHECK: sub ebx,{{.*e.[^x]}} |
| 538 ; CHECK: mov ecx,edx | 538 ; CHECK: mov ecx,edx |
| 539 ; CHECK: sbb ecx,{{.*e.[^x]}} | 539 ; CHECK: sbb ecx,{{.*e.[^x]}} |
| 540 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 540 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 541 ; CHECK: jne [[LABEL]] | 541 ; CHECK: jne [[LABEL]] |
| 542 ; ARM32-LABEL: test_atomic_rmw_sub_64 | 542 ; ARM32-LABEL: test_atomic_rmw_sub_64 |
| 543 ; ARM32: dmb | 543 ; ARM32: dmb |
| 544 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 544 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 545 ; ARM32: subs | 545 ; ARM32: subs |
| 546 ; ARM32-NEXT: sbc | 546 ; ARM32: sbc |
| 547 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 547 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 548 ; ARM32: bne | 548 ; ARM32: bne |
| 549 ; ARM32: dmb | 549 ; ARM32: dmb |
| 550 | 550 |
| 551 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) { | 551 define internal i32 @test_atomic_rmw_sub_32_ignored(i32 %iptr, i32 %v) { |
| 552 entry: | 552 entry: |
| 553 %ptr = inttoptr i32 %iptr to i32* | 553 %ptr = inttoptr i32 %iptr to i32* |
| 554 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) | 554 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) |
| 555 ret i32 %v | 555 ret i32 %v |
| 556 } | 556 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) { | 595 define internal i32 @test_atomic_rmw_or_8_global(i32 %v) { |
| 596 entry: | 596 entry: |
| 597 %trunc = trunc i32 %v to i8 | 597 %trunc = trunc i32 %v to i8 |
| 598 %ptr = bitcast [1 x i8]* @SzGlobal8 to i8* | 598 %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) | 599 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) |
| 600 %a_ext = zext i8 %a to i32 | 600 %a_ext = zext i8 %a to i32 |
| 601 ret i32 %a_ext | 601 ret i32 %a_ext |
| 602 } | 602 } |
| 603 ; CHECK-LABEL: test_atomic_rmw_or_8_global | 603 ; CHECK-LABEL: test_atomic_rmw_or_8_global |
| 604 ; ARM32-LABEL: test_atomic_rmw_or_8_global | 604 ; ARM32-LABEL: test_atomic_rmw_or_8_global |
| 605 ; ARM32: dmb |
| 605 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8 | 606 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal8 |
| 606 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8 | 607 ; ARM32: movt [[PTR]], #:upper16:SzGlobal8 |
| 607 ; ARM32: dmb | |
| 608 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 608 ; ARM32: ldrexb r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 609 ; ARM32: orr | 609 ; ARM32: orr |
| 610 ; ARM32: strexb | 610 ; ARM32: strexb |
| 611 ; ARM32: bne | 611 ; ARM32: bne |
| 612 ; ARM32: dmb | 612 ; ARM32: dmb |
| 613 | 613 |
| 614 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { | 614 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { |
| 615 entry: | 615 entry: |
| 616 %trunc = trunc i32 %v to i16 | 616 %trunc = trunc i32 %v to i16 |
| 617 %ptr = inttoptr i32 %iptr to i16* | 617 %ptr = inttoptr i32 %iptr to i16* |
| (...skipping 18 matching lines...) Expand all Loading... |
| 636 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) { | 636 define internal i32 @test_atomic_rmw_or_16_global(i32 %v) { |
| 637 entry: | 637 entry: |
| 638 %trunc = trunc i32 %v to i16 | 638 %trunc = trunc i32 %v to i16 |
| 639 %ptr = bitcast [2 x i8]* @SzGlobal16 to i16* | 639 %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) | 640 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) |
| 641 %a_ext = zext i16 %a to i32 | 641 %a_ext = zext i16 %a to i32 |
| 642 ret i32 %a_ext | 642 ret i32 %a_ext |
| 643 } | 643 } |
| 644 ; CHECK-LABEL: test_atomic_rmw_or_16_global | 644 ; CHECK-LABEL: test_atomic_rmw_or_16_global |
| 645 ; ARM32-LABEL: test_atomic_rmw_or_16_global | 645 ; ARM32-LABEL: test_atomic_rmw_or_16_global |
| 646 ; ARM32: dmb |
| 646 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16 | 647 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal16 |
| 647 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16 | 648 ; ARM32: movt [[PTR]], #:upper16:SzGlobal16 |
| 648 ; ARM32: dmb | |
| 649 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 649 ; ARM32: ldrexh r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 650 ; ARM32: orr | 650 ; ARM32: orr |
| 651 ; ARM32: strexh | 651 ; ARM32: strexh |
| 652 ; ARM32: bne | 652 ; ARM32: bne |
| 653 ; ARM32: dmb | 653 ; ARM32: dmb |
| 654 | 654 |
| 655 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { | 655 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { |
| 656 entry: | 656 entry: |
| 657 %ptr = inttoptr i32 %iptr to i32* | 657 %ptr = inttoptr i32 %iptr to i32* |
| 658 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) | 658 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 673 | 673 |
| 674 ; Same test as above, but with a global address to test FakeUse issues. | 674 ; 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) { | 675 define internal i32 @test_atomic_rmw_or_32_global(i32 %v) { |
| 676 entry: | 676 entry: |
| 677 %ptr = bitcast [4 x i8]* @SzGlobal32 to i32* | 677 %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) | 678 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
| 679 ret i32 %a | 679 ret i32 %a |
| 680 } | 680 } |
| 681 ; CHECK-LABEL: test_atomic_rmw_or_32_global | 681 ; CHECK-LABEL: test_atomic_rmw_or_32_global |
| 682 ; ARM32-LABEL: test_atomic_rmw_or_32_global | 682 ; ARM32-LABEL: test_atomic_rmw_or_32_global |
| 683 ; ARM32: dmb |
| 683 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32 | 684 ; ARM32: movw [[PTR:r[0-9]+]], #:lower16:SzGlobal32 |
| 684 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32 | 685 ; ARM32: movt [[PTR]], #:upper16:SzGlobal32 |
| 685 ; ARM32: dmb | |
| 686 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 686 ; ARM32: ldrex r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 687 ; ARM32: orr | 687 ; ARM32: orr |
| 688 ; ARM32: strex | 688 ; ARM32: strex |
| 689 ; ARM32: bne | 689 ; ARM32: bne |
| 690 ; ARM32: dmb | 690 ; ARM32: dmb |
| 691 | 691 |
| 692 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { | 692 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { |
| 693 entry: | 693 entry: |
| 694 %ptr = inttoptr i32 %iptr to i64* | 694 %ptr = inttoptr i32 %iptr to i64* |
| 695 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) | 695 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) |
| 696 ret i64 %a | 696 ret i64 %a |
| 697 } | 697 } |
| 698 ; CHECK-LABEL: test_atomic_rmw_or_64 | 698 ; CHECK-LABEL: test_atomic_rmw_or_64 |
| 699 ; CHECK: push ebx | 699 ; CHECK: push ebx |
| 700 ; CHECK: mov eax,DWORD PTR [{{.*}}] | 700 ; CHECK: mov eax,DWORD PTR [{{.*}}] |
| 701 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] | 701 ; CHECK: mov edx,DWORD PTR [{{.*}}+0x4] |
| 702 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 702 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
| 703 ; CHECK: or ebx,{{.*e.[^x]}} | 703 ; CHECK: or ebx,{{.*e.[^x]}} |
| 704 ; CHECK: mov ecx,edx | 704 ; CHECK: mov ecx,edx |
| 705 ; CHECK: or ecx,{{.*e.[^x]}} | 705 ; CHECK: or ecx,{{.*e.[^x]}} |
| 706 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 706 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 707 ; CHECK: jne [[LABEL]] | 707 ; CHECK: jne [[LABEL]] |
| 708 ; ARM32-LABEL: test_atomic_rmw_or_64 | 708 ; ARM32-LABEL: test_atomic_rmw_or_64 |
| 709 ; ARM32: dmb | 709 ; ARM32: dmb |
| 710 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 710 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 711 ; ARM32: orr | 711 ; ARM32: orr |
| 712 ; ARM32-NEXT: orr | 712 ; ARM32: orr |
| 713 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 713 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 714 ; ARM32: bne | 714 ; ARM32: bne |
| 715 ; ARM32: dmb | 715 ; ARM32: dmb |
| 716 | 716 |
| 717 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) { | 717 define internal i32 @test_atomic_rmw_or_32_ignored(i32 %iptr, i32 %v) { |
| 718 entry: | 718 entry: |
| 719 %ptr = inttoptr i32 %iptr to i32* | 719 %ptr = inttoptr i32 %iptr to i32* |
| 720 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) | 720 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) |
| 721 ret i32 %v | 721 ret i32 %v |
| 722 } | 722 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax | 812 ; CHECK: [[LABEL:[^ ]*]]: {{.*}} mov ebx,eax |
| 813 ; CHECK: and ebx,{{.*e.[^x]}} | 813 ; CHECK: and ebx,{{.*e.[^x]}} |
| 814 ; CHECK: mov ecx,edx | 814 ; CHECK: mov ecx,edx |
| 815 ; CHECK: and ecx,{{.*e.[^x]}} | 815 ; CHECK: and ecx,{{.*e.[^x]}} |
| 816 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 816 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 817 ; CHECK: jne [[LABEL]] | 817 ; CHECK: jne [[LABEL]] |
| 818 ; ARM32-LABEL: test_atomic_rmw_and_64 | 818 ; ARM32-LABEL: test_atomic_rmw_and_64 |
| 819 ; ARM32: dmb | 819 ; ARM32: dmb |
| 820 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 820 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 821 ; ARM32: and | 821 ; ARM32: and |
| 822 ; ARM32-NEXT: and | 822 ; ARM32: and |
| 823 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 823 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 824 ; ARM32: bne | 824 ; ARM32: bne |
| 825 ; ARM32: dmb | 825 ; ARM32: dmb |
| 826 | 826 |
| 827 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) { | 827 define internal i32 @test_atomic_rmw_and_32_ignored(i32 %iptr, i32 %v) { |
| 828 entry: | 828 entry: |
| 829 %ptr = inttoptr i32 %iptr to i32* | 829 %ptr = inttoptr i32 %iptr to i32* |
| 830 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) | 830 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) |
| 831 ret i32 %v | 831 ret i32 %v |
| 832 } | 832 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 ; CHECK: mov ebx,eax | 920 ; CHECK: mov ebx,eax |
| 921 ; CHECK: or ebx,{{.*e.[^x]}} | 921 ; CHECK: or ebx,{{.*e.[^x]}} |
| 922 ; CHECK: mov ecx,edx | 922 ; CHECK: mov ecx,edx |
| 923 ; CHECK: or ecx,{{.*e.[^x]}} | 923 ; CHECK: or ecx,{{.*e.[^x]}} |
| 924 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 924 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 925 ; CHECK: jne | 925 ; CHECK: jne |
| 926 ; ARM32-LABEL: test_atomic_rmw_xor_64 | 926 ; ARM32-LABEL: test_atomic_rmw_xor_64 |
| 927 ; ARM32: dmb | 927 ; ARM32: dmb |
| 928 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 928 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 929 ; ARM32: eor | 929 ; ARM32: eor |
| 930 ; ARM32-NEXT: eor | 930 ; ARM32: eor |
| 931 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] | 931 ; ARM32: strexd r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, [r{{[0-9]+}}] |
| 932 ; ARM32: bne | 932 ; ARM32: bne |
| 933 ; ARM32: dmb | 933 ; ARM32: dmb |
| 934 | 934 |
| 935 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) { | 935 define internal i32 @test_atomic_rmw_xor_32_ignored(i32 %iptr, i32 %v) { |
| 936 entry: | 936 entry: |
| 937 %ptr = inttoptr i32 %iptr to i32* | 937 %ptr = inttoptr i32 %iptr to i32* |
| 938 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) | 938 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) |
| 939 ret i32 %v | 939 ret i32 %v |
| 940 } | 940 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 } | 1060 } |
| 1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 | 1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 |
| 1062 ; CHECK: mov eax,{{.*}} | 1062 ; CHECK: mov eax,{{.*}} |
| 1063 ; Need to check that eax isn't used as the address register or the desired. | 1063 ; 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. | 1064 ; since it is already used as the *expected* register. |
| 1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l | 1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l |
| 1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 | 1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 |
| 1067 ; ARM32: dmb | 1067 ; ARM32: dmb |
| 1068 ; ARM32: ldrexb | 1068 ; ARM32: ldrexb |
| 1069 ; ARM32: cmp | 1069 ; ARM32: cmp |
| 1070 ; ARM32: {{strb|mov}} |
| 1070 ; ARM32: strexbeq | 1071 ; ARM32: strexbeq |
| 1071 ; ARM32: {{strb|mov}}ne | |
| 1072 ; ARM32: cmpeq | 1072 ; ARM32: cmpeq |
| 1073 ; ARM32: bne | 1073 ; ARM32: bne |
| 1074 ; ARM32: dmb | 1074 ; ARM32: dmb |
| 1075 | 1075 |
| 1076 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, | 1076 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, |
| 1077 i32 %desired) { | 1077 i32 %desired) { |
| 1078 entry: | 1078 entry: |
| 1079 %trunc_exp = trunc i32 %expected to i16 | 1079 %trunc_exp = trunc i32 %expected to i16 |
| 1080 %trunc_des = trunc i32 %desired to i16 | 1080 %trunc_des = trunc i32 %desired to i16 |
| 1081 %ptr = inttoptr i32 %iptr to i16* | 1081 %ptr = inttoptr i32 %iptr to i16* |
| 1082 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, | 1082 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, |
| 1083 i16 %trunc_des, i32 6, i32 6) | 1083 i16 %trunc_des, i32 6, i32 6) |
| 1084 %old_ext = zext i16 %old to i32 | 1084 %old_ext = zext i16 %old to i32 |
| 1085 ret i32 %old_ext | 1085 ret i32 %old_ext |
| 1086 } | 1086 } |
| 1087 ; CHECK-LABEL: test_atomic_cmpxchg_16 | 1087 ; CHECK-LABEL: test_atomic_cmpxchg_16 |
| 1088 ; CHECK: mov {{ax|eax}},{{.*}} | 1088 ; CHECK: mov {{ax|eax}},{{.*}} |
| 1089 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x | 1089 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x |
| 1090 ; ARM32-LABEL: test_atomic_cmpxchg_16 | 1090 ; ARM32-LABEL: test_atomic_cmpxchg_16 |
| 1091 ; ARM32: dmb | 1091 ; ARM32: dmb |
| 1092 ; ARM32: ldrexh | 1092 ; ARM32: ldrexh |
| 1093 ; ARM32: cmp | 1093 ; ARM32: cmp |
| 1094 ; ARM32: {{strh|mov}} |
| 1094 ; ARM32: strexheq | 1095 ; ARM32: strexheq |
| 1095 ; ARM32: {{strh|mov}}ne | |
| 1096 ; ARM32: cmpeq | 1096 ; ARM32: cmpeq |
| 1097 ; ARM32: bne | 1097 ; ARM32: bne |
| 1098 ; ARM32: dmb | 1098 ; ARM32: dmb |
| 1099 | 1099 |
| 1100 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, | 1100 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, |
| 1101 i32 %desired) { | 1101 i32 %desired) { |
| 1102 entry: | 1102 entry: |
| 1103 %ptr = inttoptr i32 %iptr to i32* | 1103 %ptr = inttoptr i32 %iptr to i32* |
| 1104 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1104 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
| 1105 i32 %desired, i32 6, i32 6) | 1105 i32 %desired, i32 6, i32 6) |
| 1106 ret i32 %old | 1106 ret i32 %old |
| 1107 } | 1107 } |
| 1108 ; CHECK-LABEL: test_atomic_cmpxchg_32 | 1108 ; CHECK-LABEL: test_atomic_cmpxchg_32 |
| 1109 ; CHECK: mov eax,{{.*}} | 1109 ; CHECK: mov eax,{{.*}} |
| 1110 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} | 1110 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} |
| 1111 ; ARM32-LABEL: test_atomic_cmpxchg_32 | 1111 ; ARM32-LABEL: test_atomic_cmpxchg_32 |
| 1112 ; ARM32: dmb | 1112 ; ARM32: dmb |
| 1113 ; ARM32: ldrex | 1113 ; ARM32: ldrex |
| 1114 ; ARM32: cmp | 1114 ; ARM32: cmp |
| 1115 ; ARM32: {{str|mov}} |
| 1115 ; ARM32: strexeq | 1116 ; ARM32: strexeq |
| 1116 ; ARM32: {{str|mov}}ne | |
| 1117 ; ARM32: cmpeq | 1117 ; ARM32: cmpeq |
| 1118 ; ARM32: bne | 1118 ; ARM32: bne |
| 1119 ; ARM32: dmb | 1119 ; ARM32: dmb |
| 1120 | 1120 |
| 1121 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, | 1121 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, |
| 1122 i64 %desired) { | 1122 i64 %desired) { |
| 1123 entry: | 1123 entry: |
| 1124 %ptr = inttoptr i32 %iptr to i64* | 1124 %ptr = inttoptr i32 %iptr to i64* |
| 1125 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1125 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1126 i64 %desired, i32 6, i32 6) | 1126 i64 %desired, i32 6, i32 6) |
| 1127 ret i64 %old | 1127 ret i64 %old |
| 1128 } | 1128 } |
| 1129 ; CHECK-LABEL: test_atomic_cmpxchg_64 | 1129 ; CHECK-LABEL: test_atomic_cmpxchg_64 |
| 1130 ; CHECK: push ebx | 1130 ; CHECK: push ebx |
| 1131 ; CHECK-DAG: mov edx | 1131 ; CHECK-DAG: mov edx |
| 1132 ; CHECK-DAG: mov eax | 1132 ; CHECK-DAG: mov eax |
| 1133 ; CHECK-DAG: mov ecx | 1133 ; CHECK-DAG: mov ecx |
| 1134 ; CHECK-DAG: mov ebx | 1134 ; CHECK-DAG: mov ebx |
| 1135 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1135 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 1136 ; edx and eax are already the return registers, so they don't actually | 1136 ; edx and eax are already the return registers, so they don't actually |
| 1137 ; need to be reshuffled via movs. The next test stores the result | 1137 ; need to be reshuffled via movs. The next test stores the result |
| 1138 ; somewhere, so in that case they do need to be mov'ed. | 1138 ; somewhere, so in that case they do need to be mov'ed. |
| 1139 ; ARM32-LABEL: test_atomic_cmpxchg_64 | 1139 ; ARM32-LABEL: test_atomic_cmpxchg_64 |
| 1140 ; ARM32: dmb | 1140 ; ARM32: dmb |
| 1141 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1141 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
| 1142 ; ARM32: cmp | 1142 ; ARM32: cmp |
| 1143 ; ARM32-NEXT: cmpeq | 1143 ; ARM32: cmpeq |
| 1144 ; ARM32: mov |
| 1145 ; ARM32: mov |
| 1144 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1146 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 1145 ; ARM32: {{str|mov}}ne | |
| 1146 ; ARM32: {{str|mov}}ne | |
| 1147 ; ARM32: cmpeq | 1147 ; ARM32: cmpeq |
| 1148 ; ARM32: bne | 1148 ; ARM32: bne |
| 1149 ; ARM32: dmb | 1149 ; ARM32: dmb |
| 1150 | 1150 |
| 1151 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { | 1151 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { |
| 1152 entry: | 1152 entry: |
| 1153 %ptr = inttoptr i32 %iptr to i64* | 1153 %ptr = inttoptr i32 %iptr to i64* |
| 1154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, | 1154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, |
| 1155 i64 %desired, i32 6, i32 6) | 1155 i64 %desired, i32 6, i32 6) |
| 1156 ret i64 %old | 1156 ret i64 %old |
| 1157 } | 1157 } |
| 1158 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef | 1158 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef |
| 1159 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1159 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 1160 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef | 1160 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef |
| 1161 ; ARM32: mov r{{[0-9]+}}, #0 | 1161 ; ARM32: mov r{{[0-9]+}}, #0 |
| 1162 ; ARM32: mov r{{[0-9]+}}, #0 | 1162 ; ARM32: mov r{{[0-9]+}}, #0 |
| 1163 ; ARM32: dmb | 1163 ; ARM32: dmb |
| 1164 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1164 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
| 1165 ; ARM32: cmp | 1165 ; ARM32: cmp |
| 1166 ; ARM32-NEXT: cmpeq | 1166 ; ARM32: cmpeq |
| 1167 ; ARM32: mov |
| 1168 ; ARM32: mov |
| 1167 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1169 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 1168 ; ARM32: {{str|mov}}ne | |
| 1169 ; ARM32: {{str|mov}}ne | |
| 1170 ; ARM32: cmpeq | 1170 ; ARM32: cmpeq |
| 1171 ; ARM32: bne | 1171 ; ARM32: bne |
| 1172 ; ARM32: dmb | 1172 ; ARM32: dmb |
| 1173 | 1173 |
| 1174 ; Test a case where %old really does need to be copied out of edx:eax. | 1174 ; Test a case where %old really does need to be copied out of edx:eax. |
| 1175 define internal void @test_atomic_cmpxchg_64_store( | 1175 define internal void @test_atomic_cmpxchg_64_store( |
| 1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { | 1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { |
| 1177 entry: | 1177 entry: |
| 1178 %ptr = inttoptr i32 %iptr to i64* | 1178 %ptr = inttoptr i32 %iptr to i64* |
| 1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1180 i64 %desired, i32 6, i32 6) | 1180 i64 %desired, i32 6, i32 6) |
| 1181 %__6 = inttoptr i32 %ret_iptr to i64* | 1181 %__6 = inttoptr i32 %ret_iptr to i64* |
| 1182 store i64 %old, i64* %__6, align 1 | 1182 store i64 %old, i64* %__6, align 1 |
| 1183 ret void | 1183 ret void |
| 1184 } | 1184 } |
| 1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store | 1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store |
| 1186 ; CHECK: push ebx | 1186 ; CHECK: push ebx |
| 1187 ; CHECK-DAG: mov edx | 1187 ; CHECK-DAG: mov edx |
| 1188 ; CHECK-DAG: mov eax | 1188 ; CHECK-DAG: mov eax |
| 1189 ; CHECK-DAG: mov ecx | 1189 ; CHECK-DAG: mov ecx |
| 1190 ; CHECK-DAG: mov ebx | 1190 ; CHECK-DAG: mov ebx |
| 1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 1192 ; CHECK-DAG: mov {{.*}},edx | 1192 ; CHECK-DAG: mov {{.*}},edx |
| 1193 ; CHECK-DAG: mov {{.*}},eax | 1193 ; CHECK-DAG: mov {{.*}},eax |
| 1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store | 1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store |
| 1195 ; ARM32: dmb | 1195 ; ARM32: dmb |
| 1196 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1196 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
| 1197 ; ARM32: cmp | 1197 ; ARM32: cmp |
| 1198 ; ARM32-NEXT: cmpeq | 1198 ; ARM32: cmpeq |
| 1199 ; ARM32: mov |
| 1200 ; ARM32: mov |
| 1199 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1201 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 1200 ; ARM32: {{str|mov}}ne | |
| 1201 ; ARM32: {{str|mov}}ne | |
| 1202 ; ARM32: cmpeq | 1202 ; ARM32: cmpeq |
| 1203 ; ARM32: bne | 1203 ; ARM32: bne |
| 1204 ; ARM32: dmb | 1204 ; ARM32: dmb |
| 1205 ; ARM32: str | 1205 ; ARM32: str |
| 1206 ; ARM32: str | 1206 ; ARM32: str |
| 1207 | 1207 |
| 1208 ; Test with some more register pressure. When we have an alloca, ebp is | 1208 ; Test with some more register pressure. When we have an alloca, ebp is |
| 1209 ; used to manage the stack frame, so it cannot be used as a register either. | 1209 ; used to manage the stack frame, so it cannot be used as a register either. |
| 1210 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, | 1210 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, |
| 1211 i64 %desired) { | 1211 i64 %desired) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1234 ; It also cannot be ebp since we use that for alloca. Also make sure it's | 1234 ; It also cannot be ebp since we use that for alloca. Also make sure it's |
| 1235 ; not esp, since that's the stack pointer and mucking with it will break | 1235 ; not esp, since that's the stack pointer and mucking with it will break |
| 1236 ; the later use_ptr function call. | 1236 ; the later use_ptr function call. |
| 1237 ; That pretty much leaves esi, or edi as the only viable registers. | 1237 ; That pretty much leaves esi, or edi as the only viable registers. |
| 1238 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] | 1238 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] |
| 1239 ; CHECK: call {{.*}} R_{{.*}} use_ptr | 1239 ; CHECK: call {{.*}} R_{{.*}} use_ptr |
| 1240 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca | 1240 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca |
| 1241 ; ARM32: dmb | 1241 ; ARM32: dmb |
| 1242 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1242 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} |
| 1243 ; ARM32: cmp | 1243 ; ARM32: cmp |
| 1244 ; ARM32-NEXT: cmpeq | 1244 ; ARM32: cmpeq |
| 1245 ; ARM32: mov |
| 1246 ; ARM32: mov |
| 1245 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1247 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 1246 ; ARM32: {{str|mov}}ne | |
| 1247 ; ARM32: {{str|mov}}ne | |
| 1248 ; ARM32: cmpeq | 1248 ; ARM32: cmpeq |
| 1249 ; ARM32: bne | 1249 ; ARM32: bne |
| 1250 ; ARM32: dmb | 1250 ; ARM32: dmb |
| 1251 | 1251 |
| 1252 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, | 1252 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, |
| 1253 i32 %desired) { | 1253 i32 %desired) { |
| 1254 entry: | 1254 entry: |
| 1255 %ptr = inttoptr i32 %iptr to i32* | 1255 %ptr = inttoptr i32 %iptr to i32* |
| 1256 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1256 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
| 1257 i32 %desired, i32 6, i32 6) | 1257 i32 %desired, i32 6, i32 6) |
| 1258 ret i32 0 | 1258 ret i32 0 |
| 1259 } | 1259 } |
| 1260 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored | 1260 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored |
| 1261 ; CHECK: mov eax,{{.*}} | 1261 ; CHECK: mov eax,{{.*}} |
| 1262 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] | 1262 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] |
| 1263 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored | 1263 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored |
| 1264 ; ARM32: dmb | 1264 ; ARM32: dmb |
| 1265 ; ARM32: ldrex | 1265 ; ARM32: ldrex |
| 1266 ; ARM32: cmp | 1266 ; ARM32: cmp |
| 1267 ; ARM32: strexeq | 1267 ; ARM32: strexeq |
| 1268 ; ARM32: {{str|mov}}ne | |
| 1269 ; ARM32: cmpeq | 1268 ; ARM32: cmpeq |
| 1270 ; ARM32: bne | 1269 ; ARM32: bne |
| 1271 ; ARM32: dmb | 1270 ; ARM32: dmb |
| 1272 | 1271 |
| 1273 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, | 1272 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, |
| 1274 i64 %desired) { | 1273 i64 %desired) { |
| 1275 entry: | 1274 entry: |
| 1276 %ptr = inttoptr i32 %iptr to i64* | 1275 %ptr = inttoptr i32 %iptr to i64* |
| 1277 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1276 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1278 i64 %desired, i32 6, i32 6) | 1277 i64 %desired, i32 6, i32 6) |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 br i1 %cmp, label %done, label %body | 1463 br i1 %cmp, label %done, label %body |
| 1465 done: | 1464 done: |
| 1466 ret void | 1465 ret void |
| 1467 } | 1466 } |
| 1468 ; O2-LABEL: test_cmpxchg8b_regalloc | 1467 ; O2-LABEL: test_cmpxchg8b_regalloc |
| 1469 ;;; eax and some other register will be used in the cmpxchg instruction. | 1468 ;;; eax and some other register will be used in the cmpxchg instruction. |
| 1470 ; O2: lock cmpxchg8b QWORD PTR | 1469 ; O2: lock cmpxchg8b QWORD PTR |
| 1471 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. | 1470 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. |
| 1472 ; O2-NOT: {{eax|ecx|edx|ebx}} | 1471 ; O2-NOT: {{eax|ecx|edx|ebx}} |
| 1473 ; O2: pop ebx | 1472 ; O2: pop ebx |
| OLD | NEW |