ac/llvm: fix SSBO bounds checking by using raw instead of struct opcodes

Setting vindex != NULL (even if it's 0) selects a struct.buffer.load opcode,
which causes LLVM to look for "index * stride + offset" in voffset and
moves "index" to vindex (i.e. not 0 anymore), but the bounds checking
(OOB_SELECT) is set to ignore vindex. Setting vindex = NULL selects
a raw.buffer.load opcode.

Fixes: 6b573c00c9 - ac/nir: use ac_build_buffer_load() for SSBO load operations
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10794

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28119>
This commit is contained in:
Marek Olšák 2024-03-11 16:16:50 -04:00 committed by Marge Bot
parent 31920cb60c
commit e589833ee1

View file

@ -1935,7 +1935,6 @@ static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx, nir_intrinsic_
LLVMValueRef offset = get_src(ctx, instr->src[1]);
LLVMValueRef rsrc = ctx->abi->load_ssbo ?
ctx->abi->load_ssbo(ctx->abi, rsrc_base, false, false) : rsrc_base;
LLVMValueRef vindex = ctx->ac.i32_0;
LLVMTypeRef def_type = get_def_type(ctx, &instr->def);
LLVMTypeRef def_elem_type = num_components > 1 ? LLVMGetElementType(def_type) : def_type;
@ -1964,7 +1963,7 @@ static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx, nir_intrinsic_
int num_channels = util_next_power_of_two(load_bytes) / 4;
bool can_speculate = access & ACCESS_CAN_REORDER;
ret = ac_build_buffer_load(&ctx->ac, rsrc, num_channels, vindex, voffset, ctx->ac.i32_0,
ret = ac_build_buffer_load(&ctx->ac, rsrc, num_channels, NULL, voffset, ctx->ac.i32_0,
ctx->ac.f32, access, can_speculate, false);
}