Module: Mesa Branch: staging/22.1 Commit: b4ce0d7113fa3af4f24caa40b31e1a861f59923a URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b4ce0d7113fa3af4f24caa40b31e1a861f59923a
Author: Timur Kristóf <[email protected]> Date: Thu May 19 23:13:28 2022 +0200 ac/llvm: Add LLVM bug workaround to ac_build_mbcnt_add. 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 <[email protected]> Reviewed-by: Qiang Yu <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17706> (cherry picked from commit 1e2663b62c241d6389e3f97cb8e104ccdd8d567e) --- .pick_status.json | 2 +- src/amd/llvm/ac_llvm_build.c | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 28415343620..a7e4f84e1d2 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2389,7 +2389,7 @@ "description": "ac/llvm: Add LLVM bug workaround to ac_build_mbcnt_add.", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index e10a546d98b..e4ed7a72357 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -3457,21 +3457,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; }
