540 lines · plain
1; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=kaveri -mattr=-promote-alloca < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CI,MUBUF %s2; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-promote-alloca < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX9-MUBUF,MUBUF %s3; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-promote-alloca,+enable-flat-scratch < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX9-FLATSCR %s4; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=+real-true16 < %s | FileCheck --check-prefixes=GFX11-TRUE16 %s5; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck --check-prefixes=GFX11-FAKE16 %s6 7; Test that non-entry function frame indices are expanded properly to8; give an index relative to the scratch wave offset register9 10; Materialize into a mov. Make sure there isn't an unnecessary copy.11; GCN-LABEL: {{^}}func_mov_fi_i32:12; GCN: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)13 14; CI-NEXT: v_lshr_b32_e64 v0, s32, 615; GFX9-MUBUF-NEXT: v_lshrrev_b32_e64 v0, 6, s3216 17; GFX9-FLATSCR: v_mov_b32_e32 v0, s3218; GFX9-FLATSCR-NOT: v_lshrrev_b32_e6419 20; MUBUF-NOT: v_mov21 22; GCN: ds_write_b32 v0, v023define void @func_mov_fi_i32() #0 {24 %alloca = alloca i32, addrspace(5)25 store volatile ptr addrspace(5) %alloca, ptr addrspace(3) poison26 ret void27}28 29; Offset due to different objects30; GCN-LABEL: {{^}}func_mov_fi_i32_offset:31; GCN: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)32 33; CI-DAG: v_lshr_b32_e64 v0, s32, 634; CI-NOT: v_mov35; CI: ds_write_b32 v0, v036; CI-NEXT: v_lshr_b32_e64 [[SCALED:v[0-9]+]], s32, 637; CI-NEXT: v_add_i32_e{{32|64}} v0, {{s\[[0-9]+:[0-9]+\]|vcc}}, 4, [[SCALED]]38; CI-NEXT: ds_write_b32 v0, v039 40; GFX9-MUBUF-NEXT: v_lshrrev_b32_e64 v0, 6, s3241; GFX9-FLATSCR: v_mov_b32_e32 v0, s3242; GFX9-FLATSCR: s_add_i32 [[ADD:[^,]+]], s32, 443; GFX9-NEXT: ds_write_b32 v0, v044; GFX9-MUBUF-NEXT: v_lshrrev_b32_e64 [[SCALED:v[0-9]+]], 6, s3245; GFX9-MUBUF-NEXT: v_add_u32_e32 v0, 4, [[SCALED]]46; GFX9-FLATSCR-NEXT: v_mov_b32_e32 v0, [[ADD]]47; GFX9-NEXT: ds_write_b32 v0, v048define void @func_mov_fi_i32_offset() #0 {49 %alloca0 = alloca i32, addrspace(5)50 %alloca1 = alloca i32, addrspace(5)51 store volatile ptr addrspace(5) %alloca0, ptr addrspace(3) poison52 store volatile ptr addrspace(5) %alloca1, ptr addrspace(3) poison53 ret void54}55 56; Materialize into an add of a constant offset from the FI.57; FIXME: Should be able to merge adds58 59; GCN-LABEL: {{^}}func_add_constant_to_fi_i32:60; GCN: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)61 62; CI: v_lshr_b32_e64 [[SCALED:v[0-9]+]], s32, 663; CI-NEXT: v_add_i32_e32 v0, vcc, 4, [[SCALED]]64 65; GFX9-MUBUF: v_lshrrev_b32_e64 [[SCALED:v[0-9]+]], 6, s3266; GFX9-MUBUF-NEXT: v_add_u32_e32 v0, 4, [[SCALED]]67 68; FIXME: Should commute and shrink69; GFX9-FLATSCR: v_add_u32_e64 v0, 4, s3270 71; GCN-NOT: v_mov72; GCN: ds_write_b32 v0, v073define void @func_add_constant_to_fi_i32() #0 {74 %alloca = alloca [2 x i32], align 4, addrspace(5)75 %gep0 = getelementptr inbounds [2 x i32], ptr addrspace(5) %alloca, i32 0, i32 176 store volatile ptr addrspace(5) %gep0, ptr addrspace(3) poison77 ret void78}79 80; A user the materialized frame index can't be meaningfully folded81; into.82; FIXME: Should use s_mul but the frame index always gets materialized into a83; vgpr84 85; GCN-LABEL: {{^}}func_other_fi_user_i32:86; MUBUF: s_lshr_b32 [[SCALED:s[0-9]+]], s32, 687; MUBUF: s_mul_i32 [[MUL:s[0-9]+]], [[SCALED]], 988; MUBUF: v_mov_b32_e32 v0, [[MUL]]89 90; GFX9-FLATSCR: s_mul_i32 [[MUL:s[0-9]+]], s32, 991; GFX9-FLATSCR: v_mov_b32_e32 v0, [[MUL]]92 93; GCN-NOT: v_mov94; GCN: ds_write_b32 v0, v095define void @func_other_fi_user_i32() #0 {96 %alloca = alloca [2 x i32], align 4, addrspace(5)97 %ptrtoint = ptrtoint ptr addrspace(5) %alloca to i3298 %mul = mul i32 %ptrtoint, 999 store volatile i32 %mul, ptr addrspace(3) poison100 ret void101}102 103; GCN-LABEL: {{^}}func_store_private_arg_i32_ptr:104; GCN: v_mov_b32_e32 v1, 15{{$}}105; MUBUF: buffer_store_dword v1, v0, s[0:3], 0 offen{{$}}106; GFX9-FLATSCR: scratch_store_dword v0, v1, off{{$}}107define void @func_store_private_arg_i32_ptr(ptr addrspace(5) %ptr) #0 {108 store volatile i32 15, ptr addrspace(5) %ptr109 ret void110}111 112; GCN-LABEL: {{^}}func_load_private_arg_i32_ptr:113; GCN: s_waitcnt114; MUBUF-NEXT: buffer_load_dword v0, v0, s[0:3], 0 offen glc{{$}}115; GFX9-FLATSCR-NEXT: scratch_load_dword v0, v0, off glc{{$}}116define void @func_load_private_arg_i32_ptr(ptr addrspace(5) %ptr) #0 {117 %val = load volatile i32, ptr addrspace(5) %ptr118 ret void119}120 121; GCN-LABEL: {{^}}void_func_byval_struct_i8_i32_ptr:122; GCN: s_waitcnt123 124; CI: v_lshr_b32_e64 [[SHIFT:v[0-9]+]], s32, 6125; CI-NEXT: v_or_b32_e32 v0, 4, [[SHIFT]]126 127; GFX9-MUBUF: v_lshrrev_b32_e64 [[SHIFT:v[0-9]+]], 6, s32128; GFX9-MUBUF-NEXT: v_or_b32_e32 v0, 4, [[SHIFT]]129 130; GFX9-FLATSCR: v_or_b32_e64 v0, s32, 4131 132; GCN-NOT: v_mov133; GCN: ds_write_b32 v0, v0134define void @void_func_byval_struct_i8_i32_ptr(ptr addrspace(5) byval({ i8, i32 }) %arg0) #0 {135 %gep0 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 0136 %gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 1137 %load1 = load i32, ptr addrspace(5) %gep1138 store volatile ptr addrspace(5) %gep1, ptr addrspace(3) poison139 ret void140}141 142; GCN-LABEL: {{^}}void_func_byval_struct_i8_i32_ptr_value:143; GCN: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)144; MUBUF-NEXT: buffer_load_ubyte v0, off, s[0:3], s32145; MUBUF-NEXT: buffer_load_dword v1, off, s[0:3], s32 offset:4146; GFX9-FLATSCR-NEXT: scratch_load_ubyte v0, off, s32147; GFX9-FLATSCR-NEXT: scratch_load_dword v1, off, s32 offset:4148define void @void_func_byval_struct_i8_i32_ptr_value(ptr addrspace(5) byval({ i8, i32 }) %arg0) #0 {149 %gep0 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 0150 %gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 1151 %load0 = load i8, ptr addrspace(5) %gep0152 %load1 = load i32, ptr addrspace(5) %gep1153 store volatile i8 %load0, ptr addrspace(3) poison154 store volatile i32 %load1, ptr addrspace(3) poison155 ret void156}157 158; GCN-LABEL: {{^}}void_func_byval_struct_i8_i32_ptr_nonentry_block:159 160; GCN: s_and_saveexec_b64161 162; CI: buffer_load_dword v{{[0-9]+}}, off, s[0:3], s32 offset:4 glc{{$}}163; GFX9-MUBUF: buffer_load_dword v{{[0-9]+}}, off, s[0:3], s32 offset:4 glc{{$}}164; GFX9-FLATSCR: scratch_load_dword v{{[0-9]+}}, off, s32 offset:4 glc{{$}}165 166; CI: v_lshr_b32_e64 [[SHIFT:v[0-9]+]], s32, 6167; CI: v_add_i32_e64 [[GEP:v[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 4, [[SHIFT]]168 169; GFX9-MUBUF: v_lshrrev_b32_e64 [[SP:v[0-9]+]], 6, s32170; GFX9-MUBUF: v_add_u32_e32 [[GEP:v[0-9]+]], 4, [[SP]]171 172; GFX9-FLATSCR: v_add_u32_e64 [[GEP:v[0-9]+]], 4, s32173 174; GCN: ds_write_b32 v{{[0-9]+}}, [[GEP]]175define void @void_func_byval_struct_i8_i32_ptr_nonentry_block(ptr addrspace(5) byval({ i8, i32 }) %arg0, i32 %arg2) #0 {176 %cmp = icmp eq i32 %arg2, 0177 br i1 %cmp, label %bb, label %ret178 179bb:180 %gep0 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 0181 %gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %arg0, i32 0, i32 1182 %load1 = load volatile i32, ptr addrspace(5) %gep1183 store volatile ptr addrspace(5) %gep1, ptr addrspace(3) poison184 br label %ret185 186ret:187 ret void188}189 190; Added offset can't be used with VOP3 add191; GCN-LABEL: {{^}}func_other_fi_user_non_inline_imm_offset_i32:192 193; MUBUF: s_lshr_b32 [[SCALED:s[0-9]+]], s32, 6194; MUBUF: s_addk_i32 [[SCALED]], 0x200195 196; MUBUF: s_mul_i32 [[Z:s[0-9]+]], [[SCALED]], 9197; MUBUF: v_mov_b32_e32 [[VZ:v[0-9]+]], [[Z]]198 199; GFX9-FLATSCR: s_add_i32 [[SZ:[^,]+]], s32, 0x200200; GFX9-FLATSCR: s_mul_i32 [[MUL:s[0-9]+]], [[SZ]], 9201; GFX9-FLATSCR: v_mov_b32_e32 [[VZ:v[0-9]+]], [[MUL]]202 203; GCN: ds_write_b32 v0, [[VZ]]204define void @func_other_fi_user_non_inline_imm_offset_i32() #0 {205 %alloca0 = alloca [128 x i32], align 4, addrspace(5)206 %alloca1 = alloca [8 x i32], align 4, addrspace(5)207 %gep0 = getelementptr inbounds [128 x i32], ptr addrspace(5) %alloca0, i32 0, i32 65208 store volatile i32 7, ptr addrspace(5) %gep0209 %ptrtoint = ptrtoint ptr addrspace(5) %alloca1 to i32210 %mul = mul i32 %ptrtoint, 9211 store volatile i32 %mul, ptr addrspace(3) poison212 ret void213}214 215; GCN-LABEL: {{^}}func_other_fi_user_non_inline_imm_offset_i32_vcc_live:216 217; MUBUF: s_lshr_b32 [[SCALED:s[0-9]+]], s32, 6218; MUBUF: s_addk_i32 [[SCALED]], 0x200219; MUBUF: s_mul_i32 [[Z:s[0-9]+]], [[SCALED]], 9220; MUBUF: v_mov_b32_e32 [[VZ:v[0-9]+]], [[Z]]221 222; GFX9-FLATSCR: s_add_i32 [[SZ:[^,]+]], s32, 0x200223; GFX9-FLATSCR: s_mul_i32 [[MUL:s[0-9]+]], [[SZ]], 9224; GFX9-FLATSCR: v_mov_b32_e32 [[VZ:v[0-9]+]], [[MUL]]225 226; GCN: ds_write_b32 v0, [[VZ]]227define void @func_other_fi_user_non_inline_imm_offset_i32_vcc_live() #0 {228 %alloca0 = alloca [128 x i32], align 4, addrspace(5)229 %alloca1 = alloca [8 x i32], align 4, addrspace(5)230 %vcc = call i64 asm sideeffect "; def $0", "={vcc}"()231 %gep0 = getelementptr inbounds [128 x i32], ptr addrspace(5) %alloca0, i32 0, i32 65232 store volatile i32 7, ptr addrspace(5) %gep0233 call void asm sideeffect "; use $0", "{vcc}"(i64 %vcc)234 %ptrtoint = ptrtoint ptr addrspace(5) %alloca1 to i32235 %mul = mul i32 %ptrtoint, 9236 store volatile i32 %mul, ptr addrspace(3) poison237 ret void238}239 240declare void @func(ptr addrspace(5) nocapture) #0241 242; undef flag not preserved in eliminateFrameIndex when handling the243; stores in the middle block.244 245; GCN-LABEL: {{^}}undefined_stack_store_reg:246; GCN: s_and_saveexec_b64247; MUBUF: buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33 offset:248; MUBUF: buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33 offset:249; MUBUF: buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33 offset:250; MUBUF: buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33 offset:251; FLATSCR: scratch_store_dword v0, off, s33 offset:252; FLATSCR: scratch_store_dword v0, off, s33 offset:253; FLATSCR: scratch_store_dword v0, off, s33 offset:254; FLATSCR: scratch_store_dword v{{[0-9]+}}, off, s33 offset:255define void @undefined_stack_store_reg(float %arg, i32 %arg1) #0 {256bb:257 %tmp = alloca <4 x float>, align 16, addrspace(5)258 %tmp2 = insertelement <4 x float> poison, float %arg, i32 0259 store <4 x float> %tmp2, ptr addrspace(5) poison260 %tmp3 = icmp eq i32 %arg1, 0261 br i1 %tmp3, label %bb4, label %bb5262 263bb4:264 call void @func(ptr addrspace(5) nonnull undef)265 store <4 x float> %tmp2, ptr addrspace(5) %tmp, align 16266 call void @func(ptr addrspace(5) nonnull %tmp)267 br label %bb5268 269bb5:270 ret void271}272 273; GCN-LABEL: {{^}}alloca_ptr_nonentry_block:274; GCN: s_and_saveexec_b64275; MUBUF: buffer_load_dword v{{[0-9]+}}, off, s[0:3], s32 offset:4276; FLATSCR: scratch_load_dword v{{[0-9]+}}, off, s32 offset:4277 278; CI: v_lshr_b32_e64 [[SHIFT:v[0-9]+]], s32, 6279; CI-NEXT: v_or_b32_e32 [[PTR:v[0-9]+]], 4, [[SHIFT]]280 281; GFX9-MUBUF: v_lshrrev_b32_e64 [[SHIFT:v[0-9]+]], 6, s32282; GFX9-MUBUF-NEXT: v_or_b32_e32 [[PTR:v[0-9]+]], 4, [[SHIFT]]283 284; GFX9-FLATSCR: v_or_b32_e64 [[PTR:v[0-9]+]], s32, 4285 286; GCN: ds_write_b32 v{{[0-9]+}}, [[PTR]]287define void @alloca_ptr_nonentry_block(i32 %arg0) #0 {288 %alloca0 = alloca { i8, i32 }, align 8, addrspace(5)289 %cmp = icmp eq i32 %arg0, 0290 br i1 %cmp, label %bb, label %ret291 292bb:293 %gep0 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %alloca0, i32 0, i32 0294 %gep1 = getelementptr inbounds { i8, i32 }, ptr addrspace(5) %alloca0, i32 0, i32 1295 %load1 = load volatile i32, ptr addrspace(5) %gep1296 store volatile ptr addrspace(5) %gep1, ptr addrspace(3) poison297 br label %ret298 299ret:300 ret void301}302 303%struct0 = type { [4224 x %type.i16] }304%type.i16 = type { i16 }305@_ZZN0 = external hidden addrspace(3) global %struct0, align 8306 307; GFX11-TRUE16-LABEL: tied_operand_test:308; GFX11-TRUE16: ; %bb.0: ; %entry309; GFX11-TRUE16: scratch_load_d16_b16 [[LDRESULT:v[0-9]+]], off, off310; GFX11-TRUE16: v_mov_b16_e32 [[C:v[0-9]]].{{(l|h)}}, 0x7b311; GFX11-TRUE16-DAG: ds_store_b16 v{{[0-9]+}}, [[LDRESULT]] offset:10312; GFX11-TRUE16-NEXT: s_endpgm313;314; GFX11-FAKE16-LABEL: tied_operand_test:315; GFX11-FAKE16: ; %bb.0: ; %entry316; GFX11-FAKE16: scratch_load_u16 [[LDRESULT:v[0-9]+]], off, off317; GFX11-FAKE16: v_dual_mov_b32 [[C:v[0-9]+]], 0x7b :: v_dual_mov_b32 v{{[0-9]+}}, s{{[0-9]+}}318; GFX11-FAKE16-DAG: ds_store_b16 v{{[0-9]+}}, [[LDRESULT]] offset:10319; GFX11-FAKE16-DAG: ds_store_b16 v{{[0-9]+}}, [[C]] offset:8320; GFX11-FAKE16-NEXT: s_endpgm321define protected amdgpu_kernel void @tied_operand_test(i1 %c1, i1 %c2, i32 %val) {322entry:323 %scratch0 = alloca i16, align 4, addrspace(5)324 %scratch1 = alloca i16, align 4, addrspace(5)325 %first = select i1 %c1, ptr addrspace(5) %scratch0, ptr addrspace(5) %scratch1326 %spec.select = select i1 %c2, ptr addrspace(5) %first, ptr addrspace(5) %scratch0327 %dead.load = load i16, ptr addrspace(5) %spec.select, align 2328 %scratch0.load = load i16, ptr addrspace(5) %scratch0, align 4329 %add4 = add nuw nsw i32 %val, 4330 %addr0 = getelementptr inbounds %struct0, ptr addrspace(3) @_ZZN0, i32 0, i32 0, i32 %add4, i32 0331 store i16 123, ptr addrspace(3) %addr0, align 2332 %add5 = add nuw nsw i32 %val, 5333 %addr1 = getelementptr inbounds %struct0, ptr addrspace(3) @_ZZN0, i32 0, i32 0, i32 %add5, i32 0334 store i16 %scratch0.load, ptr addrspace(3) %addr1, align 2335 ret void336}337 338; GCN-LABEL: {{^}}fi_vop3_literal_error:339; CI: v_lshr_b32_e64 [[SCALED_FP:v[0-9]+]], s33, 6340; CI: s_movk_i32 vcc_lo, 0x3000341; CI-NEXT: v_add_i32_e32 [[SCALED_FP]], vcc, vcc_lo, [[SCALED_FP]]342; CI-NEXT: v_add_i32_e32 v0, vcc, 64, [[SCALED_FP]]343 344; GFX9-MUBUF: v_lshrrev_b32_e64 [[SCALED_FP:v[0-9]+]], 6, s33345; GFX9-MUBUF-NEXT: v_add_u32_e32 [[SCALED_FP]], 0x3000, [[SCALED_FP]]346; GFX9-MUBUF-NEXT: v_add_u32_e32 v0, 64, [[SCALED_FP]]347define void @fi_vop3_literal_error() {348entry:349 %pin.low = alloca i32, align 8192, addrspace(5)350 %local.area = alloca [1060 x i64], align 4096, addrspace(5)351 store i32 0, ptr addrspace(5) %pin.low, align 4352 %gep.small.offset = getelementptr i8, ptr addrspace(5) %local.area, i64 64353 %load1 = load volatile i64, ptr addrspace(5) %gep.small.offset, align 4354 ret void355}356 357; Check for "SOP2/SOPC instruction requires too many immediate358; constants" verifier error. Frame index would fold into low half of359; the lowered flat pointer add, and use s_add_u32 instead of360; s_add_i32.361 362; GCN-LABEL: {{^}}fi_sop2_s_add_u32_literal_error:363; GCN: s_movk_i32 [[S_MOVK_I32_:s[0-9]+]], 0x1000364; GCN: s_add_u32 [[ADD_LO:s[0-9]+]], 0x1010, [[S_MOVK_I32_]]365; GCN: s_addc_u32 [[ADD_HI:s[0-9]+]], s{{[0-9]+}}, 0366define amdgpu_kernel void @fi_sop2_s_add_u32_literal_error() #0 {367entry:368 %.omp.reduction.element.i.i.i.i = alloca [1024 x i32], align 4, addrspace(5)369 %Total3.i.i = alloca [1024 x i32], align 16, addrspace(5)370 %Total3.ascast.i.i = addrspacecast ptr addrspace(5) %Total3.i.i to ptr371 %gep = getelementptr i8, ptr %Total3.ascast.i.i, i64 4096372 %p2i = ptrtoint ptr %gep to i64373 br label %.shuffle.then.i.i.i.i374 375.shuffle.then.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i, %entry376 store i64 0, ptr addrspace(5) null, align 4377 %icmp = icmp ugt i64 %p2i, 1378 br i1 %icmp, label %.shuffle.then.i.i.i.i, label %vector.body.i.i.i.i379 380vector.body.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i381 %wide.load9.i.i.i.i = load <2 x i32>, ptr addrspace(5) %.omp.reduction.element.i.i.i.i, align 4382 store <2 x i32> %wide.load9.i.i.i.i, ptr addrspace(5) null, align 4383 ret void384}385 386; GCN-LABEL: {{^}}fi_sop2_and_literal_error:387; GCN: s_and_b32 s{{[0-9]+}}, s{{[0-9]+}}, 0x1fe00388define amdgpu_kernel void @fi_sop2_and_literal_error() #0 {389entry:390 %.omp.reduction.element.i.i.i.i = alloca [1024 x i32], align 4, addrspace(5)391 %Total3.i.i = alloca [1024 x i32], align 16, addrspace(5)392 %p2i = ptrtoint ptr addrspace(5) %Total3.i.i to i32393 br label %.shuffle.then.i.i.i.i394 395.shuffle.then.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i, %entry396 store i64 0, ptr addrspace(5) null, align 4397 %or = and i32 %p2i, -512398 %icmp = icmp ugt i32 %or, 9999999399 br i1 %icmp, label %.shuffle.then.i.i.i.i, label %vector.body.i.i.i.i400 401vector.body.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i402 %wide.load9.i.i.i.i = load <2 x i32>, ptr addrspace(5) %.omp.reduction.element.i.i.i.i, align 4403 store <2 x i32> %wide.load9.i.i.i.i, ptr addrspace(5) null, align 4404 ret void405}406 407; GCN-LABEL: {{^}}fi_sop2_or_literal_error:408; GCN: s_or_b32 s{{[0-9]+}}, s{{[0-9]+}}, 0x3039409define amdgpu_kernel void @fi_sop2_or_literal_error() #0 {410entry:411 %.omp.reduction.element.i.i.i.i = alloca [1024 x i32], align 4, addrspace(5)412 %Total3.i.i = alloca [1024 x i32], align 16, addrspace(5)413 %p2i = ptrtoint ptr addrspace(5) %Total3.i.i to i32414 br label %.shuffle.then.i.i.i.i415 416.shuffle.then.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i, %entry417 store i64 0, ptr addrspace(5) null, align 4418 %or = or i32 %p2i, 12345419 %icmp = icmp ugt i32 %or, 9999999420 br i1 %icmp, label %.shuffle.then.i.i.i.i, label %vector.body.i.i.i.i421 422vector.body.i.i.i.i: ; preds = %.shuffle.then.i.i.i.i423 %wide.load9.i.i.i.i = load <2 x i32>, ptr addrspace(5) %.omp.reduction.element.i.i.i.i, align 4424 store <2 x i32> %wide.load9.i.i.i.i, ptr addrspace(5) null, align 4425 ret void426}427 428; Check that we do not produce a verifier error after prolog429; epilog. alloca1 and alloca2 will lower to literals.430 431; GCN-LABEL: {{^}}s_multiple_frame_indexes_literal_offsets:432; GCN: s_load_dword [[ARG0:s[0-9]+]]433; GCN: s_movk_i32 [[ALLOCA1:s[0-9]+]], 0x44434; GCN: s_cmp_eq_u32 [[ARG0]], 0435; GCN: s_cselect_b32 [[SELECT:s[0-9]+]], [[ALLOCA1]], 0x48436; GCN: s_mov_b32 [[ALLOCA0:s[0-9]+]], 0437; GCN: ; use [[SELECT]], [[ALLOCA0]]438define amdgpu_kernel void @s_multiple_frame_indexes_literal_offsets(i32 inreg %arg0) #0 {439 %alloca0 = alloca [17 x i32], align 8, addrspace(5)440 %alloca1 = alloca i32, align 4, addrspace(5)441 %alloca2 = alloca i32, align 4, addrspace(5)442 %cmp = icmp eq i32 %arg0, 0443 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2444 call void asm sideeffect "; use $0, $1","s,s"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)445 ret void446}447 448; %alloca1 or alloca2 will lower to an inline constant, and one will449; be a literal, so we could fold both indexes into the instruction.450 451; GCN-LABEL: {{^}}s_multiple_frame_indexes_one_imm_one_literal_offset:452; GCN: s_load_dword [[ARG0:s[0-9]+]]453; GCN: s_mov_b32 [[ALLOCA1:s[0-9]+]], 64454; GCN: s_cmp_eq_u32 [[ARG0]], 0455; GCN: s_cselect_b32 [[SELECT:s[0-9]+]], [[ALLOCA1]], 0x44456; GCN: s_mov_b32 [[ALLOCA0:s[0-9]+]], 0457; GCN: ; use [[SELECT]], [[ALLOCA0]]458define amdgpu_kernel void @s_multiple_frame_indexes_one_imm_one_literal_offset(i32 inreg %arg0) #0 {459 %alloca0 = alloca [16 x i32], align 8, addrspace(5)460 %alloca1 = alloca i32, align 4, addrspace(5)461 %alloca2 = alloca i32, align 4, addrspace(5)462 %cmp = icmp eq i32 %arg0, 0463 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2464 call void asm sideeffect "; use $0, $1","s,s"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)465 ret void466}467 468; GCN-LABEL: {{^}}s_multiple_frame_indexes_imm_offsets:469; GCN: s_load_dword [[ARG0:s[0-9]+]]470; GCN: s_mov_b32 [[ALLOCA1:s[0-9]+]], 16471; GCN: s_cmp_eq_u32 [[ARG0]], 0472; GCN: s_cselect_b32 [[SELECT:s[0-9]+]], [[ALLOCA1]], 20473; GCN: s_mov_b32 [[ALLOCA0:s[0-9]+]], 0474; GCN: ; use [[SELECT]], [[ALLOCA0]]475define amdgpu_kernel void @s_multiple_frame_indexes_imm_offsets(i32 inreg %arg0) #0 {476 %alloca0 = alloca [4 x i32], align 8, addrspace(5)477 %alloca1 = alloca i32, align 4, addrspace(5)478 %alloca2 = alloca i32, align 4, addrspace(5)479 %cmp = icmp eq i32 %arg0, 0480 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2481 call void asm sideeffect "; use $0, $1","s,s"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)482 ret void483}484 485; GCN-LABEL: {{^}}v_multiple_frame_indexes_literal_offsets:486; GCN: v_mov_b32_e32 [[ALLOCA1:v[0-9]+]], 0x48487; GCN: v_mov_b32_e32 [[ALLOCA2:v[0-9]+]], 0x44488; GCN: v_cmp_eq_u32_e32 vcc, 0, v0489; GCN: v_cndmask_b32_e32 [[SELECT:v[0-9]+]], [[ALLOCA1]], [[ALLOCA2]], vcc490; GCN: v_mov_b32_e32 [[ALLOCA0:v[0-9]+]], 0{{$}}491; GCN: ; use [[SELECT]], [[ALLOCA0]]492define amdgpu_kernel void @v_multiple_frame_indexes_literal_offsets() #0 {493 %vgpr = call i32 @llvm.amdgcn.workitem.id.x()494 %alloca0 = alloca [17 x i32], align 8, addrspace(5)495 %alloca1 = alloca i32, align 4, addrspace(5)496 %alloca2 = alloca i32, align 4, addrspace(5)497 %cmp = icmp eq i32 %vgpr, 0498 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2499 call void asm sideeffect "; use $0, $1","v,v"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)500 ret void501}502 503; GCN-LABEL: {{^}}v_multiple_frame_indexes_one_imm_one_literal_offset:504; GCN: v_mov_b32_e32 [[ALLOCA1:v[0-9]+]], 0x44505; GCN: v_mov_b32_e32 [[ALLOCA2:v[0-9]+]], 64506; GCN: v_cmp_eq_u32_e32 vcc, 0, v0507; GCN: v_cndmask_b32_e32 [[SELECT:v[0-9]+]], [[ALLOCA1]], [[ALLOCA2]], vcc508; GCN: v_mov_b32_e32 [[ALLOCA0:v[0-9]+]], 0{{$}}509; GCN: ; use [[SELECT]], [[ALLOCA0]]510define amdgpu_kernel void @v_multiple_frame_indexes_one_imm_one_literal_offset() #0 {511 %vgpr = call i32 @llvm.amdgcn.workitem.id.x()512 %alloca0 = alloca [16 x i32], align 8, addrspace(5)513 %alloca1 = alloca i32, align 4, addrspace(5)514 %alloca2 = alloca i32, align 4, addrspace(5)515 %cmp = icmp eq i32 %vgpr, 0516 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2517 call void asm sideeffect "; use $0, $1","v,v"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)518 ret void519}520 521; GCN-LABEL: {{^}}v_multiple_frame_indexes_imm_offsets:522; GCN: v_mov_b32_e32 [[ALLOCA1:v[0-9]+]], 12523; GCN: v_mov_b32_e32 [[ALLOCA2:v[0-9]+]], 8524; GCN: v_cmp_eq_u32_e32 vcc, 0, v0525; GCN: v_cndmask_b32_e32 [[SELECT:v[0-9]+]], [[ALLOCA1]], [[ALLOCA2]], vcc526; GCN: v_mov_b32_e32 [[ALLOCA0:v[0-9]+]], 0{{$}}527; GCN: ; use [[SELECT]], [[ALLOCA0]]528define amdgpu_kernel void @v_multiple_frame_indexes_imm_offsets() #0 {529 %vgpr = call i32 @llvm.amdgcn.workitem.id.x()530 %alloca0 = alloca [2 x i32], align 8, addrspace(5)531 %alloca1 = alloca i32, align 4, addrspace(5)532 %alloca2 = alloca i32, align 4, addrspace(5)533 %cmp = icmp eq i32 %vgpr, 0534 %select = select i1 %cmp, ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca2535 call void asm sideeffect "; use $0, $1","v,v"(ptr addrspace(5) %select, ptr addrspace(5) %alloca0)536 ret void537}538 539attributes #0 = { nounwind }540