summaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorDaniel Schürmann <[email protected]>2018-03-08 22:45:04 +0100
committerBas Nieuwenhuizen <[email protected]>2018-03-29 01:29:35 +0200
commitd00fb7ce54ddedb611ab6085346cd25b0ee8a58e (patch)
tree91b84b35a3b1cd721149a060a59f40aa0ca57454 /src/amd
parentfe5d5d19b01bd5d1407943181d613d18a44aa42b (diff)
ac: add support for trinary_minmax instructions
v2: Add missing break (Bas) Reviewed-by: Bas Nieuwenhuizen <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 2da73a7bfb1..7efbe4b31aa 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -963,6 +963,60 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
break;
}
+ case nir_op_fmin3:
+ result = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
+ ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
+ result = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
+ ac_to_float_type(&ctx->ac, def_type), result, src[2]);
+ break;
+ case nir_op_umin3:
+ result = emit_minmax_int(&ctx->ac, LLVMIntULT, src[0], src[1]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntULT, result, src[2]);
+ break;
+ case nir_op_imin3:
+ result = emit_minmax_int(&ctx->ac, LLVMIntSLT, src[0], src[1]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntSLT, result, src[2]);
+ break;
+ case nir_op_fmax3:
+ result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
+ ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
+ result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
+ ac_to_float_type(&ctx->ac, def_type), result, src[2]);
+ break;
+ case nir_op_umax3:
+ result = emit_minmax_int(&ctx->ac, LLVMIntUGT, src[0], src[1]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntUGT, result, src[2]);
+ break;
+ case nir_op_imax3:
+ result = emit_minmax_int(&ctx->ac, LLVMIntSGT, src[0], src[1]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntSGT, result, src[2]);
+ break;
+ case nir_op_fmed3: {
+ LLVMValueRef tmp1 = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
+ ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
+ LLVMValueRef tmp2 = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
+ ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
+ tmp2 = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
+ ac_to_float_type(&ctx->ac, def_type), tmp2, src[2]);
+ result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
+ ac_to_float_type(&ctx->ac, def_type), tmp1, tmp2);
+ break;
+ }
+ case nir_op_imed3: {
+ LLVMValueRef tmp1 = emit_minmax_int(&ctx->ac, LLVMIntSLT, src[0], src[1]);
+ LLVMValueRef tmp2 = emit_minmax_int(&ctx->ac, LLVMIntSGT, src[0], src[1]);
+ tmp2 = emit_minmax_int(&ctx->ac, LLVMIntSLT, tmp2, src[2]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntSGT, tmp1, tmp2);
+ break;
+ }
+ case nir_op_umed3: {
+ LLVMValueRef tmp1 = emit_minmax_int(&ctx->ac, LLVMIntULT, src[0], src[1]);
+ LLVMValueRef tmp2 = emit_minmax_int(&ctx->ac, LLVMIntUGT, src[0], src[1]);
+ tmp2 = emit_minmax_int(&ctx->ac, LLVMIntULT, tmp2, src[2]);
+ result = emit_minmax_int(&ctx->ac, LLVMIntUGT, tmp1, tmp2);
+ break;
+ }
+
default:
fprintf(stderr, "Unknown NIR alu instr: ");
nir_print_instr(&instr->instr, stderr);