From: Marek Olšák Date: Thu, 3 Sep 2020 09:51:17 +0000 (-0400) Subject: ac/llvm: add better code for isign X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=70375a9afb0800722509d4a09c94b8b959aeb3fc ac/llvm: add better code for isign There are 2 improvements: - select v_med3_i32 - support vectors Reviewed-by: Bas Nieuwenhuizen Part-of: --- diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c index de9091693c1..a3fa30fc003 100644 --- a/src/amd/llvm/ac_llvm_build.c +++ b/src/amd/llvm/ac_llvm_build.c @@ -2751,19 +2751,29 @@ LLVMValueRef ac_build_fract(struct ac_llvm_context *ctx, LLVMValueRef src0, AC_FUNC_ATTR_READNONE); } -LLVMValueRef ac_build_isign(struct ac_llvm_context *ctx, LLVMValueRef src0, - unsigned bitsize) +static LLVMValueRef ac_const_uint_vec(struct ac_llvm_context *ctx, LLVMTypeRef type, uint64_t value) { - LLVMTypeRef type = LLVMIntTypeInContext(ctx->context, bitsize); - LLVMValueRef zero = LLVMConstInt(type, 0, false); - LLVMValueRef one = LLVMConstInt(type, 1, false); - LLVMValueRef cmp, val; - cmp = LLVMBuildICmp(ctx->builder, LLVMIntSGT, src0, zero, ""); - val = LLVMBuildSelect(ctx->builder, cmp, one, src0, ""); - cmp = LLVMBuildICmp(ctx->builder, LLVMIntSGE, val, zero, ""); - val = LLVMBuildSelect(ctx->builder, cmp, val, LLVMConstInt(type, -1, true), ""); - return val; + if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) { + LLVMValueRef scalar = LLVMConstInt(LLVMGetElementType(type), value, 0); + unsigned vec_size = LLVMGetVectorSize(type); + LLVMValueRef *scalars = alloca(vec_size * sizeof(LLVMValueRef*)); + + for (unsigned i = 0; i < vec_size; i++) + scalars[i] = scalar; + return LLVMConstVector(scalars, vec_size); + } + return LLVMConstInt(type, value, 0); +} + +LLVMValueRef ac_build_isign(struct ac_llvm_context *ctx, LLVMValueRef src0) +{ + LLVMTypeRef type = LLVMTypeOf(src0); + LLVMValueRef val; + + /* v_med3 is selected only when max is first. (LLVM bug?) */ + val = ac_build_imax(ctx, src0, ac_const_uint_vec(ctx, type, -1)); + return ac_build_imin(ctx, val, ac_const_uint_vec(ctx, type, 1)); } LLVMValueRef ac_build_fsign(struct ac_llvm_context *ctx, LLVMValueRef src0, diff --git a/src/amd/llvm/ac_llvm_build.h b/src/amd/llvm/ac_llvm_build.h index 764b0565a66..7cb98d06a6e 100644 --- a/src/amd/llvm/ac_llvm_build.h +++ b/src/amd/llvm/ac_llvm_build.h @@ -597,10 +597,7 @@ void ac_build_waitcnt(struct ac_llvm_context *ctx, unsigned wait_flags); LLVMValueRef ac_build_fract(struct ac_llvm_context *ctx, LLVMValueRef src0, unsigned bitsize); - -LLVMValueRef ac_build_isign(struct ac_llvm_context *ctx, LLVMValueRef src0, - unsigned bitsize); - +LLVMValueRef ac_build_isign(struct ac_llvm_context *ctx, LLVMValueRef src0); LLVMValueRef ac_build_fsign(struct ac_llvm_context *ctx, LLVMValueRef src0, unsigned bitsize); diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index 9ad16fba8d3..ddea78180b1 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -822,8 +822,7 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr) result = ac_build_umin(&ctx->ac, src[0], src[1]); break; case nir_op_isign: - result = ac_build_isign(&ctx->ac, src[0], - instr->dest.dest.ssa.bit_size); + result = ac_build_isign(&ctx->ac, src[0]); break; case nir_op_fsign: src[0] = ac_to_float(&ctx->ac, src[0]);