From 1e2663b62c241d6389e3f97cb8e104ccdd8d567e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timur=20Krist=C3=B3f?= Date: Thu, 19 May 2022 23:13:28 +0200 Subject: [PATCH] ac/llvm: Add LLVM bug workaround to ac_build_mbcnt_add. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit LLVM always believes that this instruction's upper bound is the wave size, regardless of ac_set_range_metadata and regardless of whether the add source is used. As a workaround, emit an extra add instruction. Cc: mesa-stable Signed-off-by: Timur Kristóf Reviewed-by: Qiang Yu Part-of: --- src/amd/llvm/ac_llvm_build.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index 9bb6e6a..ab2326c 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -3220,21 +3220,28 @@ LLVMValueRef ac_build_writelane(struct ac_llvm_context *ctx, LLVMValueRef src, L LLVMValueRef ac_build_mbcnt_add(struct ac_llvm_context *ctx, LLVMValueRef mask, LLVMValueRef add_src) { + LLVMValueRef val; + if (ctx->wave_size == 32) { - LLVMValueRef val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32, - (LLVMValueRef[]){mask, add_src}, 2, AC_FUNC_ATTR_READNONE); - ac_set_range_metadata(ctx, val, 0, ctx->wave_size); - return val; + val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32, + (LLVMValueRef[]){mask, ctx->i32_0}, 2, AC_FUNC_ATTR_READNONE); + } else { + LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask, ctx->v2i32, ""); + LLVMValueRef mask_lo = LLVMBuildExtractElement(ctx->builder, mask_vec, ctx->i32_0, ""); + LLVMValueRef mask_hi = LLVMBuildExtractElement(ctx->builder, mask_vec, ctx->i32_1, ""); + val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32, + (LLVMValueRef[]){mask_lo, ctx->i32_0}, 2, AC_FUNC_ATTR_READNONE); + val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.hi", ctx->i32, (LLVMValueRef[]){mask_hi, val}, + 2, AC_FUNC_ATTR_READNONE); } - LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask, ctx->v2i32, ""); - LLVMValueRef mask_lo = LLVMBuildExtractElement(ctx->builder, mask_vec, ctx->i32_0, ""); - LLVMValueRef mask_hi = LLVMBuildExtractElement(ctx->builder, mask_vec, ctx->i32_1, ""); - LLVMValueRef val = - ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32, - (LLVMValueRef[]){mask_lo, add_src}, 2, AC_FUNC_ATTR_READNONE); - val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.hi", ctx->i32, (LLVMValueRef[]){mask_hi, val}, - 2, AC_FUNC_ATTR_READNONE); - ac_set_range_metadata(ctx, val, 0, ctx->wave_size); + + /* Bug workaround. LLVM always believes the upper bound of mbcnt to be the wave size, + * regardless of ac_set_range_metadata. Use an extra add instruction to work around it. + */ + if (add_src != NULL && add_src != ctx->i32_0) { + return LLVMBuildAdd(ctx->builder, val, add_src, ""); + } + return val; } -- 2.7.4