diff options
author | Marek Olšák <[email protected]> | 2019-07-24 17:44:51 -0400 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2019-07-30 22:06:23 -0400 |
commit | d3c80733cdfe8552b2f447ec8ed62465d0f2af1a (patch) | |
tree | 9de90c2a74d5b733fb8e5de23567296c8b91a3e9 /src/amd/common | |
parent | efe2d8c5f925a643d8de79cb8e6a4c4e00e71dd3 (diff) |
ac/nir: handle abs modifier
Diffstat (limited to 'src/amd/common')
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index f3cb9e879ed..34d9b83e85b 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -153,6 +153,12 @@ static LLVMBasicBlockRef get_block(struct ac_nir_context *nir, return (LLVMBasicBlockRef)entry->data; } +static LLVMValueRef emit_iabs(struct ac_llvm_context *ctx, + LLVMValueRef src0) +{ + return ac_build_imax(ctx, src0, LLVMBuildNeg(ctx->builder, src0, "")); +} + static LLVMValueRef get_alu_src(struct ac_nir_context *ctx, nir_alu_src src, unsigned num_components) @@ -188,18 +194,37 @@ static LLVMValueRef get_alu_src(struct ac_nir_context *ctx, } } - if (src.negate) { - LLVMTypeRef type = LLVMTypeOf(value); - if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) - type = LLVMGetElementType(type); + LLVMTypeRef type = LLVMTypeOf(value); + if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) + type = LLVMGetElementType(type); + + if (src.abs) { + if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind) { + value = emit_iabs(&ctx->ac, value); + } else { + char name[128]; + unsigned fsize = type == ctx->ac.f16 ? 16 : + type == ctx->ac.f32 ? 32 : 64; + + if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMVectorTypeKind) { + snprintf(name, sizeof(name), "llvm.fabs.v%uf%u", + LLVMGetVectorSize(LLVMTypeOf(value)), fsize); + } else { + snprintf(name, sizeof(name), "llvm.fabs.f%u", fsize); + } + + value = ac_build_intrinsic(&ctx->ac, name, LLVMTypeOf(value), + &value, 1, AC_FUNC_ATTR_READNONE); + } + } + if (src.negate) { if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind) value = LLVMBuildNeg(ctx->ac.builder, value, ""); else value = LLVMBuildFNeg(ctx->ac.builder, value, ""); } - assert(!src.abs); return value; } @@ -289,12 +314,6 @@ static LLVMValueRef emit_bcsel(struct ac_llvm_context *ctx, ac_to_integer_or_pointer(ctx, src2), ""); } -static LLVMValueRef emit_iabs(struct ac_llvm_context *ctx, - LLVMValueRef src0) -{ - return ac_build_imax(ctx, src0, LLVMBuildNeg(ctx->builder, src0, "")); -} - static LLVMValueRef emit_uint_carry(struct ac_llvm_context *ctx, const char *intrin, LLVMValueRef src0, LLVMValueRef src1) |