From 72b6b02e0974b3cee442209325a8450ba7568f5e Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 22 Apr 2021 10:35:24 +0200 Subject: [PATCH] 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 Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/llvm/ac_nir_to_llvm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index 821b96c520c..0b74b10218f 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -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), ""); }