Mesa (main): ac/llvm: Add LLVM bug workaround to ac_build_mbcnt_add.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 22 08:44:32 UTC 2022


Module: Mesa
Branch: main
Commit: 1e2663b62c241d6389e3f97cb8e104ccdd8d567e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1e2663b62c241d6389e3f97cb8e104ccdd8d567e

Author: Timur Kristóf <timur.kristof at gmail.com>
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 <timur.kristof at gmail.com>
Reviewed-by: Qiang Yu <yuq825 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17706>

---

 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 9bb6e6a183b..ab2326cca1d 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;
 }
 



More information about the mesa-commit mailing list