1 ; Test parsing NaCl atomic instructions. 2 3 ; RUN: %p2i -i %s --insts | FileCheck %s 4 ; RUN: %p2i -i %s --args -notranslate -timing | \ 5 ; RUN: FileCheck --check-prefix=NOIR %s 6 7 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) 8 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) 9 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) 10 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) 11 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32) 12 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32) 13 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) 14 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) 15 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) 16 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32) 17 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32) 18 declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32) 19 declare i8 @llvm.nacl.atomic.cmpxchg.i8(i8*, i8, i8, i32, i32) 20 declare i16 @llvm.nacl.atomic.cmpxchg.i16(i16*, i16, i16, i32, i32) 21 declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32) 22 declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32) 23 declare void @llvm.nacl.atomic.fence(i32) 24 declare void @llvm.nacl.atomic.fence.all() 25 declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*) 26 27 ;;; Load 28 29 define internal i32 @test_atomic_load_8(i32 %iptr) { 30 entry: 31 %ptr = inttoptr i32 %iptr to i8* 32 ; parameter value "6" is for the sequential consistency memory order. 33 %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 6) 34 %r = zext i8 %i to i32 35 ret i32 %r 36 } 37 38 ; CHECK: define internal i32 @test_atomic_load_8(i32 %iptr) { 39 ; CHECK-NEXT: entry: 40 ; CHECK-NEXT: %i = call i8 @llvm.nacl.atomic.load.i8(i32 %iptr, i32 6) 41 ; CHECK-NEXT: %r = zext i8 %i to i32 42 ; CHECK-NEXT: ret i32 %r 43 ; CHECK-NEXT: } 44 45 define internal i32 @test_atomic_load_16(i32 %iptr) { 46 entry: 47 %ptr = inttoptr i32 %iptr to i16* 48 %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6) 49 %r = zext i16 %i to i32 50 ret i32 %r 51 } 52 53 ; CHECK-NEXT: define internal i32 @test_atomic_load_16(i32 %iptr) { 54 ; CHECK-NEXT: entry: 55 ; CHECK-NEXT: %i = call i16 @llvm.nacl.atomic.load.i16(i32 %iptr, i32 6) 56 ; CHECK-NEXT: %r = zext i16 %i to i32 57 ; CHECK-NEXT: ret i32 %r 58 ; CHECK-NEXT: } 59 60 define internal i32 @test_atomic_load_32(i32 %iptr) { 61 entry: 62 %ptr = inttoptr i32 %iptr to i32* 63 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6) 64 ret i32 %r 65 } 66 67 ; CHECK-NEXT: define internal i32 @test_atomic_load_32(i32 %iptr) { 68 ; CHECK-NEXT: entry: 69 ; CHECK-NEXT: %r = call i32 @llvm.nacl.atomic.load.i32(i32 %iptr, i32 6) 70 ; CHECK-NEXT: ret i32 %r 71 ; CHECK-NEXT: } 72 73 define internal i64 @test_atomic_load_64(i32 %iptr) { 74 entry: 75 %ptr = inttoptr i32 %iptr to i64* 76 %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6) 77 ret i64 %r 78 } 79 80 ; CHECK-NEXT: define internal i64 @test_atomic_load_64(i32 %iptr) { 81 ; CHECK-NEXT: entry: 82 ; CHECK-NEXT: %r = call i64 @llvm.nacl.atomic.load.i64(i32 %iptr, i32 6) 83 ; CHECK-NEXT: ret i64 %r 84 ; CHECK-NEXT: } 85 86 ;;; Store 87 88 define internal void @test_atomic_store_8(i32 %iptr, i32 %v) { 89 entry: 90 %truncv = trunc i32 %v to i8 91 %ptr = inttoptr i32 %iptr to i8* 92 call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6) 93 ret void 94 } 95 96 ; CHECK-NEXT: define internal void @test_atomic_store_8(i32 %iptr, i32 %v) { 97 ; CHECK-NEXT: entry: 98 ; CHECK-NEXT: %truncv = trunc i32 %v to i8 99 ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i8(i8 %truncv, i32 %iptr, i32 6) 100 ; CHECK-NEXT: ret void 101 ; CHECK-NEXT: } 102 103 define internal void @test_atomic_store_16(i32 %iptr, i32 %v) { 104 entry: 105 %truncv = trunc i32 %v to i16 106 %ptr = inttoptr i32 %iptr to i16* 107 call void @llvm.nacl.atomic.store.i16(i16 %truncv, i16* %ptr, i32 6) 108 ret void 109 } 110 111 ; CHECK-NEXT: define internal void @test_atomic_store_16(i32 %iptr, i32 %v) { 112 ; CHECK-NEXT: entry: 113 ; CHECK-NEXT: %truncv = trunc i32 %v to i16 114 ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i16(i16 %truncv, i32 %iptr, i32 6) 115 ; CHECK-NEXT: ret void 116 ; CHECK-NEXT: } 117 118 define internal void @test_atomic_store_32(i32 %iptr, i32 %v) { 119 entry: 120 %ptr = inttoptr i32 %iptr to i32* 121 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6) 122 ret void 123 } 124 125 ; CHECK-NEXT: define internal void @test_atomic_store_32(i32 %iptr, i32 %v) { 126 ; CHECK-NEXT: entry: 127 ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i32(i32 %v, i32 %iptr, i32 6) 128 ; CHECK-NEXT: ret void 129 ; CHECK-NEXT: } 130 131 define internal void @test_atomic_store_64(i32 %iptr, i64 %v) { 132 entry: 133 %ptr = inttoptr i32 %iptr to i64* 134 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6) 135 ret void 136 } 137 138 ; CHECK-NEXT: define internal void @test_atomic_store_64(i32 %iptr, i64 %v) { 139 ; CHECK-NEXT: entry: 140 ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i64(i64 %v, i32 %iptr, i32 6) 141 ; CHECK-NEXT: ret void 142 ; CHECK-NEXT: } 143 144 define internal void @test_atomic_store_64_const(i32 %iptr) { 145 entry: 146 %ptr = inttoptr i32 %iptr to i64* 147 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6) 148 ret void 149 } 150 151 ; CHECK-NEXT: define internal void @test_atomic_store_64_const(i32 %iptr) { 152 ; CHECK-NEXT: entry: 153 ; CHECK-NEXT: call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i32 %iptr, i32 6) 154 ; CHECK-NEXT: ret void 155 ; CHECK-NEXT: } 156 157 ;;; RMW 158 159 ;; add 160 161 define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) { 162 entry: 163 %trunc = trunc i32 %v to i8 164 %ptr = inttoptr i32 %iptr to i8* 165 ; "1" is an atomic add, and "6" is sequential consistency. 166 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6) 167 %a_ext = zext i8 %a to i32 168 ret i32 %a_ext 169 } 170 171 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) { 172 ; CHECK-NEXT: entry: 173 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 174 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i32 %iptr, i8 %trunc, i32 6) 175 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 176 ; CHECK-NEXT: ret i32 %a_ext 177 ; CHECK-NEXT: } 178 179 define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) { 180 entry: 181 %trunc = trunc i32 %v to i16 182 %ptr = inttoptr i32 %iptr to i16* 183 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6) 184 %a_ext = zext i16 %a to i32 185 ret i32 %a_ext 186 } 187 188 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) { 189 ; CHECK-NEXT: entry: 190 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 191 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i32 %iptr, i16 %trunc, i32 6) 192 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 193 ; CHECK-NEXT: ret i32 %a_ext 194 ; CHECK-NEXT: } 195 196 define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) { 197 entry: 198 %ptr = inttoptr i32 %iptr to i32* 199 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6) 200 ret i32 %a 201 } 202 203 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) { 204 ; CHECK-NEXT: entry: 205 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32 %iptr, i32 %v, i32 6) 206 ; CHECK-NEXT: ret i32 %a 207 ; CHECK-NEXT: } 208 209 define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) { 210 entry: 211 %ptr = inttoptr i32 %iptr to i64* 212 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6) 213 ret i64 %a 214 } 215 216 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) { 217 ; CHECK-NEXT: entry: 218 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i32 %iptr, i64 %v, i32 6) 219 ; CHECK-NEXT: ret i64 %a 220 ; CHECK-NEXT: } 221 222 ;; sub 223 224 define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { 225 entry: 226 %trunc = trunc i32 %v to i8 227 %ptr = inttoptr i32 %iptr to i8* 228 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i8* %ptr, i8 %trunc, i32 6) 229 %a_ext = zext i8 %a to i32 230 ret i32 %a_ext 231 } 232 233 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { 234 ; CHECK-NEXT: entry: 235 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 236 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i32 %iptr, i8 %trunc, i32 6) 237 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 238 ; CHECK-NEXT: ret i32 %a_ext 239 ; CHECK-NEXT: } 240 241 define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) { 242 entry: 243 %trunc = trunc i32 %v to i16 244 %ptr = inttoptr i32 %iptr to i16* 245 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i16* %ptr, i16 %trunc, i32 6) 246 %a_ext = zext i16 %a to i32 247 ret i32 %a_ext 248 } 249 250 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) { 251 ; CHECK-NEXT: entry: 252 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 253 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i32 %iptr, i16 %trunc, i32 6) 254 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 255 ; CHECK-NEXT: ret i32 %a_ext 256 ; CHECK-NEXT: } 257 258 define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) { 259 entry: 260 %ptr = inttoptr i32 %iptr to i32* 261 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6) 262 ret i32 %a 263 } 264 265 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) { 266 ; CHECK-NEXT: entry: 267 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32 %iptr, i32 %v, i32 6) 268 ; CHECK-NEXT: ret i32 %a 269 ; CHECK-NEXT: } 270 271 define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) { 272 entry: 273 %ptr = inttoptr i32 %iptr to i64* 274 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i64* %ptr, i64 %v, i32 6) 275 ret i64 %a 276 } 277 278 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) { 279 ; CHECK-NEXT: entry: 280 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i32 %iptr, i64 %v, i32 6) 281 ; CHECK-NEXT: ret i64 %a 282 ; CHECK-NEXT: } 283 284 ;; or 285 286 define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) { 287 entry: 288 %trunc = trunc i32 %v to i8 289 %ptr = inttoptr i32 %iptr to i8* 290 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6) 291 %a_ext = zext i8 %a to i32 292 ret i32 %a_ext 293 } 294 295 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) { 296 ; CHECK-NEXT: entry: 297 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 298 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i32 %iptr, i8 %trunc, i32 6) 299 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 300 ; CHECK-NEXT: ret i32 %a_ext 301 ; CHECK-NEXT: } 302 303 define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { 304 entry: 305 %trunc = trunc i32 %v to i16 306 %ptr = inttoptr i32 %iptr to i16* 307 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6) 308 %a_ext = zext i16 %a to i32 309 ret i32 %a_ext 310 } 311 312 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { 313 ; CHECK-NEXT: entry: 314 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 315 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i32 %iptr, i16 %trunc, i32 6) 316 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 317 ; CHECK-NEXT: ret i32 %a_ext 318 ; CHECK-NEXT: } 319 320 define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { 321 entry: 322 %ptr = inttoptr i32 %iptr to i32* 323 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6) 324 ret i32 %a 325 } 326 327 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { 328 ; CHECK-NEXT: entry: 329 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32 %iptr, i32 %v, i32 6) 330 ; CHECK-NEXT: ret i32 %a 331 ; CHECK-NEXT: } 332 333 define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { 334 entry: 335 %ptr = inttoptr i32 %iptr to i64* 336 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6) 337 ret i64 %a 338 } 339 340 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { 341 ; CHECK-NEXT: entry: 342 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i32 %iptr, i64 %v, i32 6) 343 ; CHECK-NEXT: ret i64 %a 344 ; CHECK-NEXT: } 345 346 ;; and 347 348 define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) { 349 entry: 350 %trunc = trunc i32 %v to i8 351 %ptr = inttoptr i32 %iptr to i8* 352 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i8* %ptr, i8 %trunc, i32 6) 353 %a_ext = zext i8 %a to i32 354 ret i32 %a_ext 355 } 356 357 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) { 358 ; CHECK-NEXT: entry: 359 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 360 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i32 %iptr, i8 %trunc, i32 6) 361 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 362 ; CHECK-NEXT: ret i32 %a_ext 363 ; CHECK-NEXT: } 364 365 define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) { 366 entry: 367 %trunc = trunc i32 %v to i16 368 %ptr = inttoptr i32 %iptr to i16* 369 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i16* %ptr, i16 %trunc, i32 6) 370 %a_ext = zext i16 %a to i32 371 ret i32 %a_ext 372 } 373 374 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) { 375 ; CHECK-NEXT: entry: 376 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 377 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i32 %iptr, i16 %trunc, i32 6) 378 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 379 ; CHECK-NEXT: ret i32 %a_ext 380 ; CHECK-NEXT: } 381 382 define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) { 383 entry: 384 %ptr = inttoptr i32 %iptr to i32* 385 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6) 386 ret i32 %a 387 } 388 389 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) { 390 ; CHECK-NEXT: entry: 391 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32 %iptr, i32 %v, i32 6) 392 ; CHECK-NEXT: ret i32 %a 393 ; CHECK-NEXT: } 394 395 define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) { 396 entry: 397 %ptr = inttoptr i32 %iptr to i64* 398 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i64* %ptr, i64 %v, i32 6) 399 ret i64 %a 400 } 401 402 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) { 403 ; CHECK-NEXT: entry: 404 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i32 %iptr, i64 %v, i32 6) 405 ; CHECK-NEXT: ret i64 %a 406 ; CHECK-NEXT: } 407 408 ;; xor 409 410 define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) { 411 entry: 412 %trunc = trunc i32 %v to i8 413 %ptr = inttoptr i32 %iptr to i8* 414 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i8* %ptr, i8 %trunc, i32 6) 415 %a_ext = zext i8 %a to i32 416 ret i32 %a_ext 417 } 418 419 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) { 420 ; CHECK-NEXT: entry: 421 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 422 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i32 %iptr, i8 %trunc, i32 6) 423 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 424 ; CHECK-NEXT: ret i32 %a_ext 425 ; CHECK-NEXT: } 426 427 define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) { 428 entry: 429 %trunc = trunc i32 %v to i16 430 %ptr = inttoptr i32 %iptr to i16* 431 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i16* %ptr, i16 %trunc, i32 6) 432 %a_ext = zext i16 %a to i32 433 ret i32 %a_ext 434 } 435 436 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) { 437 ; CHECK-NEXT: entry: 438 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 439 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i32 %iptr, i16 %trunc, i32 6) 440 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 441 ; CHECK-NEXT: ret i32 %a_ext 442 ; CHECK-NEXT: } 443 444 define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) { 445 entry: 446 %ptr = inttoptr i32 %iptr to i32* 447 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6) 448 ret i32 %a 449 } 450 451 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) { 452 ; CHECK-NEXT: entry: 453 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32 %iptr, i32 %v, i32 6) 454 ; CHECK-NEXT: ret i32 %a 455 ; CHECK-NEXT: } 456 457 define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) { 458 entry: 459 %ptr = inttoptr i32 %iptr to i64* 460 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i64* %ptr, i64 %v, i32 6) 461 ret i64 %a 462 } 463 464 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) { 465 ; CHECK-NEXT: entry: 466 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i32 %iptr, i64 %v, i32 6) 467 ; CHECK-NEXT: ret i64 %a 468 ; CHECK-NEXT: } 469 470 ;; exchange 471 472 define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) { 473 entry: 474 %trunc = trunc i32 %v to i8 475 %ptr = inttoptr i32 %iptr to i8* 476 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i8* %ptr, i8 %trunc, i32 6) 477 %a_ext = zext i8 %a to i32 478 ret i32 %a_ext 479 } 480 481 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) { 482 ; CHECK-NEXT: entry: 483 ; CHECK-NEXT: %trunc = trunc i32 %v to i8 484 ; CHECK-NEXT: %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i32 %iptr, i8 %trunc, i32 6) 485 ; CHECK-NEXT: %a_ext = zext i8 %a to i32 486 ; CHECK-NEXT: ret i32 %a_ext 487 ; CHECK-NEXT: } 488 489 define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) { 490 entry: 491 %trunc = trunc i32 %v to i16 492 %ptr = inttoptr i32 %iptr to i16* 493 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i16* %ptr, i16 %trunc, i32 6) 494 %a_ext = zext i16 %a to i32 495 ret i32 %a_ext 496 } 497 498 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) { 499 ; CHECK-NEXT: entry: 500 ; CHECK-NEXT: %trunc = trunc i32 %v to i16 501 ; CHECK-NEXT: %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i32 %iptr, i16 %trunc, i32 6) 502 ; CHECK-NEXT: %a_ext = zext i16 %a to i32 503 ; CHECK-NEXT: ret i32 %a_ext 504 ; CHECK-NEXT: } 505 506 define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) { 507 entry: 508 %ptr = inttoptr i32 %iptr to i32* 509 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6) 510 ret i32 %a 511 } 512 513 ; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) { 514 ; CHECK-NEXT: entry: 515 ; CHECK-NEXT: %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32 %iptr, i32 %v, i32 6) 516 ; CHECK-NEXT: ret i32 %a 517 ; CHECK-NEXT: } 518 519 define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) { 520 entry: 521 %ptr = inttoptr i32 %iptr to i64* 522 %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i64* %ptr, i64 %v, i32 6) 523 ret i64 %a 524 } 525 526 ; CHECK-NEXT: define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) { 527 ; CHECK-NEXT: entry: 528 ; CHECK-NEXT: %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i32 %iptr, i64 %v, i32 6) 529 ; CHECK-NEXT: ret i64 %a 530 ; CHECK-NEXT: } 531 532 ;;;; Cmpxchg 533 534 define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) { 535 entry: 536 %trunc_exp = trunc i32 %expected to i8 537 %trunc_des = trunc i32 %desired to i8 538 %ptr = inttoptr i32 %iptr to i8* 539 %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp, 540 i8 %trunc_des, i32 6, i32 6) 541 %old_ext = zext i8 %old to i32 542 ret i32 %old_ext 543 } 544 545 ; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) { 546 ; CHECK-NEXT: entry: 547 ; CHECK-NEXT: %trunc_exp = trunc i32 %expected to i8 548 ; CHECK-NEXT: %trunc_des = trunc i32 %desired to i8 549 ; CHECK-NEXT: %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i32 %iptr, i8 %trunc_exp, i8 %trunc_des, i32 6, i32 6) 550 ; CHECK-NEXT: %old_ext = zext i8 %old to i32 551 ; CHECK-NEXT: ret i32 %old_ext 552 ; CHECK-NEXT: } 553 554 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) { 555 entry: 556 %trunc_exp = trunc i32 %expected to i16 557 %trunc_des = trunc i32 %desired to i16 558 %ptr = inttoptr i32 %iptr to i16* 559 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, 560 i16 %trunc_des, i32 6, i32 6) 561 %old_ext = zext i16 %old to i32 562 ret i32 %old_ext 563 } 564 565 ; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) { 566 ; CHECK-NEXT: entry: 567 ; CHECK-NEXT: %trunc_exp = trunc i32 %expected to i16 568 ; CHECK-NEXT: %trunc_des = trunc i32 %desired to i16 569 ; CHECK-NEXT: %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i32 %iptr, i16 %trunc_exp, i16 %trunc_des, i32 6, i32 6) 570 ; CHECK-NEXT: %old_ext = zext i16 %old to i32 571 ; CHECK-NEXT: ret i32 %old_ext 572 ; CHECK-NEXT: } 573 574 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) { 575 entry: 576 %ptr = inttoptr i32 %iptr to i32* 577 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, 578 i32 %desired, i32 6, i32 6) 579 ret i32 %old 580 } 581 582 ; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) { 583 ; CHECK-NEXT: entry: 584 ; CHECK-NEXT: %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32 %iptr, i32 %expected, i32 %desired, i32 6, i32 6) 585 ; CHECK-NEXT: ret i32 %old 586 ; CHECK-NEXT: } 587 588 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) { 589 entry: 590 %ptr = inttoptr i32 %iptr to i64* 591 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, 592 i64 %desired, i32 6, i32 6) 593 ret i64 %old 594 } 595 596 ; CHECK-NEXT: define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) { 597 ; CHECK-NEXT: entry: 598 ; CHECK-NEXT: %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i32 %iptr, i64 %expected, i64 %desired, i32 6, i32 6) 599 ; CHECK-NEXT: ret i64 %old 600 ; CHECK-NEXT: } 601 602 ;;;; Fence and is-lock-free. 603 604 define internal void @test_atomic_fence() { 605 entry: 606 call void @llvm.nacl.atomic.fence(i32 6) 607 ret void 608 } 609 610 ; CHECK-NEXT: define internal void @test_atomic_fence() { 611 ; CHECK-NEXT: entry: 612 ; CHECK-NEXT: call void @llvm.nacl.atomic.fence(i32 6) 613 ; CHECK-NEXT: ret void 614 ; CHECK-NEXT: } 615 616 define internal void @test_atomic_fence_all() { 617 entry: 618 call void @llvm.nacl.atomic.fence.all() 619 ret void 620 } 621 622 ; CHECK-NEXT: define internal void @test_atomic_fence_all() { 623 ; CHECK-NEXT: entry: 624 ; CHECK-NEXT: call void @llvm.nacl.atomic.fence.all() 625 ; CHECK-NEXT: ret void 626 ; CHECK-NEXT: } 627 628 define internal i32 @test_atomic_is_lock_free(i32 %iptr) { 629 entry: 630 %ptr = inttoptr i32 %iptr to i8* 631 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr) 632 %r = zext i1 %i to i32 633 ret i32 %r 634 } 635 636 ; CHECK-NEXT: define internal i32 @test_atomic_is_lock_free(i32 %iptr) { 637 ; CHECK-NEXT: entry: 638 ; CHECK-NEXT: %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i32 %iptr) 639 ; CHECK-NEXT: %r = zext i1 %i to i32 640 ; CHECK-NEXT: ret i32 %r 641 ; CHECK-NEXT: } 642 643 ; NOIR: Total across all functions 644