Home | History | Annotate | Download | only in llvm2ice_tests
      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 
      8 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
      9 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
     10 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
     11 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
     12 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
     13 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
     14 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
     15 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32)
     16 declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32)
     17 declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32)
     18 declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32)
     19 declare void @llvm.nacl.atomic.fence(i32)
     20 declare 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 
     26 define internal i32 @error_atomic_load_8(i32 %iptr) {
     27 entry:
     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 
     35 define internal i32 @error_atomic_load_16(i32 %iptr) {
     36 entry:
     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 
     44 define internal i64 @error_atomic_load_64(i32 %iptr) {
     45 entry:
     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 
     56 define internal void @error_atomic_store_32(i32 %iptr, i32 %v) {
     57 entry:
     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 
     64 define internal void @error_atomic_store_64(i32 %iptr, i64 %v) {
     65 entry:
     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 
     72 define internal void @error_atomic_store_64_const(i32 %iptr) {
     73 entry:
     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 
     84 define internal i32 @error_atomic_rmw_add_8(i32 %iptr, i32 %v) {
     85 entry:
     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 
     94 define internal i64 @error_atomic_rmw_add_64(i32 %iptr, i64 %v) {
     95 entry:
     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 
    102 define internal i32 @error_atomic_rmw_add_16(i32 %iptr, i32 %v) {
    103 entry:
    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 
    112 define internal i32 @error_atomic_rmw_add_32(i32 %iptr, i32 %v) {
    113 entry:
    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 
    120 define internal i32 @error_atomic_rmw_add_32_max(i32 %iptr, i32 %v) {
    121 entry:
    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 
    130 define internal i32 @error_atomic_cmpxchg_32_success(i32 %iptr, i32 %expected,
    131                                                      i32 %desired) {
    132 entry:
    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 
    140 define internal i32 @error_atomic_cmpxchg_32_failure(i32 %iptr, i32 %expected,
    141                                                      i32 %desired) {
    142 entry:
    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 
    150 define internal i64 @error_atomic_cmpxchg_64_failure(i32 %iptr, i64 %expected,
    151                                                      i64 %desired) {
    152 entry:
    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 
    162 define internal void @error_atomic_fence() {
    163 entry:
    164   call void @llvm.nacl.atomic.fence(i32 0)
    165   ret void
    166 }
    167 ; CHECK: Unexpected memory ordering for AtomicFence
    168 
    169 define internal i32 @error_atomic_is_lock_free_var(i32 %iptr, i32 %bs) {
    170 entry:
    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 
    181 define internal i32 @error_atomic_load_8_nonconst(i32 %iptr) {
    182 entry:
    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 
    190 define internal void @error_atomic_store_32_nonconst(i32 %iptr, i32 %v) {
    191 entry:
    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 
    198 define internal i32 @error_atomic_rmw_add_8_nonconst(i32 %iptr, i32 %v) {
    199 entry:
    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 
    208 define internal i32 @error_atomic_cmpxchg_32_success_nonconst_1(i32 %iptr, i32 %expected,
    209                                                                 i32 %desired) {
    210 entry:
    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 
    218 define internal i32 @error_atomic_cmpxchg_32_success_nonconst_2(i32 %iptr, i32 %expected,
    219                                                                 i32 %desired) {
    220 entry:
    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 
    228 define internal void @error_atomic_fence_nonconst(i32 %v) {
    229 entry:
    230   call void @llvm.nacl.atomic.fence(i32 %v)
    231   ret void
    232 }
    233 ; CHECK: Unexpected memory ordering for AtomicFence
    234