From cd4c1458baba595aaff25ca1099c60a57d31772b Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 6 Mar 2019 12:27:26 -0600 Subject: [PATCH] nir/builder: Emit better code for iadd/imul_imm Because we already know the immediate right-hand parameter, we can potentially save the optimizer a bit of work. Reviewed-by: Karol Herbst Reviewed-by: Lionel Landwerlin Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/nir/nir_builder.h | 25 +++++++++++++++++++++++-- src/compiler/spirv/vtn_variables.c | 4 +--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h index 43edf0a9d36..42004a2fe54 100644 --- a/src/compiler/nir/nir_builder.h +++ b/src/compiler/nir/nir_builder.h @@ -25,6 +25,7 @@ #define NIR_BUILDER_H #include "nir_control_flow.h" +#include "util/bitscan.h" #include "util/half_float.h" struct exec_list; @@ -601,13 +602,33 @@ nir_u2u(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) static inline nir_ssa_def * nir_iadd_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) { - return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size)); + assert(x->bit_size <= 64); + if (x->bit_size < 64) + y &= (1ull << x->bit_size) - 1; + + if (y == 0) { + return x; + } else { + return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size)); + } } static inline nir_ssa_def * nir_imul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) { - return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size)); + assert(x->bit_size <= 64); + if (x->bit_size < 64) + y &= (1ull << x->bit_size) - 1; + + if (y == 0) { + return nir_imm_intN_t(build, 0, x->bit_size); + } else if (y == 1) { + return x; + } else if (util_is_power_of_two_or_zero64(y)) { + return nir_ishl(build, x, nir_imm_int(build, ffsll(y) - 1)); + } else { + return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size)); + } } static inline nir_ssa_def * diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index d8a4407639f..c3ce15aaaaf 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -79,9 +79,7 @@ vtn_access_link_as_ssa(struct vtn_builder *b, struct vtn_access_link link, nir_ssa_def *ssa = vtn_ssa_value(b, link.id)->def; if (ssa->bit_size != bit_size) ssa = nir_i2i(&b->nb, ssa, bit_size); - if (stride != 1) - ssa = nir_imul_imm(&b->nb, ssa, stride); - return ssa; + return nir_imul_imm(&b->nb, ssa, stride); } } -- 2.30.2