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