ac/llvm: fix huge alignment when loading from shared memory

LLVM doesn't support huge alignments, also it can optimize the shared
loads, so it's unecessary to emit better (but broken) LLVM IR.

Fixes a bunch of crashes with RADV_DEBUG=llvm,checkir.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12616>
This commit is contained in:
Samuel Pitoiset
2021-04-22 10:35:24 +02:00
parent e72c2e36e0
commit 72b6b02e09
+9 -6
View File
@@ -2939,15 +2939,18 @@ static LLVMValueRef visit_first_invocation(struct ac_nir_context *ctx)
static LLVMValueRef visit_load_shared(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr)
{
unsigned alignment = nir_intrinsic_align(instr);
LLVMValueRef values[4], derived_ptr, index, ret;
unsigned const_off = nir_intrinsic_base(instr);
LLVMValueRef ptr = get_memory_ptr(ctx, instr->src[0], instr->dest.ssa.bit_size, const_off);
LLVMTypeRef result_type = get_def_type(ctx, &instr->dest.ssa);
int addr_space = LLVMGetPointerAddressSpace(LLVMTypeOf(ptr));
LLVMValueRef derived_ptr = LLVMBuildBitCast(ctx->ac.builder, ptr, LLVMPointerType(result_type, addr_space), "");
LLVMValueRef ret = LLVMBuildLoad(ctx->ac.builder, derived_ptr, "");
LLVMSetAlignment(ret, alignment);
for (int chan = 0; chan < instr->num_components; chan++) {
index = LLVMConstInt(ctx->ac.i32, chan, 0);
derived_ptr = LLVMBuildGEP(ctx->ac.builder, ptr, &index, 1, "");
values[chan] = LLVMBuildLoad(ctx->ac.builder, derived_ptr, "");
}
ret = ac_build_gather_values(&ctx->ac, values, instr->num_components);
return LLVMBuildBitCast(ctx->ac.builder, ret, get_def_type(ctx, &instr->dest.ssa), "");
}