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 7declare i8 @llvm.nacl.atomic.load.i8(i8*, i32) 8declare i16 @llvm.nacl.atomic.load.i16(i16*, i32) 9declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) 10declare i64 @llvm.nacl.atomic.load.i64(i64*, i32) 11declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32) 12declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32) 13declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) 14declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32) 15declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32) 16declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32) 17declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32) 18declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32) 19declare i8 @llvm.nacl.atomic.cmpxchg.i8(i8*, i8, i8, i32, i32) 20declare i16 @llvm.nacl.atomic.cmpxchg.i16(i16*, i16, i16, i32, i32) 21declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32) 22declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32) 23declare void @llvm.nacl.atomic.fence(i32) 24declare void @llvm.nacl.atomic.fence.all() 25declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*) 26 27;;; Load 28 29define internal i32 @test_atomic_load_8(i32 %iptr) { 30entry: 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 45define internal i32 @test_atomic_load_16(i32 %iptr) { 46entry: 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 60define internal i32 @test_atomic_load_32(i32 %iptr) { 61entry: 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 73define internal i64 @test_atomic_load_64(i32 %iptr) { 74entry: 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 88define internal void @test_atomic_store_8(i32 %iptr, i32 %v) { 89entry: 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 103define internal void @test_atomic_store_16(i32 %iptr, i32 %v) { 104entry: 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 118define internal void @test_atomic_store_32(i32 %iptr, i32 %v) { 119entry: 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 131define internal void @test_atomic_store_64(i32 %iptr, i64 %v) { 132entry: 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 144define internal void @test_atomic_store_64_const(i32 %iptr) { 145entry: 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 161define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) { 162entry: 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 179define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) { 180entry: 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 196define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) { 197entry: 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 209define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) { 210entry: 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 224define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) { 225entry: 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 241define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) { 242entry: 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 258define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) { 259entry: 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 271define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) { 272entry: 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 286define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) { 287entry: 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 303define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) { 304entry: 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 320define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) { 321entry: 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 333define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) { 334entry: 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 348define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) { 349entry: 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 365define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) { 366entry: 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 382define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) { 383entry: 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 395define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) { 396entry: 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 410define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) { 411entry: 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 427define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) { 428entry: 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 444define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) { 445entry: 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 457define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) { 458entry: 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 472define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) { 473entry: 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 489define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) { 490entry: 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 506define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) { 507entry: 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 519define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) { 520entry: 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 534define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) { 535entry: 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 554define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) { 555entry: 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 574define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) { 575entry: 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 588define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) { 589entry: 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 604define internal void @test_atomic_fence() { 605entry: 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 616define internal void @test_atomic_fence_all() { 617entry: 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 628define internal i32 @test_atomic_is_lock_free(i32 %iptr) { 629entry: 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