Home | History | Annotate | Download | only in reader_tests
      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