1; Test that some errors trigger when the usage of NaCl atomic 2; intrinsics does not match the required ABI. 3; REQUIRES: allow_dump 4 5; RUN: %p2i -i %s --args --verbose none --exit-success -threads=0 2>&1 \ 6; RUN: | FileCheck %s 7 8declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) 9declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) 10declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) 11declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) 12declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) 13declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) 14declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32) 15declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32) 16declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32) 17declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32) 18declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32) 19declare void @llvm.nacl.atomic.fence(i32) 20declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*) 21 22;;; Load 23;;; Check unexpected memory order parameter (release=4 and acq_rel=5 24;;; are disallowed). 25 26define internal i32 @error_atomic_load_8(i32 %iptr) { 27entry: 28 %ptr = inttoptr i32 %iptr to i8* 29 %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 0) 30 %r = zext i8 %i to i32 31 ret i32 %r 32} 33; CHECK: Unexpected memory ordering for AtomicLoad 34 35define internal i32 @error_atomic_load_16(i32 %iptr) { 36entry: 37 %ptr = inttoptr i32 %iptr to i16* 38 %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 4) 39 %r = zext i16 %i to i32 40 ret i32 %r 41} 42; CHECK: Unexpected memory ordering for AtomicLoad 43 44define internal i64 @error_atomic_load_64(i32 %iptr) { 45entry: 46 %ptr = inttoptr i32 %iptr to i64* 47 %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 5) 48 ret i64 %r 49} 50; CHECK: Unexpected memory ordering for AtomicLoad 51 52 53;;; Store 54;;; consume=2, acquire=3, acq_rel=5 are disallowed 55 56define internal void @error_atomic_store_32(i32 %iptr, i32 %v) { 57entry: 58 %ptr = inttoptr i32 %iptr to i32* 59 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 2) 60 ret void 61} 62; CHECK: Unexpected memory ordering for AtomicStore 63 64define internal void @error_atomic_store_64(i32 %iptr, i64 %v) { 65entry: 66 %ptr = inttoptr i32 %iptr to i64* 67 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 3) 68 ret void 69} 70; CHECK: Unexpected memory ordering for AtomicStore 71 72define internal void @error_atomic_store_64_const(i32 %iptr) { 73entry: 74 %ptr = inttoptr i32 %iptr to i64* 75 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 5) 76 ret void 77} 78; CHECK: Unexpected memory ordering for AtomicStore 79 80;;; RMW 81;;; Test atomic memory order and operation. 82;;; Modes 3:6 allowed. 83 84define internal i32 @error_atomic_rmw_add_8(i32 %iptr, i32 %v) { 85entry: 86 %trunc = trunc i32 %v to i8 87 %ptr = inttoptr i32 %iptr to i8* 88 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 1) 89 %a_ext = zext i8 %a to i32 90 ret i32 %a_ext 91} 92; CHECK: Unexpected memory ordering for AtomicRMW 93 94define internal i64 @error_atomic_rmw_add_64(i32 %iptr, i64 %v) { 95entry: 96 %ptr = inttoptr i32 %iptr to i64* 97 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 7) 98 ret i64 %a 99} 100; CHECK: Unexpected memory ordering for AtomicRMW 101 102define internal i32 @error_atomic_rmw_add_16(i32 %iptr, i32 %v) { 103entry: 104 %trunc = trunc i32 %v to i16 105 %ptr = inttoptr i32 %iptr to i16* 106 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 0, i16* %ptr, i16 %trunc, i32 6) 107 %a_ext = zext i16 %a to i32 108 ret i32 %a_ext 109} 110; CHECK: Unknown AtomicRMW operation 111 112define internal i32 @error_atomic_rmw_add_32(i32 %iptr, i32 %v) { 113entry: 114 %ptr = inttoptr i32 %iptr to i32* 115 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 7, i32* %ptr, i32 %v, i32 6) 116 ret i32 %a 117} 118; CHECK: Unknown AtomicRMW operation 119 120define internal i32 @error_atomic_rmw_add_32_max(i32 %iptr, i32 %v) { 121entry: 122 %ptr = inttoptr i32 %iptr to i32* 123 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4294967295, i32* %ptr, i32 %v, i32 6) 124 ret i32 %a 125} 126; CHECK: Unknown AtomicRMW operation 127 128;;; Cmpxchg 129 130define internal i32 @error_atomic_cmpxchg_32_success(i32 %iptr, i32 %expected, 131 i32 %desired) { 132entry: 133 %ptr = inttoptr i32 %iptr to i32* 134 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 135 i32 %desired, i32 0, i32 6) 136 ret i32 %old 137} 138; CHECK: Unexpected memory ordering for AtomicCmpxchg 139 140define internal i32 @error_atomic_cmpxchg_32_failure(i32 %iptr, i32 %expected, 141 i32 %desired) { 142entry: 143 %ptr = inttoptr i32 %iptr to i32* 144 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 145 i32 %desired, i32 6, i32 0) 146 ret i32 %old 147} 148; CHECK: Unexpected memory ordering for AtomicCmpxchg 149 150define internal i64 @error_atomic_cmpxchg_64_failure(i32 %iptr, i64 %expected, 151 i64 %desired) { 152entry: 153 %ptr = inttoptr i32 %iptr to i64* 154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, 155 i64 %desired, i32 4, i32 1) 156 ret i64 %old 157} 158; CHECK: Unexpected memory ordering for AtomicCmpxchg 159 160;;; Fence and is-lock-free. 161 162define internal void @error_atomic_fence() { 163entry: 164 call void @llvm.nacl.atomic.fence(i32 0) 165 ret void 166} 167; CHECK: Unexpected memory ordering for AtomicFence 168 169define internal i32 @error_atomic_is_lock_free_var(i32 %iptr, i32 %bs) { 170entry: 171 %ptr = inttoptr i32 %iptr to i8* 172 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 %bs, i8* %ptr) 173 %r = zext i1 %i to i32 174 ret i32 %r 175} 176; CHECK: AtomicIsLockFree byte size should be compile-time const 177 178 179;;; Test bad non-constant memory ordering values. 180 181define internal i32 @error_atomic_load_8_nonconst(i32 %iptr) { 182entry: 183 %ptr = inttoptr i32 %iptr to i8* 184 %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 %iptr) 185 %r = zext i8 %i to i32 186 ret i32 %r 187} 188; CHECK: Unexpected memory ordering for AtomicLoad 189 190define internal void @error_atomic_store_32_nonconst(i32 %iptr, i32 %v) { 191entry: 192 %ptr = inttoptr i32 %iptr to i32* 193 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 %v) 194 ret void 195} 196; CHECK: Unexpected memory ordering for AtomicStore 197 198define internal i32 @error_atomic_rmw_add_8_nonconst(i32 %iptr, i32 %v) { 199entry: 200 %trunc = trunc i32 %v to i8 201 %ptr = inttoptr i32 %iptr to i8* 202 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 %iptr) 203 %a_ext = zext i8 %a to i32 204 ret i32 %a_ext 205} 206; CHECK: Unexpected memory ordering for AtomicRMW 207 208define internal i32 @error_atomic_cmpxchg_32_success_nonconst_1(i32 %iptr, i32 %expected, 209 i32 %desired) { 210entry: 211 %ptr = inttoptr i32 %iptr to i32* 212 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 213 i32 %desired, i32 %iptr, i32 6) 214 ret i32 %old 215} 216; CHECK: Unexpected memory ordering for AtomicCmpxchg 217 218define internal i32 @error_atomic_cmpxchg_32_success_nonconst_2(i32 %iptr, i32 %expected, 219 i32 %desired) { 220entry: 221 %ptr = inttoptr i32 %iptr to i32* 222 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 223 i32 %desired, i32 6, i32 %iptr) 224 ret i32 %old 225} 226; CHECK: Unexpected memory ordering for AtomicCmpxchg 227 228define internal void @error_atomic_fence_nonconst(i32 %v) { 229entry: 230 call void @llvm.nacl.atomic.fence(i32 %v) 231 ret void 232} 233; CHECK: Unexpected memory ordering for AtomicFence 234