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); +}