From d764c03d5d9b50df0a7b90c420ad13fb91f9b551 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 12 May 2023 02:20:39 -0700 Subject: [PATCH] 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 Part-of: --- src/compiler/nir/nir.h | 1 + src/compiler/nir/nir_lower_int64.c | 37 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 208759d80de..95c82577a4a 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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, diff --git a/src/compiler/nir/nir_lower_int64.c b/src/compiler/nir/nir_lower_int64.c index f19f659803d..a0f81f9c9d1 100644 --- a/src/compiler/nir/nir_lower_int64.c +++ b/src/compiler/nir/nir_lower_int64.c @@ -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); +}