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@gmail.com> Reviewed-by: Qiang Yu <yuq825@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17706>
This commit is contained in:
@@ -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 ac_build_mbcnt_add(struct ac_llvm_context *ctx, LLVMValueRef mask, LLVMValueRef add_src)
|
||||||
{
|
{
|
||||||
|
LLVMValueRef val;
|
||||||
|
|
||||||
if (ctx->wave_size == 32) {
|
if (ctx->wave_size == 32) {
|
||||||
LLVMValueRef val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32,
|
val = ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32,
|
||||||
(LLVMValueRef[]){mask, add_src}, 2, AC_FUNC_ATTR_READNONE);
|
(LLVMValueRef[]){mask, ctx->i32_0}, 2, AC_FUNC_ATTR_READNONE);
|
||||||
ac_set_range_metadata(ctx, val, 0, ctx->wave_size);
|
} else {
|
||||||
return val;
|
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, "");
|
/* Bug workaround. LLVM always believes the upper bound of mbcnt to be the wave size,
|
||||||
LLVMValueRef mask_hi = LLVMBuildExtractElement(ctx->builder, mask_vec, ctx->i32_1, "");
|
* regardless of ac_set_range_metadata. Use an extra add instruction to work around it.
|
||||||
LLVMValueRef val =
|
*/
|
||||||
ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32,
|
if (add_src != NULL && add_src != ctx->i32_0) {
|
||||||
(LLVMValueRef[]){mask_lo, add_src}, 2, AC_FUNC_ATTR_READNONE);
|
return LLVMBuildAdd(ctx->builder, val, add_src, "");
|
||||||
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);
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user