diff options
author | Jason Ekstrand <[email protected]> | 2019-03-06 12:27:26 -0600 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-03-07 21:20:30 +0000 |
commit | cd4c1458baba595aaff25ca1099c60a57d31772b (patch) | |
tree | 48a983ba94a95c432c7f6840c7c57517b43bfdcd /src/compiler | |
parent | ebbb6b8eaa06c0eac93fee689223c6a98d3f98bc (diff) |
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 <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir_builder.h | 25 | ||||
-rw-r--r-- | 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); } } |