summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorConnor Abbott <[email protected]>2017-07-31 18:28:45 -0700
committerEmil Velikov <[email protected]>2017-08-05 00:09:25 +0100
commit2dd6030fbb0d8f94f1dbba3c73aa87cf6f38781c (patch)
treed59a856da9081dbf7ba2e4c2f84713d2f2ebc6d7 /src
parenta90d99f7a5f091c2f5697dd7b11d9803f369aa3a (diff)
ac/nir: fix lsb emission
This makes it match radeonsi. The LLVM backend itself will emit the correct instruction, but LLVM might do incorrect optimizations since it thinks the output is undefined when the input is 0, even though it's not supposed to be. We really need a new intrinsic, or for the backend to become smarter and recognize this pattern. Cc: [email protected] Reviewed-by: Bas Nieuwenhuizen <[email protected]> (cherry picked from commit 6d731c5651ea98551e0bf0c1a8896d5ea63558d5)
Diffstat (limited to 'src')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index d6b450f8ee1..e12354980eb 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1178,7 +1178,17 @@ static LLVMValueRef emit_find_lsb(struct ac_llvm_context *ctx,
*/
LLVMConstInt(ctx->i1, 1, false),
};
- return ac_build_intrinsic(ctx, "llvm.cttz.i32", ctx->i32, params, 2, AC_FUNC_ATTR_READNONE);
+
+ LLVMValueRef lsb = ac_build_intrinsic(ctx, "llvm.cttz.i32", ctx->i32,
+ params, 2,
+ AC_FUNC_ATTR_READNONE);
+
+ /* TODO: We need an intrinsic to skip this conditional. */
+ /* Check for zero: */
+ return LLVMBuildSelect(ctx->builder, LLVMBuildICmp(ctx->builder,
+ LLVMIntEQ, src0,
+ ctx->i32_0, ""),
+ LLVMConstInt(ctx->i32, -1, 0), lsb, "");
}
static LLVMValueRef emit_ifind_msb(struct ac_llvm_context *ctx,