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/nir/nir_builder.h | |
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/nir/nir_builder.h')
-rw-r--r-- | src/compiler/nir/nir_builder.h | 25 |
1 files changed, 23 insertions, 2 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 * |