diff options
-rw-r--r-- | src/amd/common/ac_llvm_build.c | 28 | ||||
-rw-r--r-- | src/amd/common/ac_llvm_build.h | 2 | ||||
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 7 |
3 files changed, 31 insertions, 6 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c index 1f5112e9929..4fbe0ddb9c5 100644 --- a/src/amd/common/ac_llvm_build.c +++ b/src/amd/common/ac_llvm_build.c @@ -2107,6 +2107,34 @@ LLVMValueRef ac_build_fsign(struct ac_llvm_context *ctx, LLVMValueRef src0, return val; } +LLVMValueRef ac_build_bit_count(struct ac_llvm_context *ctx, LLVMValueRef src0) +{ + LLVMValueRef result; + unsigned bitsize; + + bitsize = ac_get_elem_bits(ctx, LLVMTypeOf(src0)); + + switch (bitsize) { + case 64: + result = ac_build_intrinsic(ctx, "llvm.ctpop.i64", ctx->i64, + (LLVMValueRef []) { src0 }, 1, + AC_FUNC_ATTR_READNONE); + + result = LLVMBuildTrunc(ctx->builder, result, ctx->i32, ""); + break; + case 32: + result = ac_build_intrinsic(ctx, "llvm.ctpop.i32", ctx->i32, + (LLVMValueRef []) { src0 }, 1, + AC_FUNC_ATTR_READNONE); + break; + default: + unreachable(!"invalid bitsize"); + break; + } + + return result; +} + #define AC_EXP_TARGET 0 #define AC_EXP_ENABLED_CHANNELS 1 #define AC_EXP_OUT0 2 diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h index 0d261bae097..98a61a24054 100644 --- a/src/amd/common/ac_llvm_build.h +++ b/src/amd/common/ac_llvm_build.h @@ -424,6 +424,8 @@ LLVMValueRef ac_build_isign(struct ac_llvm_context *ctx, LLVMValueRef src0, LLVMValueRef ac_build_fsign(struct ac_llvm_context *ctx, LLVMValueRef src0, unsigned bitsize); +LLVMValueRef ac_build_bit_count(struct ac_llvm_context *ctx, LLVMValueRef src0); + void ac_optimize_vs_outputs(struct ac_llvm_context *ac, LLVMValueRef main_fn, uint8_t *vs_output_param_offset, diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index a3f26ab46c9..d79ff4399b1 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -839,12 +839,7 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr) result = ac_build_intrinsic(&ctx->ac, "llvm.bitreverse.i32", ctx->ac.i32, src, 1, AC_FUNC_ATTR_READNONE); break; case nir_op_bit_count: - if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) == 32) - result = ac_build_intrinsic(&ctx->ac, "llvm.ctpop.i32", ctx->ac.i32, src, 1, AC_FUNC_ATTR_READNONE); - else { - result = ac_build_intrinsic(&ctx->ac, "llvm.ctpop.i64", ctx->ac.i64, src, 1, AC_FUNC_ATTR_READNONE); - result = LLVMBuildTrunc(ctx->ac.builder, result, ctx->ac.i32, ""); - } + result = ac_build_bit_count(&ctx->ac, src[0]); break; case nir_op_vec2: case nir_op_vec3: |