Home | History | Annotate | Download | only in R600
      1 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
      2 
      3 ; FUNC-LABEL: @lds_atomic_xchg_ret_i64:
      4 ; SI: DS_WRXCHG_RTN_B64
      5 ; SI: S_ENDPGM
      6 define void @lds_atomic_xchg_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
      7   %result = atomicrmw xchg i64 addrspace(3)* %ptr, i64 4 seq_cst
      8   store i64 %result, i64 addrspace(1)* %out, align 8
      9   ret void
     10 }
     11 
     12 ; FUNC-LABEL: @lds_atomic_xchg_ret_i64_offset:
     13 ; SI: DS_WRXCHG_RTN_B64 {{.*}} 0x20
     14 ; SI: S_ENDPGM
     15 define void @lds_atomic_xchg_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     16   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
     17   %result = atomicrmw xchg i64 addrspace(3)* %gep, i64 4 seq_cst
     18   store i64 %result, i64 addrspace(1)* %out, align 8
     19   ret void
     20 }
     21 
     22 ; FUNC-LABEL: @lds_atomic_add_ret_i64:
     23 ; SI: DS_ADD_RTN_U64
     24 ; SI: S_ENDPGM
     25 define void @lds_atomic_add_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     26   %result = atomicrmw add i64 addrspace(3)* %ptr, i64 4 seq_cst
     27   store i64 %result, i64 addrspace(1)* %out, align 8
     28   ret void
     29 }
     30 
     31 ; FUNC-LABEL: @lds_atomic_add_ret_i64_offset:
     32 ; SI: S_LOAD_DWORD [[PTR:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
     33 ; SI: S_MOV_B64 s{{\[}}[[LOSDATA:[0-9]+]]:[[HISDATA:[0-9]+]]{{\]}}, 9
     34 ; SI-DAG: V_MOV_B32_e32 v[[LOVDATA:[0-9]+]], s[[LOSDATA]]
     35 ; SI-DAG: V_MOV_B32_e32 v[[HIVDATA:[0-9]+]], s[[HISDATA]]
     36 ; SI-DAG: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[PTR]]
     37 ; SI: DS_ADD_RTN_U64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}, 0x20, [M0]
     38 ; SI: BUFFER_STORE_DWORDX2 [[RESULT]],
     39 ; SI: S_ENDPGM
     40 define void @lds_atomic_add_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     41   %gep = getelementptr i64 addrspace(3)* %ptr, i64 4
     42   %result = atomicrmw add i64 addrspace(3)* %gep, i64 9 seq_cst
     43   store i64 %result, i64 addrspace(1)* %out, align 8
     44   ret void
     45 }
     46 
     47 ; FUNC-LABEL: @lds_atomic_inc_ret_i64:
     48 ; SI: S_MOV_B64 s{{\[}}[[LOSDATA:[0-9]+]]:[[HISDATA:[0-9]+]]{{\]}}, -1
     49 ; SI-DAG: V_MOV_B32_e32 v[[LOVDATA:[0-9]+]], s[[LOSDATA]]
     50 ; SI-DAG: V_MOV_B32_e32 v[[HIVDATA:[0-9]+]], s[[HISDATA]]
     51 ; SI: DS_INC_RTN_U64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}},
     52 ; SI: BUFFER_STORE_DWORDX2 [[RESULT]],
     53 ; SI: S_ENDPGM
     54 define void @lds_atomic_inc_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     55   %result = atomicrmw add i64 addrspace(3)* %ptr, i64 1 seq_cst
     56   store i64 %result, i64 addrspace(1)* %out, align 8
     57   ret void
     58 }
     59 
     60 ; FUNC-LABEL: @lds_atomic_inc_ret_i64_offset:
     61 ; SI: DS_INC_RTN_U64 {{.*}} 0x20
     62 ; SI: S_ENDPGM
     63 define void @lds_atomic_inc_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     64   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
     65   %result = atomicrmw add i64 addrspace(3)* %gep, i64 1 seq_cst
     66   store i64 %result, i64 addrspace(1)* %out, align 8
     67   ret void
     68 }
     69 
     70 ; FUNC-LABEL: @lds_atomic_sub_ret_i64:
     71 ; SI: DS_SUB_RTN_U64
     72 ; SI: S_ENDPGM
     73 define void @lds_atomic_sub_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     74   %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 4 seq_cst
     75   store i64 %result, i64 addrspace(1)* %out, align 8
     76   ret void
     77 }
     78 
     79 ; FUNC-LABEL: @lds_atomic_sub_ret_i64_offset:
     80 ; SI: DS_SUB_RTN_U64 {{.*}} 0x20
     81 ; SI: S_ENDPGM
     82 define void @lds_atomic_sub_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     83   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
     84   %result = atomicrmw sub i64 addrspace(3)* %gep, i64 4 seq_cst
     85   store i64 %result, i64 addrspace(1)* %out, align 8
     86   ret void
     87 }
     88 
     89 ; FUNC-LABEL: @lds_atomic_dec_ret_i64:
     90 ; SI: S_MOV_B64 s{{\[}}[[LOSDATA:[0-9]+]]:[[HISDATA:[0-9]+]]{{\]}}, -1
     91 ; SI-DAG: V_MOV_B32_e32 v[[LOVDATA:[0-9]+]], s[[LOSDATA]]
     92 ; SI-DAG: V_MOV_B32_e32 v[[HIVDATA:[0-9]+]], s[[HISDATA]]
     93 ; SI: DS_DEC_RTN_U64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}},
     94 ; SI: BUFFER_STORE_DWORDX2 [[RESULT]],
     95 ; SI: S_ENDPGM
     96 define void @lds_atomic_dec_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
     97   %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 1 seq_cst
     98   store i64 %result, i64 addrspace(1)* %out, align 8
     99   ret void
    100 }
    101 
    102 ; FUNC-LABEL: @lds_atomic_dec_ret_i64_offset:
    103 ; SI: DS_DEC_RTN_U64 {{.*}} 0x20
    104 ; SI: S_ENDPGM
    105 define void @lds_atomic_dec_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    106   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    107   %result = atomicrmw sub i64 addrspace(3)* %gep, i64 1 seq_cst
    108   store i64 %result, i64 addrspace(1)* %out, align 8
    109   ret void
    110 }
    111 
    112 ; FUNC-LABEL: @lds_atomic_and_ret_i64:
    113 ; SI: DS_AND_RTN_B64
    114 ; SI: S_ENDPGM
    115 define void @lds_atomic_and_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    116   %result = atomicrmw and i64 addrspace(3)* %ptr, i64 4 seq_cst
    117   store i64 %result, i64 addrspace(1)* %out, align 8
    118   ret void
    119 }
    120 
    121 ; FUNC-LABEL: @lds_atomic_and_ret_i64_offset:
    122 ; SI: DS_AND_RTN_B64 {{.*}} 0x20
    123 ; SI: S_ENDPGM
    124 define void @lds_atomic_and_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    125   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    126   %result = atomicrmw and i64 addrspace(3)* %gep, i64 4 seq_cst
    127   store i64 %result, i64 addrspace(1)* %out, align 8
    128   ret void
    129 }
    130 
    131 ; FUNC-LABEL: @lds_atomic_or_ret_i64:
    132 ; SI: DS_OR_RTN_B64
    133 ; SI: S_ENDPGM
    134 define void @lds_atomic_or_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    135   %result = atomicrmw or i64 addrspace(3)* %ptr, i64 4 seq_cst
    136   store i64 %result, i64 addrspace(1)* %out, align 8
    137   ret void
    138 }
    139 
    140 ; FUNC-LABEL: @lds_atomic_or_ret_i64_offset:
    141 ; SI: DS_OR_RTN_B64 {{.*}} 0x20
    142 ; SI: S_ENDPGM
    143 define void @lds_atomic_or_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    144   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    145   %result = atomicrmw or i64 addrspace(3)* %gep, i64 4 seq_cst
    146   store i64 %result, i64 addrspace(1)* %out, align 8
    147   ret void
    148 }
    149 
    150 ; FUNC-LABEL: @lds_atomic_xor_ret_i64:
    151 ; SI: DS_XOR_RTN_B64
    152 ; SI: S_ENDPGM
    153 define void @lds_atomic_xor_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    154   %result = atomicrmw xor i64 addrspace(3)* %ptr, i64 4 seq_cst
    155   store i64 %result, i64 addrspace(1)* %out, align 8
    156   ret void
    157 }
    158 
    159 ; FUNC-LABEL: @lds_atomic_xor_ret_i64_offset:
    160 ; SI: DS_XOR_RTN_B64 {{.*}} 0x20
    161 ; SI: S_ENDPGM
    162 define void @lds_atomic_xor_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    163   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    164   %result = atomicrmw xor i64 addrspace(3)* %gep, i64 4 seq_cst
    165   store i64 %result, i64 addrspace(1)* %out, align 8
    166   ret void
    167 }
    168 
    169 ; FIXME: There is no atomic nand instr
    170 ; XFUNC-LABEL: @lds_atomic_nand_ret_i64:uction, so we somehow need to expand this.
    171 ; define void @lds_atomic_nand_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    172 ;   %result = atomicrmw nand i64 addrspace(3)* %ptr, i32 4 seq_cst
    173 ;   store i64 %result, i64 addrspace(1)* %out, align 8
    174 ;   ret void
    175 ; }
    176 
    177 ; FUNC-LABEL: @lds_atomic_min_ret_i64:
    178 ; SI: DS_MIN_RTN_I64
    179 ; SI: S_ENDPGM
    180 define void @lds_atomic_min_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    181   %result = atomicrmw min i64 addrspace(3)* %ptr, i64 4 seq_cst
    182   store i64 %result, i64 addrspace(1)* %out, align 8
    183   ret void
    184 }
    185 
    186 ; FUNC-LABEL: @lds_atomic_min_ret_i64_offset:
    187 ; SI: DS_MIN_RTN_I64 {{.*}} 0x20
    188 ; SI: S_ENDPGM
    189 define void @lds_atomic_min_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    190   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    191   %result = atomicrmw min i64 addrspace(3)* %gep, i64 4 seq_cst
    192   store i64 %result, i64 addrspace(1)* %out, align 8
    193   ret void
    194 }
    195 
    196 ; FUNC-LABEL: @lds_atomic_max_ret_i64:
    197 ; SI: DS_MAX_RTN_I64
    198 ; SI: S_ENDPGM
    199 define void @lds_atomic_max_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    200   %result = atomicrmw max i64 addrspace(3)* %ptr, i64 4 seq_cst
    201   store i64 %result, i64 addrspace(1)* %out, align 8
    202   ret void
    203 }
    204 
    205 ; FUNC-LABEL: @lds_atomic_max_ret_i64_offset:
    206 ; SI: DS_MAX_RTN_I64 {{.*}} 0x20
    207 ; SI: S_ENDPGM
    208 define void @lds_atomic_max_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    209   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    210   %result = atomicrmw max i64 addrspace(3)* %gep, i64 4 seq_cst
    211   store i64 %result, i64 addrspace(1)* %out, align 8
    212   ret void
    213 }
    214 
    215 ; FUNC-LABEL: @lds_atomic_umin_ret_i64:
    216 ; SI: DS_MIN_RTN_U64
    217 ; SI: S_ENDPGM
    218 define void @lds_atomic_umin_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    219   %result = atomicrmw umin i64 addrspace(3)* %ptr, i64 4 seq_cst
    220   store i64 %result, i64 addrspace(1)* %out, align 8
    221   ret void
    222 }
    223 
    224 ; FUNC-LABEL: @lds_atomic_umin_ret_i64_offset:
    225 ; SI: DS_MIN_RTN_U64 {{.*}} 0x20
    226 ; SI: S_ENDPGM
    227 define void @lds_atomic_umin_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    228   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    229   %result = atomicrmw umin i64 addrspace(3)* %gep, i64 4 seq_cst
    230   store i64 %result, i64 addrspace(1)* %out, align 8
    231   ret void
    232 }
    233 
    234 ; FUNC-LABEL: @lds_atomic_umax_ret_i64:
    235 ; SI: DS_MAX_RTN_U64
    236 ; SI: S_ENDPGM
    237 define void @lds_atomic_umax_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    238   %result = atomicrmw umax i64 addrspace(3)* %ptr, i64 4 seq_cst
    239   store i64 %result, i64 addrspace(1)* %out, align 8
    240   ret void
    241 }
    242 
    243 ; FUNC-LABEL: @lds_atomic_umax_ret_i64_offset:
    244 ; SI: DS_MAX_RTN_U64 {{.*}} 0x20
    245 ; SI: S_ENDPGM
    246 define void @lds_atomic_umax_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
    247   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
    248   %result = atomicrmw umax i64 addrspace(3)* %gep, i64 4 seq_cst
    249   store i64 %result, i64 addrspace(1)* %out, align 8
    250   ret void
    251 }
    252