nir: Add a variant of nir_lower_int64 for float conversions only

We'd like to postpone most int64 lowering until pretty late in the
process, because e.g. turning iadd@64 into (unpack + add-low + add-high
+ compare + b2i32 + repack) sequences makes it difficult for many
optimization passes to detect basic arithmetic patterns.  In particular,
nir_opt_load_store_vectorizer becomes unable to handle basic offset math
on 64-bit addresses.

We'd like to do double precision lowering earlier in the process,
however.  One snag is that nir_lower_int64's lower_2f and lower_f2 can
produce operations that may need lowering by nir_lower_doubles(), so
it's crucial to run those sets of lowering together.

To handle this, we make a new entrypoint that does nir_lower_int64
but skips everything except float conversions.  Note that the newly
produced instructions will still be lowered according to the full set
of int64 lowering options; this shouldn't be a huge deal.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23064>
This commit is contained in:
Kenneth Graunke 2023-05-12 02:20:39 -07:00 committed by Marge Bot
parent 0960ac2a24
commit d764c03d5d
2 changed files with 38 additions and 0 deletions

View file

@ -5679,6 +5679,7 @@ bool nir_split_64bit_vec3_and_vec4(nir_shader *shader);
nir_lower_int64_options nir_lower_int64_op_to_options_mask(nir_op opcode);
bool nir_lower_int64(nir_shader *shader);
bool nir_lower_int64_float_conversions(nir_shader *shader);
nir_lower_doubles_options nir_lower_doubles_op_to_options_mask(nir_op opcode);
bool nir_lower_doubles(nir_shader *shader, const nir_shader *softfp64,

View file

@ -1368,3 +1368,40 @@ nir_lower_int64(nir_shader *shader)
lower_int64_instr,
(void *)shader->options);
}
static bool
should_lower_int64_float_conv(const nir_instr *instr, const void *_options)
{
if (instr->type != nir_instr_type_alu)
return false;
nir_alu_instr *alu = nir_instr_as_alu(instr);
switch (alu->op) {
case nir_op_i2f64:
case nir_op_i2f32:
case nir_op_i2f16:
case nir_op_u2f64:
case nir_op_u2f32:
case nir_op_u2f16:
case nir_op_f2i64:
case nir_op_f2u64:
return should_lower_int64_alu_instr(alu, _options);
default:
return false;
}
}
/**
* Like nir_lower_int64(), but only lowers conversions to/from float.
*
* These operations in particular may affect double-precision lowering,
* so it can be useful to run them in tandem with nir_lower_doubles().
*/
bool
nir_lower_int64_float_conversions(nir_shader *shader)
{
return nir_shader_lower_instructions(shader, should_lower_int64_float_conv,
lower_int64_instr,
(void *)shader->options);
}