1; RUN: llc -march=amdgcn -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: s_load_dword [[SPTR:s[0-9]+]], 9; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 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: s_load_dword [[SPTR:s[0-9]+]], 35; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 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_add1_ret_i32: 72; EG: LDS_ADD_RET * 73; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 74; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] 75; GCN: s_endpgm 76define void @lds_atomic_add1_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_add1_ret_i32_offset: 83; EG: LDS_ADD_RET * 84; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 85; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] offset:16 86; GCN: s_endpgm 87define void @lds_atomic_add1_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_add1_ret_i32_bad_si_offset: 95; EG: LDS_ADD_RET * 96; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} 97; CIVI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16 98; GCN: s_endpgm 99define void @lds_atomic_add1_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_sub1_ret_i32: 130; EG: LDS_SUB_RET * 131; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 132; GCN: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] 133; GCN: s_endpgm 134define void @lds_atomic_sub1_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_sub1_ret_i32_offset: 141; EG: LDS_SUB_RET * 142; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 143; GCN: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] offset:16 144; GCN: s_endpgm 145define void @lds_atomic_sub1_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; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32: 328; GCN: s_load_dword [[SPTR:s[0-9]+]], 329; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4 330; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 331; GCN: ds_add_u32 [[VPTR]], [[DATA]] 332; GCN: s_endpgm 333define void @lds_atomic_add_noret_i32(i32 addrspace(3)* %ptr) nounwind { 334 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst 335 ret void 336} 337 338; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_offset: 339; GCN: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 340; GCN: s_endpgm 341define void @lds_atomic_add_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 342 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 343 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 344 ret void 345} 346 347; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_bad_si_offset 348; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} 349; CIVI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 350; GCN: s_endpgm 351define void @lds_atomic_add_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 352 %sub = sub i32 %a, %b 353 %add = add i32 %sub, 4 354 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 355 %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst 356 ret void 357} 358 359; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32: 360; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 361; GCN: ds_add_u32 v{{[0-9]+}}, [[ONE]] 362; GCN: s_endpgm 363define void @lds_atomic_add1_noret_i32(i32 addrspace(3)* %ptr) nounwind { 364 %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst 365 ret void 366} 367 368; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32_offset: 369; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 370; GCN: ds_add_u32 v{{[0-9]+}}, [[ONE]] offset:16 371; GCN: s_endpgm 372define void @lds_atomic_add1_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 373 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 374 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 375 ret void 376} 377 378; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32_bad_si_offset: 379; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} 380; CIVI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 381; GCN: s_endpgm 382define void @lds_atomic_add1_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind { 383 %sub = sub i32 %a, %b 384 %add = add i32 %sub, 4 385 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add 386 %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst 387 ret void 388} 389 390; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32: 391; GCN: ds_sub_u32 392; GCN: s_endpgm 393define void @lds_atomic_sub_noret_i32(i32 addrspace(3)* %ptr) nounwind { 394 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst 395 ret void 396} 397 398; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32_offset: 399; GCN: ds_sub_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 400; GCN: s_endpgm 401define void @lds_atomic_sub_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 402 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 403 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst 404 ret void 405} 406 407; FUNC-LABEL: {{^}}lds_atomic_sub1_noret_i32: 408; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 409; GCN: ds_sub_u32 v{{[0-9]+}}, [[ONE]] 410; GCN: s_endpgm 411define void @lds_atomic_sub1_noret_i32(i32 addrspace(3)* %ptr) nounwind { 412 %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst 413 ret void 414} 415 416; FUNC-LABEL: {{^}}lds_atomic_sub1_noret_i32_offset: 417; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}} 418; GCN: ds_sub_u32 v{{[0-9]+}}, [[ONE]] offset:16 419; GCN: s_endpgm 420define void @lds_atomic_sub1_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 421 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 422 %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst 423 ret void 424} 425 426; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32: 427; GCN: ds_and_b32 428; GCN: s_endpgm 429define void @lds_atomic_and_noret_i32(i32 addrspace(3)* %ptr) nounwind { 430 %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst 431 ret void 432} 433 434; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32_offset: 435; GCN: ds_and_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 436; GCN: s_endpgm 437define void @lds_atomic_and_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 438 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 439 %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst 440 ret void 441} 442 443; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32: 444; GCN: ds_or_b32 445; GCN: s_endpgm 446define void @lds_atomic_or_noret_i32(i32 addrspace(3)* %ptr) nounwind { 447 %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst 448 ret void 449} 450 451; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32_offset: 452; GCN: ds_or_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 453; GCN: s_endpgm 454define void @lds_atomic_or_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 455 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 456 %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst 457 ret void 458} 459 460; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32: 461; GCN: ds_xor_b32 462; GCN: s_endpgm 463define void @lds_atomic_xor_noret_i32(i32 addrspace(3)* %ptr) nounwind { 464 %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst 465 ret void 466} 467 468; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32_offset: 469; GCN: ds_xor_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 470; GCN: s_endpgm 471define void @lds_atomic_xor_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 472 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 473 %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst 474 ret void 475} 476 477; FIXME: There is no atomic nand instr 478; XFUNC-LABEL: {{^}}lds_atomic_nand_noret_i32:uction, so we somehow need to expand this. 479; define void @lds_atomic_nand_noret_i32(i32 addrspace(3)* %ptr) nounwind { 480; %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst 481; ret void 482; } 483 484; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32: 485; GCN: ds_min_i32 486; GCN: s_endpgm 487define void @lds_atomic_min_noret_i32(i32 addrspace(3)* %ptr) nounwind { 488 %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst 489 ret void 490} 491 492; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32_offset: 493; GCN: ds_min_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 494; GCN: s_endpgm 495define void @lds_atomic_min_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 496 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 497 %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst 498 ret void 499} 500 501; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32: 502; GCN: ds_max_i32 503; GCN: s_endpgm 504define void @lds_atomic_max_noret_i32(i32 addrspace(3)* %ptr) nounwind { 505 %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst 506 ret void 507} 508 509; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32_offset: 510; GCN: ds_max_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 511; GCN: s_endpgm 512define void @lds_atomic_max_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 513 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 514 %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst 515 ret void 516} 517 518; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32: 519; GCN: ds_min_u32 520; GCN: s_endpgm 521define void @lds_atomic_umin_noret_i32(i32 addrspace(3)* %ptr) nounwind { 522 %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst 523 ret void 524} 525 526; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32_offset: 527; GCN: ds_min_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 528; GCN: s_endpgm 529define void @lds_atomic_umin_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 530 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 531 %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst 532 ret void 533} 534 535; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32: 536; GCN: ds_max_u32 537; GCN: s_endpgm 538define void @lds_atomic_umax_noret_i32(i32 addrspace(3)* %ptr) nounwind { 539 %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst 540 ret void 541} 542 543; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32_offset: 544; GCN: ds_max_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 545; GCN: s_endpgm 546define void @lds_atomic_umax_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind { 547 %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4 548 %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst 549 ret void 550} 551