460 lines · plain
1; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=amdgpu-lower-kernel-attributes,instcombine,infer-alignment %s | FileCheck -enable-var-scope %s2; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=amdgpu-lower-kernel-attributes,instcombine,infer-alignment %s | FileCheck -enable-var-scope %s3 4; CHECK-LABEL: @invalid_reqd_work_group_size(5; CHECK: load i16,6define amdgpu_kernel void @invalid_reqd_work_group_size(ptr addrspace(1) %out) #0 !reqd_work_group_size !1 {7 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()8 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 49 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 410 store i16 %group.size.x, ptr addrspace(1) %out11 ret void12}13 14; CHECK-LABEL: @volatile_load_group_size_x(15; CHECK: load volatile i16,16define amdgpu_kernel void @volatile_load_group_size_x(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {17 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()18 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 419 %group.size.x = load volatile i16, ptr addrspace(4) %gep.group.size.x, align 420 store i16 %group.size.x, ptr addrspace(1) %out21 ret void22}23 24; CHECK-LABEL: @load_group_size_x(25; CHECK: store i16 %group.size.x,26define amdgpu_kernel void @load_group_size_x(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {27 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()28 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 429 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 430 store i16 %group.size.x, ptr addrspace(1) %out31 ret void32}33 34; CHECK-LABEL: @load_group_size_y(35; CHECK: store i16 %group.size.y,36define amdgpu_kernel void @load_group_size_y(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {37 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()38 %gep.group.size.y = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 639 %group.size.y = load i16, ptr addrspace(4) %gep.group.size.y, align 440 store i16 %group.size.y, ptr addrspace(1) %out41 ret void42}43 44; CHECK-LABEL: @load_group_size_z(45; CHECK: store i16 %group.size.z,46define amdgpu_kernel void @load_group_size_z(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {47 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()48 %gep.group.size.z = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 849 %group.size.z = load i16, ptr addrspace(4) %gep.group.size.z, align 450 store i16 %group.size.z, ptr addrspace(1) %out51 ret void52}53 54; Metadata uses i64 instead of i3255; CHECK-LABEL: @load_group_size_x_reqd_work_group_size_i64(56; CHECK: store i16 %group.size.x,57define amdgpu_kernel void @load_group_size_x_reqd_work_group_size_i64(ptr addrspace(1) %out) #0 !reqd_work_group_size !2 {58 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()59 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 460 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 461 store i16 %group.size.x, ptr addrspace(1) %out62 ret void63}64 65; Metadata uses i16 instead of i3266; CHECK-LABEL: @load_group_size_x_reqd_work_group_size_i16(67; CHECK: store i16 %group.size.x,68define amdgpu_kernel void @load_group_size_x_reqd_work_group_size_i16(ptr addrspace(1) %out) #0 !reqd_work_group_size !3 {69 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()70 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 471 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 472 store i16 %group.size.x, ptr addrspace(1) %out73 ret void74}75 76; CHECK-LABEL: @use_local_size_x_8_16_2(77; CHECK: store i64 %zext,78define amdgpu_kernel void @use_local_size_x_8_16_2(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {79 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()80 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 481 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 482 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 1283 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 484 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()85 %group.size.x.zext = zext i16 %group.size.x to i3286 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext87 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x88 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)89 %zext = zext i32 %umin to i6490 store i64 %zext, ptr addrspace(1) %out91 ret void92}93 94; CHECK-LABEL: @use_local_size_y_8_16_2(95; CHECK: store i64 %zext,96define amdgpu_kernel void @use_local_size_y_8_16_2(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {97 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()98 %gep.group.size.y = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 699 %group.size.y = load i16, ptr addrspace(4) %gep.group.size.y, align 4100 %gep.grid.size.y = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 16101 %grid.size.y = load i32, ptr addrspace(4) %gep.grid.size.y, align 4102 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.y()103 %group.size.y.zext = zext i16 %group.size.y to i32104 %group.id_x_group.size.y = mul i32 %group.id, %group.size.y.zext105 %sub = sub i32 %grid.size.y, %group.id_x_group.size.y106 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.y.zext)107 %zext = zext i32 %umin to i64108 store i64 %zext, ptr addrspace(1) %out109 ret void110}111 112; CHECK-LABEL: @use_local_size_z_8_16_2(113; CHECK: store i64 %zext,114define amdgpu_kernel void @use_local_size_z_8_16_2(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {115 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()116 %gep.group.size.z = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 8117 %group.size.z = load i16, ptr addrspace(4) %gep.group.size.z, align 4118 %gep.grid.size.z = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 20119 %grid.size.z = load i32, ptr addrspace(4) %gep.grid.size.z, align 4120 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.z()121 %group.size.z.zext = zext i16 %group.size.z to i32122 %group.id_x_group.size.z = mul i32 %group.id, %group.size.z.zext123 %sub = sub i32 %grid.size.z, %group.id_x_group.size.z124 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.z.zext)125 %zext = zext i32 %umin to i64126 store i64 %zext, ptr addrspace(1) %out127 ret void128}129 130; Simplification on select is invalid, but we can still eliminate the131; load of the group size.132 133; CHECK-LABEL: @local_size_x_8_16_2_wrong_group_id(134; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.y()135; CHECK: %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext136define amdgpu_kernel void @local_size_x_8_16_2_wrong_group_id(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {137 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()138 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4139 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4140 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12141 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4142 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.y()143 %group.size.x.zext = zext i16 %group.size.x to i32144 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext145 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x146 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)147 %zext = zext i32 %umin to i64148 store i64 %zext, ptr addrspace(1) %out149 ret void150}151 152; CHECK-LABEL: @local_size_x_8_16_2_wrong_grid_size(153; CHECK: %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4154; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()155; CHECK: %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext156 define amdgpu_kernel void @local_size_x_8_16_2_wrong_grid_size(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {157 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()158 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4159 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4160 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 16161 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4162 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()163 %group.size.x.zext = zext i16 %group.size.x to i32164 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext165 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x166 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)167 %zext = zext i32 %umin to i64168 store i64 %zext, ptr addrspace(1) %out169 ret void170}171 172; CHECK-LABEL: @local_size_x_8_16_2_wrong_cmp_type(173; CHECK: %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4174; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()175; CHECK: %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext176; CHECK: %sub = sub i32 %grid.size.x, %group.id_x_group.size.x177; CHECK: %smin = call i32 @llvm.smin.i32(i32 %sub, i32 %group.size.x.zext)178define amdgpu_kernel void @local_size_x_8_16_2_wrong_cmp_type(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {179 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()180 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4181 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4182 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12183 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4184 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()185 %group.size.x.zext = zext i16 %group.size.x to i32186 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext187 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x188 %smin = call i32 @llvm.smin.i32(i32 %sub, i32 %group.size.x.zext)189 %zext = zext i32 %smin to i64190 store i64 %zext, ptr addrspace(1) %out191 ret void192}193 194; CHECK-LABEL: @local_size_x_8_16_2_wrong_select(195; CHECK: %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext196; CHECK: %sub = sub i32 %grid.size.x, %group.id_x_group.size.x197; CHECK: %umax = call i32 @llvm.umax.i32(i32 %sub, i32 %group.size.x.zext)198; CHECK: %zext = zext i32 %umax to i64199define amdgpu_kernel void @local_size_x_8_16_2_wrong_select(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {200 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()201 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4202 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4203 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12204 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4205 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()206 %group.size.x.zext = zext i16 %group.size.x to i32207 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext208 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x209 %umax = call i32 @llvm.umax.i32(i32 %sub, i32 %group.size.x.zext)210 %zext = zext i32 %umax to i64211 store i64 %zext, ptr addrspace(1) %out212 ret void213}214 215; CHECK-LABEL: @use_local_size_x_8_16_2_wrong_grid_load_size(216; CHECK: %grid.size.x = load i16, ptr addrspace(4) %gep.grid.size.x, align 4217; CHECK: %grid.size.x.zext = zext i16 %grid.size.x to i32218; CHECK: %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()219; CHECK: %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext220; CHECK: %sub = sub i32 %grid.size.x.zext, %group.id_x_group.size.x221define amdgpu_kernel void @use_local_size_x_8_16_2_wrong_grid_load_size(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {222 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()223 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4224 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4225 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12226 %grid.size.x = load i16, ptr addrspace(4) %gep.grid.size.x, align 4227 %grid.size.x.zext = zext i16 %grid.size.x to i32228 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()229 %group.size.x.zext = zext i16 %group.size.x to i32230 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext231 %sub = sub i32 %grid.size.x.zext, %group.id_x_group.size.x232 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)233 %zext = zext i32 %umin to i64234 store i64 %zext, ptr addrspace(1) %out235 ret void236}237 238; CHECK-LABEL: @func_group_size_x(239; CHECK: ret i32 %zext240define i32 @func_group_size_x(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {241 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()242 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4243 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4244 %zext = zext i16 %group.size.x to i32245 ret i32 %zext246}247 248; CHECK-LABEL: @__ockl_get_local_size_reqd_size(249; CHECK: %group.size = phi i16 [ %tmp24, %bb17 ], [ %tmp16, %bb9 ], [ %tmp8, %bb1 ], [ 1, %bb ]250define i64 @__ockl_get_local_size_reqd_size(i32 %arg) #1 !reqd_work_group_size !0 {251bb:252 %tmp = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() #2253 switch i32 %arg, label %bb25 [254 i32 0, label %bb1255 i32 1, label %bb9256 i32 2, label %bb17257 ]258 259bb1: ; preds = %bb260 %tmp2 = tail call i32 @llvm.amdgcn.workgroup.id.x()261 %tmp3 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 12262 %tmp5 = load i32, ptr addrspace(4) %tmp3, align 4263 %tmp6 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 4264 %tmp8 = load i16, ptr addrspace(4) %tmp6, align 4265 br label %bb25266 267bb9: ; preds = %bb268 %tmp10 = tail call i32 @llvm.amdgcn.workgroup.id.y()269 %tmp11 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 16270 %tmp13 = load i32, ptr addrspace(4) %tmp11, align 8271 %tmp14 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 6272 %tmp16 = load i16, ptr addrspace(4) %tmp14, align 2273 br label %bb25274 275bb17: ; preds = %bb276 %tmp18 = tail call i32 @llvm.amdgcn.workgroup.id.z()277 %tmp19 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 20278 %tmp21 = load i32, ptr addrspace(4) %tmp19, align 4279 %tmp22 = getelementptr inbounds i8, ptr addrspace(4) %tmp, i64 8280 %tmp24 = load i16, ptr addrspace(4) %tmp22, align 8281 br label %bb25282 283bb25: ; preds = %bb17, %bb9, %bb1, %bb284 %tmp26 = phi i32 [ %tmp21, %bb17 ], [ %tmp13, %bb9 ], [ %tmp5, %bb1 ], [ 0, %bb ]285 %group.size = phi i16 [ %tmp24, %bb17 ], [ %tmp16, %bb9 ], [ %tmp8, %bb1 ], [ 1, %bb ]286 %tmp28 = phi i32 [ %tmp18, %bb17 ], [ %tmp10, %bb9 ], [ %tmp2, %bb1 ], [ 0, %bb ]287 %tmp29 = zext i16 %group.size to i32288 %tmp30 = mul i32 %tmp28, %tmp29289 %tmp31 = sub i32 %tmp26, %tmp30290 %umin = call i32 @llvm.umin.i32(i32 %tmp31, i32 %tmp29)291 %tmp34 = zext i32 %umin to i64292 ret i64 %tmp34293}294 295; CHECK-LABEL: @all_local_size(296; CHECK: store volatile i64 %tmp34.i, ptr addrspace(1) %out, align 4297; CHECK-NEXT: store volatile i64 %tmp34.i14, ptr addrspace(1) %out, align 4298; CHECK-NEXT: store volatile i64 %tmp34.i7, ptr addrspace(1) %out, align 4299define amdgpu_kernel void @all_local_size(ptr addrspace(1) nocapture readnone %out) #0 !reqd_work_group_size !0 {300 %tmp.i = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() #0301 %tmp2.i = tail call i32 @llvm.amdgcn.workgroup.id.x() #0302 %tmp3.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 12303 %tmp5.i = load i32, ptr addrspace(4) %tmp3.i, align 4304 %tmp6.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 4305 %tmp8.i = load i16, ptr addrspace(4) %tmp6.i, align 4306 %tmp29.i = zext i16 %tmp8.i to i32307 %tmp30.i = mul i32 %tmp2.i, %tmp29.i308 %tmp31.i = sub i32 %tmp5.i, %tmp30.i309 %umin0 = call i32 @llvm.umin.i32(i32 %tmp31.i, i32 %tmp29.i)310 %tmp34.i = zext i32 %umin0 to i64311 %tmp10.i = tail call i32 @llvm.amdgcn.workgroup.id.y() #0312 %tmp11.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 16313 %tmp13.i = load i32, ptr addrspace(4) %tmp11.i, align 8314 %tmp14.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 6315 %tmp16.i = load i16, ptr addrspace(4) %tmp14.i, align 2316 %tmp29.i9 = zext i16 %tmp16.i to i32317 %tmp30.i10 = mul i32 %tmp10.i, %tmp29.i9318 %tmp31.i11 = sub i32 %tmp13.i, %tmp30.i10319 %umin1 = call i32 @llvm.umin.i32(i32 %tmp31.i11, i32 %tmp29.i9)320 %tmp34.i14 = zext i32 %umin1 to i64321 %tmp18.i = tail call i32 @llvm.amdgcn.workgroup.id.z() #0322 %tmp19.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 20323 %tmp21.i = load i32, ptr addrspace(4) %tmp19.i, align 4324 %tmp22.i = getelementptr inbounds i8, ptr addrspace(4) %tmp.i, i64 8325 %tmp24.i = load i16, ptr addrspace(4) %tmp22.i, align 8326 %tmp29.i2 = zext i16 %tmp24.i to i32327 %tmp30.i3 = mul i32 %tmp18.i, %tmp29.i2328 %tmp31.i4 = sub i32 %tmp21.i, %tmp30.i3329 %umin2 = call i32 @llvm.umin.i32(i32 %tmp31.i4, i32 %tmp29.i2)330 %tmp34.i7 = zext i32 %umin2 to i64331 store volatile i64 %tmp34.i, ptr addrspace(1) %out, align 4332 store volatile i64 %tmp34.i14, ptr addrspace(1) %out, align 4333 store volatile i64 %tmp34.i7, ptr addrspace(1) %out, align 4334 ret void335}336 337; TODO: Should be able to handle this, but not much reason to.338; CHECK-LABEL: @partial_load_group_size_x(339; CHECK-NEXT: %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()340; CHECK-NEXT: %gep.group.size.x = getelementptr inbounds nuw i8, ptr addrspace(4) %dispatch.ptr, i64 4341; CHECK-NEXT: %group.size.x.lo = load i8, ptr addrspace(4) %gep.group.size.x, align 4342; CHECK-NEXT: store i8 %group.size.x.lo, ptr addrspace(1) %out, align 1343define amdgpu_kernel void @partial_load_group_size_x(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {344 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()345 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4346 %group.size.x.lo = load i8, ptr addrspace(4) %gep.group.size.x, align 1347 store i8 %group.size.x.lo, ptr addrspace(1) %out348 ret void349}350 351; CHECK-LABEL: @partial_load_group_size_x_explicit_callsite_align(352; CHECK-NEXT: %dispatch.ptr = tail call align 2 ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()353; CHECK-NEXT: %gep.group.size.x = getelementptr inbounds nuw i8, ptr addrspace(4) %dispatch.ptr, i64 4354; CHECK-NEXT: %group.size.x.lo = load i8, ptr addrspace(4) %gep.group.size.x, align 2355; CHECK-NEXT: store i8 %group.size.x.lo, ptr addrspace(1) %out, align 1356define amdgpu_kernel void @partial_load_group_size_x_explicit_callsite_align(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {357 %dispatch.ptr = tail call align 2 ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()358 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4359 %group.size.x.lo = load i8, ptr addrspace(4) %gep.group.size.x, align 1360 store i8 %group.size.x.lo, ptr addrspace(1) %out361 ret void362}363 364; TODO: Should be able to handle this365; CHECK-LABEL: @load_group_size_xy_i32(366; CHECK: %group.size.xy = load i32,367; CHECK: store i32 %group.size.xy368define amdgpu_kernel void @load_group_size_xy_i32(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {369 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()370 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4371 %group.size.xy = load i32, ptr addrspace(4) %gep.group.size.x, align 4372 store i32 %group.size.xy, ptr addrspace(1) %out373 ret void374}375 376; CHECK-LABEL: @load_group_size_x_y_multiple_dispatch_ptr(377; CHECK: store volatile i16 %group.size.x, ptr addrspace(1) %out, align 2378; CHECK: store volatile i16 %group.size.y, ptr addrspace(1) %out, align 2379define amdgpu_kernel void @load_group_size_x_y_multiple_dispatch_ptr(ptr addrspace(1) %out) #0 !reqd_work_group_size !0 {380 %dispatch.ptr0 = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()381 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr0, i64 4382 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4383 store volatile i16 %group.size.x, ptr addrspace(1) %out384 385 %dispatch.ptr1 = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()386 %gep.group.size.y = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr1, i64 6387 %group.size.y = load i16, ptr addrspace(4) %gep.group.size.y, align 4388 store volatile i16 %group.size.y, ptr addrspace(1) %out389 390 ret void391}392 393; CHECK-LABEL: @use_local_size_x_uniform_work_group_size(394; CHECK-NEXT: %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()395; CHECK-NEXT: %gep.group.size.x = getelementptr inbounds nuw i8, ptr addrspace(4) %dispatch.ptr, i64 4396; CHECK-NEXT: %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4397; CHECK: %group.size.x.zext = zext i16 %group.size.x to i32398; CHECK: store i64 %zext, ptr addrspace(1) %out399define amdgpu_kernel void @use_local_size_x_uniform_work_group_size(ptr addrspace(1) %out) #2 {400 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()401 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4402 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4403 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12404 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4405 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()406 %group.size.x.zext = zext i16 %group.size.x to i32407 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext408 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x409 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)410 %zext = zext i32 %umin to i64411 store i64 %zext, ptr addrspace(1) %out412 ret void413}414 415; CHECK-LABEL: @use_local_size_x_uniform_work_group_size_false(416; CHECK: call i32 @llvm.umin417define amdgpu_kernel void @use_local_size_x_uniform_work_group_size_false(ptr addrspace(1) %out) #3 {418 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()419 %gep.group.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 4420 %group.size.x = load i16, ptr addrspace(4) %gep.group.size.x, align 4421 %gep.grid.size.x = getelementptr inbounds i8, ptr addrspace(4) %dispatch.ptr, i64 12422 %grid.size.x = load i32, ptr addrspace(4) %gep.grid.size.x, align 4423 %group.id = tail call i32 @llvm.amdgcn.workgroup.id.x()424 %group.size.x.zext = zext i16 %group.size.x to i32425 %group.id_x_group.size.x = mul i32 %group.id, %group.size.x.zext426 %sub = sub i32 %grid.size.x, %group.id_x_group.size.x427 %umin = call i32 @llvm.umin.i32(i32 %sub, i32 %group.size.x.zext)428 %zext = zext i32 %umin to i64429 store i64 %zext, ptr addrspace(1) %out430 ret void431}432 433; CHECK-LABEL: @no_use_dispatch_ptr(434; CHECK-NEXT: ret void435define amdgpu_kernel void @no_use_dispatch_ptr() {436 %dispatch.ptr = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()437 ret void438}439 440declare ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() #1441declare i32 @llvm.amdgcn.workgroup.id.x() #1442declare i32 @llvm.amdgcn.workgroup.id.y() #1443declare i32 @llvm.amdgcn.workgroup.id.z() #1444declare i32 @llvm.umin.i32(i32, i32) #1445declare i32 @llvm.smin.i32(i32, i32) #1446declare i32 @llvm.umax.i32(i32, i32) #1447 448attributes #0 = { nounwind "uniform-work-group-size"="true" }449attributes #1 = { nounwind readnone speculatable }450attributes #2 = { nounwind "uniform-work-group-size"="true" }451attributes #3 = { nounwind "uniform-work-group-size"="false" }452 453!0 = !{i32 8, i32 16, i32 2}454!1 = !{i32 8, i32 16}455!2 = !{i64 8, i64 16, i64 2}456!3 = !{i16 8, i16 16, i16 2}457 458!llvm.module.flags = !{!4}459!4 = !{i32 1, !"amdhsa_code_object_version", i32 500}460