mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 04:48:08 +02:00
nir: add lower_fminmax_signed_zero
This implements IEEE-754-2019 signed zero semantics for fmin/fmax, as now required by NIR, for hardware that has busted signed zero behaviour for fmin/fmax. Ian expressed interest in this for Intel. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30075>
This commit is contained in:
parent
0e46f7b39a
commit
d238d766c6
2 changed files with 32 additions and 1 deletions
|
|
@ -3807,6 +3807,12 @@ typedef struct nir_shader_compiler_options {
|
|||
/** enable rules that avoid generating umin from signed integer ops */
|
||||
bool lower_umin;
|
||||
|
||||
/* lower fmin/fmax with signed zero preserve to fmin/fmax with
|
||||
* no_signed_zero, for backends whose fmin/fmax implementations do not
|
||||
* implement IEEE-754-2019 semantics for signed zero.
|
||||
*/
|
||||
bool lower_fminmax_signed_zero;
|
||||
|
||||
/* lower fdph to fdot4 */
|
||||
bool lower_fdph;
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,30 @@ lower_alu_instr(nir_builder *b, nir_instr *instr_, UNUSED void *cb_data)
|
|||
}
|
||||
break;
|
||||
|
||||
case nir_op_fmin:
|
||||
case nir_op_fmax: {
|
||||
if (!b->shader->options->lower_fminmax_signed_zero ||
|
||||
!nir_alu_instr_is_signed_zero_preserve(instr))
|
||||
break;
|
||||
|
||||
nir_def *s0 = nir_ssa_for_alu_src(b, instr, 0);
|
||||
nir_def *s1 = nir_ssa_for_alu_src(b, instr, 1);
|
||||
|
||||
bool max = instr->op == nir_op_fmax;
|
||||
nir_def *iminmax = max ? nir_imax(b, s0, s1) : nir_imin(b, s0, s1);
|
||||
|
||||
/* Lower the fmin/fmax to a no_signed_zero fmin/fmax. This ensures that
|
||||
* nir_lower_alu is idempotent, and allows the backend to implement
|
||||
* soundly the no_signed_zero subset of fmin/fmax.
|
||||
*/
|
||||
b->fp_fast_math &= ~FLOAT_CONTROLS_SIGNED_ZERO_PRESERVE;
|
||||
nir_def *fminmax = max ? nir_fmax(b, s0, s1) : nir_fmin(b, s0, s1);
|
||||
b->fp_fast_math = instr->fp_fast_math;
|
||||
|
||||
lowered = nir_bcsel(b, nir_feq(b, s0, s1), iminmax, fminmax);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -229,7 +253,8 @@ nir_lower_alu(nir_shader *shader)
|
|||
{
|
||||
if (!shader->options->lower_bitfield_reverse &&
|
||||
!shader->options->lower_bit_count &&
|
||||
!shader->options->lower_mul_high)
|
||||
!shader->options->lower_mul_high &&
|
||||
!shader->options->lower_fminmax_signed_zero)
|
||||
return false;
|
||||
|
||||
return nir_shader_instructions_pass(shader, lower_alu_instr,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue