ac/nir: use llvm.amdgcn.rcp for nir_op_frcp
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 25 Mar 2020 17:17:06 +0000 (18:17 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 27 Mar 2020 06:45:43 +0000 (07:45 +0100)
Instead of emitting 1.0 / x which includes a slow division that
LLVM doesn't always optimize even if the metadata is correctly set.

pipeline-db (VEG10/LLVM 9):
Totals from affected shaders:
SGPRS: 50384 -> 50312 (-0.14 %)
VGPRS: 42572 -> 42696 (0.29 %)
Spilled SGPRs: 1372 -> 1372 (0.00 %)
Code Size: 5692040 -> 5691428 (-0.01 %) bytes
Max Waves: 3954 -> 3951 (-0.08 %)

pipeline-db (VEG10/LLVM 10):
Totals from affected shaders:
SGPRS: 78512 -> 78464 (-0.06 %)
VGPRS: 62408 -> 62484 (0.12 %)
Spilled SGPRs: 1502 -> 1502 (0.00 %)
Code Size: 8106188 -> 8103372 (-0.03 %) bytes
Max Waves: 7759 -> 7753 (-0.08 %)

pipeline-db (VEGA10/LLVM 11 - 92744f62478):
Totals from affected shaders:
SGPRS: 112760 -> 113232 (0.42 %)
VGPRS: 111132 -> 110568 (-0.51 %)
Spilled SGPRs: 5870 -> 5940 (1.19 %)
Spilled VGPRs: 650 -> 652 (0.31 %)
Code Size: 11887232 -> 11561744 (-2.74 %) bytes
Max Waves: 8964 -> 9015 (0.57 %)

LLVM 11 (master) is more affected than previous versions, but
based on the small impact with LLVM 9/10, I decided to emit it
unconditionally.

Cc: 20.0 <mesa-stable@lists.freedesktop.org>
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4326>

src/amd/llvm/ac_nir_to_llvm.c

index 871c6abc17fb4c5b8afe4de521c84ad532dbcb0b..1e7e95116935a3090f4c8ccf3670ec83e0b23d47 100644 (file)
@@ -688,8 +688,8 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
                result = LLVMBuildFMul(ctx->ac.builder, src[0], src[1], "");
                break;
        case nir_op_frcp:
-               src[0] = ac_to_float(&ctx->ac, src[0]);
-               result = ac_build_fdiv(&ctx->ac, LLVMConstReal(LLVMTypeOf(src[0]), 1.0), src[0]);
+               result = emit_intrin_1f_param(&ctx->ac, "llvm.amdgcn.rcp",
+                                             ac_to_float_type(&ctx->ac, def_type), src[0]);
                break;
        case nir_op_iand:
                result = LLVMBuildAnd(ctx->ac.builder, src[0], src[1], "");