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 ; TODO(kschimpf) Find out why lc2i is needed. | 4 ; RUN: %p2i -i %s --args -O2 --verbose none \ |
5 ; RUN: %lc2i -i %s --args -O2 --verbose none \ | |
6 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ | 5 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ |
7 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ | 6 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ |
8 ; RUN: | %iflc FileCheck %s | 7 ; RUN: | FileCheck %s |
9 ; RUN: %p2i -i %s --args -O2 --verbose none \ | 8 ; RUN: %p2i -i %s --args -O2 --verbose none \ |
10 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ | 9 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ |
11 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ | 10 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ |
12 ; RUN: | FileCheck --check-prefix=CHECKO2 %s | 11 ; RUN: | FileCheck --check-prefix=CHECKO2 %s |
13 ; RUN: %lc2i -i %s --args -Om1 --verbose none \ | 12 ; RUN: %p2i -i %s --args -Om1 --verbose none \ |
14 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ | 13 ; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \ |
15 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ | 14 ; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \ |
16 ; RUN: | %iflc FileCheck %s | 15 ; RUN: | FileCheck %s |
17 | 16 |
18 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) | 17 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) |
19 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) | 18 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) |
20 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) | 19 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) |
21 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) | 20 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) |
22 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32) | 21 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32) |
23 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32) | 22 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32) |
24 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) | 23 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) |
25 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) | 24 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) |
26 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) | 25 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 entry: | 706 entry: |
708 %trunc_exp = trunc i32 %expected to i8 | 707 %trunc_exp = trunc i32 %expected to i8 |
709 %trunc_des = trunc i32 %desired to i8 | 708 %trunc_des = trunc i32 %desired to i8 |
710 %ptr = inttoptr i32 %iptr to i8* | 709 %ptr = inttoptr i32 %iptr to i8* |
711 %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp, | 710 %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp, |
712 i8 %trunc_des, i32 6, i32 6) | 711 i8 %trunc_des, i32 6, i32 6) |
713 %old_ext = zext i8 %old to i32 | 712 %old_ext = zext i8 %old to i32 |
714 ret i32 %old_ext | 713 ret i32 %old_ext |
715 } | 714 } |
716 ; CHECK-LABEL: test_atomic_cmpxchg_8 | 715 ; CHECK-LABEL: test_atomic_cmpxchg_8 |
717 ; CHECK: mov al, {{.*}} | 716 ; CHECK: mov eax, {{.*}} |
718 ; Need to check that eax isn't used as the address register or the desired. | 717 ; Need to check that eax isn't used as the address register or the desired. |
719 ; since it is already used as the *expected* register. | 718 ; since it is already used as the *expected* register. |
720 ; CHECK: lock | 719 ; CHECK: lock |
721 ; CHECK-NEXT: cmpxchg byte ptr [e{{[^a].}}], {{[^a]}} | 720 ; CHECK-NEXT: cmpxchg byte ptr [e{{[^a].}}], {{[^a]}}l |
722 | 721 |
723 define i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) { | 722 define i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) { |
724 entry: | 723 entry: |
725 %trunc_exp = trunc i32 %expected to i16 | 724 %trunc_exp = trunc i32 %expected to i16 |
726 %trunc_des = trunc i32 %desired to i16 | 725 %trunc_des = trunc i32 %desired to i16 |
727 %ptr = inttoptr i32 %iptr to i16* | 726 %ptr = inttoptr i32 %iptr to i16* |
728 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, | 727 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, |
729 i16 %trunc_des, i32 6, i32 6) | 728 i16 %trunc_des, i32 6, i32 6) |
730 %old_ext = zext i16 %old to i32 | 729 %old_ext = zext i16 %old to i32 |
731 ret i32 %old_ext | 730 ret i32 %old_ext |
732 } | 731 } |
733 ; CHECK-LABEL: test_atomic_cmpxchg_16 | 732 ; CHECK-LABEL: test_atomic_cmpxchg_16 |
734 ; CHECK: mov ax, {{.*}} | 733 ; CHECK: mov eax, {{.*}} |
735 ; CHECK: lock | 734 ; CHECK: lock |
736 ; CHECK-NEXT: cmpxchg word ptr [e{{[^a].}}], {{[^a]}} | 735 ; CHECK-NEXT: cmpxchg word ptr [e{{[^a].}}], {{[^a]}}x |
737 | 736 |
738 define i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) { | 737 define i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) { |
739 entry: | 738 entry: |
740 %ptr = inttoptr i32 %iptr to i32* | 739 %ptr = inttoptr i32 %iptr to i32* |
741 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 740 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
742 i32 %desired, i32 6, i32 6) | 741 i32 %desired, i32 6, i32 6) |
743 ret i32 %old | 742 ret i32 %old |
744 } | 743 } |
745 ; CHECK-LABEL: test_atomic_cmpxchg_32 | 744 ; CHECK-LABEL: test_atomic_cmpxchg_32 |
746 ; CHECK: mov eax, {{.*}} | 745 ; CHECK: mov eax, {{.*}} |
(...skipping 30 matching lines...) Expand all Loading... |
777 ret void | 776 ret void |
778 } | 777 } |
779 ; CHECK-LABEL: test_atomic_cmpxchg_64_store | 778 ; CHECK-LABEL: test_atomic_cmpxchg_64_store |
780 ; CHECK: push ebx | 779 ; CHECK: push ebx |
781 ; CHECK-DAG: mov edx | 780 ; CHECK-DAG: mov edx |
782 ; CHECK-DAG: mov eax | 781 ; CHECK-DAG: mov eax |
783 ; CHECK-DAG: mov ecx | 782 ; CHECK-DAG: mov ecx |
784 ; CHECK-DAG: mov ebx | 783 ; CHECK-DAG: mov ebx |
785 ; CHECK: lock | 784 ; CHECK: lock |
786 ; CHECK-NEXT: cmpxchg8b qword ptr [e{{.[^x]}}] | 785 ; CHECK-NEXT: cmpxchg8b qword ptr [e{{.[^x]}}] |
787 ; CHECK: mov {{.*}}, edx | 786 ; CHECK-DAG: mov {{.*}}, edx |
788 ; CHECK: mov {{.*}}, eax | 787 ; CHECK-DAG: mov {{.*}}, eax |
789 | 788 |
790 ; Test with some more register pressure. When we have an alloca, ebp is | 789 ; Test with some more register pressure. When we have an alloca, ebp is |
791 ; used to manage the stack frame, so it cannot be used as a register either. | 790 ; used to manage the stack frame, so it cannot be used as a register either. |
792 define i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, i64 %desired
) { | 791 define i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, i64 %desired
) { |
793 entry: | 792 entry: |
794 %alloca_ptr = alloca i8, i32 16, align 16 | 793 %alloca_ptr = alloca i8, i32 16, align 16 |
795 %ptr = inttoptr i32 %iptr to i64* | 794 %ptr = inttoptr i32 %iptr to i64* |
796 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 795 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
797 i64 %desired, i32 6, i32 6) | 796 i64 %desired, i32 6, i32 6) |
798 store i8 0, i8* %alloca_ptr, align 1 | 797 store i8 0, i8* %alloca_ptr, align 1 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 | 912 |
914 not_lock_free: | 913 not_lock_free: |
915 %z = add i32 %x, %y | 914 %z = add i32 %x, %y |
916 ret i32 %z | 915 ret i32 %z |
917 } | 916 } |
918 ; CHECK-LABEL: test_atomic_is_lock_free_can_dce | 917 ; CHECK-LABEL: test_atomic_is_lock_free_can_dce |
919 ; CHECK: mov {{.*}}, 1 | 918 ; CHECK: mov {{.*}}, 1 |
920 ; CHECK: ret | 919 ; CHECK: ret |
921 ; CHECK: add | 920 ; CHECK: add |
922 ; CHECK: ret | 921 ; CHECK: ret |
OLD | NEW |