From 0ae778ca59a75b883cfc04c8a2cf62169381f734 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timur=20Krist=C3=B3f?= Date: Mon, 13 Feb 2023 12:14:04 +0100 Subject: [PATCH] ac/llvm: Fix ac_build_buffer_load to work with more than 4 channels. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit LLVM is unable to select instructions for num_channels > 4, so we workaround that by manually splitting larger buffer loads. Signed-off-by: Timur Kristóf Reviewed-by: Qiang Yu Reviewed-by: Marek Olšák Acked-by: Konstantin Seurer Part-of: --- src/amd/llvm/ac_llvm_build.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index b5e3dc5..90512bf 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -618,6 +618,9 @@ LLVMValueRef ac_build_gather_values(struct ac_llvm_context *ctx, LLVMValueRef *v LLVMValueRef ac_build_concat(struct ac_llvm_context *ctx, LLVMValueRef a, LLVMValueRef b) { + if (!a) + return b; + unsigned a_size = ac_get_llvm_num_components(a); unsigned b_size = ac_get_llvm_num_components(b); @@ -1365,8 +1368,22 @@ LLVMValueRef ac_build_buffer_load(struct ac_llvm_context *ctx, LLVMValueRef rsrc return ac_build_gather_values(ctx, result, num_channels); } - return ac_build_buffer_load_common(ctx, rsrc, vindex, voffset, soffset, num_channels, - channel_type, cache_policy, can_speculate, false); + /* LLVM is unable to select instructions for num_channels > 4, so we + * workaround that by manually splitting larger buffer loads. + */ + LLVMValueRef result = NULL; + for (unsigned i = 0, fetch_num_channels; i < num_channels; i += fetch_num_channels) { + fetch_num_channels = MIN2(4, num_channels - i); + LLVMValueRef fetch_voffset = + LLVMBuildAdd(ctx->builder, voffset, + LLVMConstInt(ctx->i32, i * ac_get_type_size(channel_type), 0), ""); + LLVMValueRef item = + ac_build_buffer_load_common(ctx, rsrc, vindex, fetch_voffset, soffset, fetch_num_channels, + channel_type, cache_policy, can_speculate, false); + result = ac_build_concat(ctx, result, item); + } + + return result; } LLVMValueRef ac_build_buffer_load_format(struct ac_llvm_context *ctx, LLVMValueRef rsrc, -- 2.7.4