OLD | NEW |
| 1 ; RUN: opt < %s -resolve-pnacl-intrinsics -S | FileCheck %s -check-prefix=CLEANE
D |
1 ; RUN: opt < %s -resolve-pnacl-intrinsics -S | FileCheck %s | 2 ; RUN: opt < %s -resolve-pnacl-intrinsics -S | FileCheck %s |
2 | 3 |
| 4 ; CLEANED-NOT: call i32 @llvm.nacl.setjmp |
| 5 ; CLEANED-NOT: call void @llvm.nacl.longjmp |
| 6 ; CLEANED-NOT: call {{.*}} @llvm.nacl.atomic |
| 7 |
3 declare i32 @llvm.nacl.setjmp(i8*) | 8 declare i32 @llvm.nacl.setjmp(i8*) |
4 declare void @llvm.nacl.longjmp(i8*, i32) | 9 declare void @llvm.nacl.longjmp(i8*, i32) |
| 10 declare i8 @llvm.nacl.atomic.8(i32, i8*, i8, i8, i32) |
| 11 declare i16 @llvm.nacl.atomic.16(i32, i16*, i16, i16, i32) |
| 12 declare i32 @llvm.nacl.atomic.32(i32, i32*, i32, i32, i32) |
| 13 declare i64 @llvm.nacl.atomic.64(i32, i64*, i64, i64, i32) |
5 | 14 |
6 ; These declarations must be here because the function pass expects | 15 ; These declarations must be here because the function pass expects |
7 ; to find them. In real life they're inserted by the translator | 16 ; to find them. In real life they're inserted by the translator |
8 ; before the function pass runs. | 17 ; before the function pass runs. |
9 declare i32 @setjmp(i8*) | 18 declare i32 @setjmp(i8*) |
10 declare void @longjmp(i8*, i32) | 19 declare void @longjmp(i8*, i32) |
11 | 20 |
12 ; CHECK-NOT: call i32 @llvm.nacl.setjmp | |
13 ; CHECK-NOT: call void @llvm.nacl.longjmp | |
14 | |
15 define i32 @call_setjmp(i8* %arg) { | 21 define i32 @call_setjmp(i8* %arg) { |
16 %val = call i32 @llvm.nacl.setjmp(i8* %arg) | 22 %val = call i32 @llvm.nacl.setjmp(i8* %arg) |
17 ; CHECK: %val = call i32 @setjmp(i8* %arg) | 23 ; CHECK: %val = call i32 @setjmp(i8* %arg) |
18 ret i32 %val | 24 ret i32 %val |
19 } | 25 } |
20 | 26 |
21 define void @call_longjmp(i8* %arg, i32 %num) { | 27 define void @call_longjmp(i8* %arg, i32 %num) { |
22 call void @llvm.nacl.longjmp(i8* %arg, i32 %num) | 28 call void @llvm.nacl.longjmp(i8* %arg, i32 %num) |
23 ; CHECK: call void @longjmp(i8* %arg, i32 %num) | 29 ; CHECK: call void @longjmp(i8* %arg, i32 %num) |
24 ret void | 30 ret void |
25 } | 31 } |
| 32 |
| 33 ; atomics |
| 34 ; Only load/store tests {i8, i16, i32, i64}, the others only test i32 |
| 35 ; since the mechanism should be the same. |
| 36 |
| 37 ; CHECK: @test_fetch_and_add_i32 |
| 38 define i32 @test_fetch_and_add_i32(i32* %ptr, i32 %value) { |
| 39 ; CHECK: %1 = atomicrmw add i32* %ptr, i32 %value seq_cst |
| 40 %1 = call i32 @llvm.nacl.atomic.32(i32 3, i32* %ptr, i32 %value, i32 0, i32 6) |
| 41 ret i32 %1 |
| 42 } |
| 43 |
| 44 ; CHECK: @test_fetch_and_sub_i32 |
| 45 define i32 @test_fetch_and_sub_i32(i32* %ptr, i32 %value) { |
| 46 ; CHECK: %1 = atomicrmw sub i32* %ptr, i32 %value seq_cst |
| 47 %1 = call i32 @llvm.nacl.atomic.32(i32 4, i32* %ptr, i32 %value, i32 0, i32 6) |
| 48 ret i32 %1 |
| 49 } |
| 50 |
| 51 ; CHECK: @test_fetch_and_or_i32 |
| 52 define i32 @test_fetch_and_or_i32(i32* %ptr, i32 %value) { |
| 53 ; CHECK: %1 = atomicrmw or i32* %ptr, i32 %value seq_cst |
| 54 %1 = call i32 @llvm.nacl.atomic.32(i32 5, i32* %ptr, i32 %value, i32 0, i32 6) |
| 55 ret i32 %1 |
| 56 } |
| 57 |
| 58 ; CHECK: @test_fetch_and_and_i32 |
| 59 define i32 @test_fetch_and_and_i32(i32* %ptr, i32 %value) { |
| 60 ; CHECK: %1 = atomicrmw and i32* %ptr, i32 %value seq_cst |
| 61 %1 = call i32 @llvm.nacl.atomic.32(i32 6, i32* %ptr, i32 %value, i32 0, i32 6) |
| 62 ret i32 %1 |
| 63 } |
| 64 |
| 65 ; CHECK: @test_fetch_and_xor_i32 |
| 66 define i32 @test_fetch_and_xor_i32(i32* %ptr, i32 %value) { |
| 67 ; CHECK: %1 = atomicrmw xor i32* %ptr, i32 %value seq_cst |
| 68 %1 = call i32 @llvm.nacl.atomic.32(i32 7, i32* %ptr, i32 %value, i32 0, i32 6) |
| 69 ret i32 %1 |
| 70 } |
| 71 |
| 72 ; CHECK: @test_val_compare_and_swap_i32 |
| 73 define i32 @test_val_compare_and_swap_i32(i32* %ptr, i32 %oldval, i32 %newval) { |
| 74 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst |
| 75 %1 = call i32 @llvm.nacl.atomic.32(i32 9, i32* %ptr, i32 %newval, i32 %oldval,
i32 6) |
| 76 ret i32 %1 |
| 77 } |
| 78 |
| 79 ; CHECK: @test_synchronize |
| 80 define void @test_synchronize() { |
| 81 ; CHECK: fence seq_cst |
| 82 call i32 @llvm.nacl.atomic.32(i32 10, i32* null, i32 0, i32 0, i32 6) |
| 83 ret void |
| 84 } |
| 85 |
| 86 ; CHECK: @test_lock_test_and_set_i32 |
| 87 define i32 @test_lock_test_and_set_i32(i32* %ptr, i32 %value) { |
| 88 ; CHECK: %1 = atomicrmw xchg i32* %ptr, i32 %value seq_cst |
| 89 %1 = call i32 @llvm.nacl.atomic.32(i32 8, i32* %ptr, i32 %value, i32 0, i32 6) |
| 90 ret i32 %1 |
| 91 } |
| 92 |
| 93 ; CHECK: @test_lock_release_i32 |
| 94 define void @test_lock_release_i32(i32* %ptr) { |
| 95 ; Note that the 'release' was changed to a 'seq_cst'. |
| 96 ; CHECK: store atomic i32 0, i32* %ptr seq_cst, align 4 |
| 97 call i32 @llvm.nacl.atomic.32(i32 2, i32* %ptr, i32 0, i32 0, i32 6) |
| 98 ret void |
| 99 } |
| 100 |
| 101 ; CHECK: @test_atomic_load_i8 |
| 102 define zeroext i8 @test_atomic_load_i8(i8* %ptr) { |
| 103 ; CHECK: %1 = load atomic i8* %ptr seq_cst, align 1 |
| 104 %1 = call i8 @llvm.nacl.atomic.8(i32 1, i8* %ptr, i8 0, i8 0, i32 6) |
| 105 ret i8 %1 |
| 106 } |
| 107 |
| 108 ; CHECK: @test_atomic_store_i8 |
| 109 define void @test_atomic_store_i8(i8* %ptr, i8 zeroext %value) { |
| 110 ; CHECK: store atomic i8 %value, i8* %ptr seq_cst, align 1 |
| 111 call i8 @llvm.nacl.atomic.8(i32 2, i8* %ptr, i8 %value, i8 0, i32 6) |
| 112 ret void |
| 113 } |
| 114 |
| 115 ; CHECK: @test_atomic_load_i16 |
| 116 define zeroext i16 @test_atomic_load_i16(i16* %ptr) { |
| 117 ; CHECK: %1 = load atomic i16* %ptr seq_cst, align 2 |
| 118 %1 = call i16 @llvm.nacl.atomic.16(i32 1, i16* %ptr, i16 0, i16 0, i32 6) |
| 119 ret i16 %1 |
| 120 } |
| 121 |
| 122 ; CHECK: @test_atomic_store_i16 |
| 123 define void @test_atomic_store_i16(i16* %ptr, i16 zeroext %value) { |
| 124 ; CHECK: store atomic i16 %value, i16* %ptr seq_cst, align 2 |
| 125 call i16 @llvm.nacl.atomic.16(i32 2, i16* %ptr, i16 %value, i16 0, i32 6) |
| 126 ret void |
| 127 } |
| 128 |
| 129 ; CHECK: @test_atomic_load_i32 |
| 130 define i32 @test_atomic_load_i32(i32* %ptr) { |
| 131 ; CHECK: %1 = load atomic i32* %ptr seq_cst, align 4 |
| 132 %1 = call i32 @llvm.nacl.atomic.32(i32 1, i32* %ptr, i32 0, i32 0, i32 6) |
| 133 ret i32 %1 |
| 134 } |
| 135 |
| 136 ; CHECK: @test_atomic_store_i32 |
| 137 define void @test_atomic_store_i32(i32* %ptr, i32 %value) { |
| 138 ; CHECK: store atomic i32 %value, i32* %ptr seq_cst, align 4 |
| 139 call i32 @llvm.nacl.atomic.32(i32 2, i32* %ptr, i32 %value, i32 0, i32 6) |
| 140 ret void |
| 141 } |
| 142 |
| 143 ; CHECK: @test_atomic_load_i64 |
| 144 define i64 @test_atomic_load_i64(i64* %ptr) { |
| 145 ; CHECK: %1 = load atomic i64* %ptr seq_cst, align 8 |
| 146 %1 = call i64 @llvm.nacl.atomic.64(i32 1, i64* %ptr, i64 0, i64 0, i32 6) |
| 147 ret i64 %1 |
| 148 } |
| 149 |
| 150 ; CHECK: @test_atomic_store_i64 |
| 151 define void @test_atomic_store_i64(i64* %ptr, i64 %value) { |
| 152 ; CHECK: store atomic i64 %value, i64* %ptr seq_cst, align 8 |
| 153 call i64 @llvm.nacl.atomic.64(i32 2, i64* %ptr, i64 %value, i64 0, i32 6) |
| 154 ret void |
| 155 } |
OLD | NEW |