1; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=FUNC %s 2; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=CIVI -check-prefix=GCN -check-prefix=FUNC %s 3; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=CIVI -check-prefix=GCN -check-prefix=FUNC %s 4; RUN: llc -march=r600 -mcpu=redwood -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s 5 6; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32: 7; EG: LDS_WRXCHG_RET * 8; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 9; GCN: s_load_dword [[SPTR:s[0-9]+]], 10; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 11; GCN: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] 12; GCN: buffer_store_dword [[RESULT]], 13; GCN: s_endpgm 14define void @lds_atomic_xchg_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 15 %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst 16 store i32 %result, i32 addrspace(1)* %out, align 4 17 ret void 18} 19 20; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32_offset: 21; EG: LDS_WRXCHG_RET * 22; GCN: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 23; GCN: s_endpgm 24define void @lds_atomic_xchg_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 25 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 26 %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst 27 store i32 %result, i32 addrspace(1)* %out, align 4 28 ret void 29} 30 31; XXX - Is it really necessary to load 4 into VGPR? 32; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32: 33; EG: LDS_ADD_RET * 34; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 35; GCN: s_load_dword [[SPTR:s[0-9]+]], 36; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 37; GCN: ds_add_rtn_u32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] 38; GCN: buffer_store_dword [[RESULT]], 39; GCN: s_endpgm 40define void @lds_atomic_add_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 41 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst 42 store i32 %result, i32 addrspace(1)* %out, align 4 43 ret void 44} 45 46; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_offset: 47; EG: LDS_ADD_RET * 48; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 49; GCN: s_endpgm 50define void @lds_atomic_add_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 51 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 52 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 53 store i32 %result, i32 addrspace(1)* %out, align 4 54 ret void 55} 56 57; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_bad_si_offset: 58; EG: LDS_ADD_RET * 59; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} 60; CIVI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 61; GCN: s_endpgm 62define void @lds_atomic_add_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 63 %sub = sub i32 %a, %b 64 %add = add i32 %sub, 4 65 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 66 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 67 store i32 %result, i32 addrspace(1)* %out, align 4 68 ret void 69} 70 71; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32: 72; EG: LDS_ADD_RET * 73; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 74; GCN: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] 75; GCN: s_endpgm 76define void @lds_atomic_inc_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 77 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst 78 store i32 %result, i32 addrspace(1)* %out, align 4 79 ret void 80} 81 82; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32_offset: 83; EG: LDS_ADD_RET * 84; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 85; GCN: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] offset:16 86; GCN: s_endpgm 87define void @lds_atomic_inc_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 88 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 89 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 90 store i32 %result, i32 addrspace(1)* %out, align 4 91 ret void 92} 93 94; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32_bad_si_offset: 95; EG: LDS_ADD_RET * 96; SI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} 97; CIVI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 98; GCN: s_endpgm 99define void @lds_atomic_inc_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 100 %sub = sub i32 %a, %b 101 %add = add i32 %sub, 4 102 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 103 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 104 store i32 %result, i32 addrspace(1)* %out, align 4 105 ret void 106} 107 108; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32: 109; EG: LDS_SUB_RET * 110; GCN: ds_sub_rtn_u32 111; GCN: s_endpgm 112define void @lds_atomic_sub_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 113 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst 114 store i32 %result, i32 addrspace(1)* %out, align 4 115 ret void 116} 117 118; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32_offset: 119; EG: LDS_SUB_RET * 120; GCN: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 121; GCN: s_endpgm 122define void @lds_atomic_sub_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 123 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 124 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst 125 store i32 %result, i32 addrspace(1)* %out, align 4 126 ret void 127} 128 129; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i32: 130; EG: LDS_SUB_RET * 131; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 132; GCN: ds_dec_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] 133; GCN: s_endpgm 134define void @lds_atomic_dec_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 135 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst 136 store i32 %result, i32 addrspace(1)* %out, align 4 137 ret void 138} 139 140; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i32_offset: 141; EG: LDS_SUB_RET * 142; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 143; GCN: ds_dec_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] offset:16 144; GCN: s_endpgm 145define void @lds_atomic_dec_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 146 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 147 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst 148 store i32 %result, i32 addrspace(1)* %out, align 4 149 ret void 150} 151 152; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32: 153; EG: LDS_AND_RET * 154; GCN: ds_and_rtn_b32 155; GCN: s_endpgm 156define void @lds_atomic_and_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 157 %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst 158 store i32 %result, i32 addrspace(1)* %out, align 4 159 ret void 160} 161 162; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32_offset: 163; EG: LDS_AND_RET * 164; GCN: ds_and_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 165; GCN: s_endpgm 166define void @lds_atomic_and_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 167 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 168 %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst 169 store i32 %result, i32 addrspace(1)* %out, align 4 170 ret void 171} 172 173; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32: 174; EG: LDS_OR_RET * 175; GCN: ds_or_rtn_b32 176; GCN: s_endpgm 177define void @lds_atomic_or_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 178 %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst 179 store i32 %result, i32 addrspace(1)* %out, align 4 180 ret void 181} 182 183; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32_offset: 184; EG: LDS_OR_RET * 185; GCN: ds_or_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 186; GCN: s_endpgm 187define void @lds_atomic_or_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 188 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 189 %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst 190 store i32 %result, i32 addrspace(1)* %out, align 4 191 ret void 192} 193 194; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32: 195; EG: LDS_XOR_RET * 196; GCN: ds_xor_rtn_b32 197; GCN: s_endpgm 198define void @lds_atomic_xor_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 199 %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst 200 store i32 %result, i32 addrspace(1)* %out, align 4 201 ret void 202} 203 204; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32_offset: 205; EG: LDS_XOR_RET * 206; GCN: ds_xor_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 207; GCN: s_endpgm 208define void @lds_atomic_xor_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 209 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 210 %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst 211 store i32 %result, i32 addrspace(1)* %out, align 4 212 ret void 213} 214 215; FIXME: There is no atomic nand instr 216; XFUNC-LABEL: {{^}}lds_atomic_nand_ret_i32:uction, so we somehow need to expand this. 217; define void @lds_atomic_nand_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 218; %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst 219; store i32 %result, i32 addrspace(1)* %out, align 4 220; ret void 221; } 222 223; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32: 224; EG: LDS_MIN_INT_RET * 225; GCN: ds_min_rtn_i32 226; GCN: s_endpgm 227define void @lds_atomic_min_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 228 %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst 229 store i32 %result, i32 addrspace(1)* %out, align 4 230 ret void 231} 232 233; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32_offset: 234; EG: LDS_MIN_INT_RET * 235; GCN: ds_min_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 236; GCN: s_endpgm 237define void @lds_atomic_min_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 238 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 239 %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst 240 store i32 %result, i32 addrspace(1)* %out, align 4 241 ret void 242} 243 244; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32: 245; EG: LDS_MAX_INT_RET * 246; GCN: ds_max_rtn_i32 247; GCN: s_endpgm 248define void @lds_atomic_max_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 249 %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst 250 store i32 %result, i32 addrspace(1)* %out, align 4 251 ret void 252} 253 254; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32_offset: 255; EG: LDS_MAX_INT_RET * 256; GCN: ds_max_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 257; GCN: s_endpgm 258define void @lds_atomic_max_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 259 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 260 %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst 261 store i32 %result, i32 addrspace(1)* %out, align 4 262 ret void 263} 264 265; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32: 266; EG: LDS_MIN_UINT_RET * 267; GCN: ds_min_rtn_u32 268; GCN: s_endpgm 269define void @lds_atomic_umin_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 270 %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst 271 store i32 %result, i32 addrspace(1)* %out, align 4 272 ret void 273} 274 275; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32_offset: 276; EG: LDS_MIN_UINT_RET * 277; GCN: ds_min_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 278; GCN: s_endpgm 279define void @lds_atomic_umin_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 280 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 281 %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst 282 store i32 %result, i32 addrspace(1)* %out, align 4 283 ret void 284} 285 286; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32: 287; EG: LDS_MAX_UINT_RET * 288; GCN: ds_max_rtn_u32 289; GCN: s_endpgm 290define void @lds_atomic_umax_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 291 %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst 292 store i32 %result, i32 addrspace(1)* %out, align 4 293 ret void 294} 295 296; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32_offset: 297; EG: LDS_MAX_UINT_RET * 298; GCN: ds_max_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 299; GCN: s_endpgm 300define void @lds_atomic_umax_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind { 301 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 302 %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst 303 store i32 %result, i32 addrspace(1)* %out, align 4 304 ret void 305} 306 307; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32: 308; GCN: s_load_dword [[SPTR:s[0-9]+]], 309; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 310; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 311; GCN: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] 312; GCN: s_endpgm 313define void @lds_atomic_xchg_noret_i32(i32 addrspace(3)* %ptr) nounwind { 314 %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst 315 ret void 316} 317 318; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32_offset: 319; GCN: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 320; GCN: s_endpgm 321define void @lds_atomic_xchg_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 322 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 323 %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst 324 ret void 325} 326 327; XXX - Is it really necessary to load 4 into VGPR? 328; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32: 329; GCN: s_load_dword [[SPTR:s[0-9]+]], 330; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 331; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 332; GCN: ds_add_u32 [[VPTR]], [[DATA]] 333; GCN: s_endpgm 334define void @lds_atomic_add_noret_i32(i32 addrspace(3)* %ptr) nounwind { 335 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst 336 ret void 337} 338 339; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_offset: 340; GCN: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 341; GCN: s_endpgm 342define void @lds_atomic_add_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 343 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 344 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 345 ret void 346} 347 348; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_bad_si_offset 349; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} 350; CIVI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 351; GCN: s_endpgm 352define void @lds_atomic_add_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 353 %sub = sub i32 %a, %b 354 %add = add i32 %sub, 4 355 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 356 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 357 ret void 358} 359 360; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32: 361; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 362; GCN: ds_inc_u32 v{{[0-9]+}}, [[NEGONE]] 363; GCN: s_endpgm 364define void @lds_atomic_inc_noret_i32(i32 addrspace(3)* %ptr) nounwind { 365 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst 366 ret void 367} 368 369; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32_offset: 370; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 371; GCN: ds_inc_u32 v{{[0-9]+}}, [[NEGONE]] offset:16 372; GCN: s_endpgm 373define void @lds_atomic_inc_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 374 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 375 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 376 ret void 377} 378 379; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32_bad_si_offset: 380; SI: ds_inc_u32 v{{[0-9]+}}, v{{[0-9]+}} 381; CIVI: ds_inc_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 382; GCN: s_endpgm 383define void @lds_atomic_inc_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 384 %sub = sub i32 %a, %b 385 %add = add i32 %sub, 4 386 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 387 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 388 ret void 389} 390 391; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32: 392; GCN: ds_sub_u32 393; GCN: s_endpgm 394define void @lds_atomic_sub_noret_i32(i32 addrspace(3)* %ptr) nounwind { 395 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst 396 ret void 397} 398 399; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32_offset: 400; GCN: ds_sub_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 401; GCN: s_endpgm 402define void @lds_atomic_sub_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 403 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 404 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst 405 ret void 406} 407 408; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i32: 409; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 410; GCN: ds_dec_u32 v{{[0-9]+}}, [[NEGONE]] 411; GCN: s_endpgm 412define void @lds_atomic_dec_noret_i32(i32 addrspace(3)* %ptr) nounwind { 413 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst 414 ret void 415} 416 417; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i32_offset: 418; GCN: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1 419; GCN: ds_dec_u32 v{{[0-9]+}}, [[NEGONE]] offset:16 420; GCN: s_endpgm 421define void @lds_atomic_dec_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 422 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 423 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst 424 ret void 425} 426 427; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32: 428; GCN: ds_and_b32 429; GCN: s_endpgm 430define void @lds_atomic_and_noret_i32(i32 addrspace(3)* %ptr) nounwind { 431 %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst 432 ret void 433} 434 435; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32_offset: 436; GCN: ds_and_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 437; GCN: s_endpgm 438define void @lds_atomic_and_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 439 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 440 %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst 441 ret void 442} 443 444; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32: 445; GCN: ds_or_b32 446; GCN: s_endpgm 447define void @lds_atomic_or_noret_i32(i32 addrspace(3)* %ptr) nounwind { 448 %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst 449 ret void 450} 451 452; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32_offset: 453; GCN: ds_or_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 454; GCN: s_endpgm 455define void @lds_atomic_or_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 456 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 457 %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst 458 ret void 459} 460 461; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32: 462; GCN: ds_xor_b32 463; GCN: s_endpgm 464define void @lds_atomic_xor_noret_i32(i32 addrspace(3)* %ptr) nounwind { 465 %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst 466 ret void 467} 468 469; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32_offset: 470; GCN: ds_xor_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 471; GCN: s_endpgm 472define void @lds_atomic_xor_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 473 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 474 %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst 475 ret void 476} 477 478; FIXME: There is no atomic nand instr 479; XFUNC-LABEL: {{^}}lds_atomic_nand_noret_i32:uction, so we somehow need to expand this. 480; define void @lds_atomic_nand_noret_i32(i32 addrspace(3)* %ptr) nounwind { 481; %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst 482; ret void 483; } 484 485; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32: 486; GCN: ds_min_i32 487; GCN: s_endpgm 488define void @lds_atomic_min_noret_i32(i32 addrspace(3)* %ptr) nounwind { 489 %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst 490 ret void 491} 492 493; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32_offset: 494; GCN: ds_min_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 495; GCN: s_endpgm 496define void @lds_atomic_min_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 497 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 498 %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst 499 ret void 500} 501 502; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32: 503; GCN: ds_max_i32 504; GCN: s_endpgm 505define void @lds_atomic_max_noret_i32(i32 addrspace(3)* %ptr) nounwind { 506 %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst 507 ret void 508} 509 510; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32_offset: 511; GCN: ds_max_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 512; GCN: s_endpgm 513define void @lds_atomic_max_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 514 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 515 %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst 516 ret void 517} 518 519; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32: 520; GCN: ds_min_u32 521; GCN: s_endpgm 522define void @lds_atomic_umin_noret_i32(i32 addrspace(3)* %ptr) nounwind { 523 %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst 524 ret void 525} 526 527; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32_offset: 528; GCN: ds_min_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 529; GCN: s_endpgm 530define void @lds_atomic_umin_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 531 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 532 %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst 533 ret void 534} 535 536; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32: 537; GCN: ds_max_u32 538; GCN: s_endpgm 539define void @lds_atomic_umax_noret_i32(i32 addrspace(3)* %ptr) nounwind { 540 %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst 541 ret void 542} 543 544; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32_offset: 545; GCN: ds_max_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 546; GCN: s_endpgm 547define void @lds_atomic_umax_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 548 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 549 %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst 550 ret void 551} 552