From 57344052b6abe57b528cabc789556db9098b5629 Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Thu, 5 Sep 2024 13:41:19 +0300 Subject: [PATCH] intel/brw: Don't apply discard_if condition opt if it can change results We can't just always negate the alu instruction's cmod, because negating it can produce different results when the argument is NaN float. We can still do that if the condition is == or !=. Fixes: 0ba9497e ("intel/fs: Improve discard_if code generation") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11800 Signed-off-by: Sviatoslav Peleshko Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/compiler/brw_fs_nir.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index 9bbf208572d..2ab59810ae3 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -4235,8 +4235,28 @@ fs_nir_emit_fs_intrinsic(nir_to_brw_state &ntb, /* The old sequence that would have been generated is, * basically, bool_result == false. This is equivalent to * !bool_result, so negate the old modifier. + * + * Unfortunately, we can't do this to most float comparisons + * because of NaN, so we'll have to fallback to the old-style + * compare. + * + * For example, this code (after negation): + * (+f1.0) cmp.ge.f1.0(8) null<1>F g30<8,8,1>F 0x0F + * will provide different results from this: + * cmp.l.f0.0(8) g31<1>F g30<1,1,0>F 0x0F + * (+f1.0) cmp.z.f1.0(8) null<1>D g31<8,8,1>D 0D + * because both (NaN >= 0) == false and (NaN < 0) == false. + * + * It will still work for == and != though, because + * (NaN == x) == false and (NaN != x) == true. */ - cmp->conditional_mod = brw_negate_cmod(cmp->conditional_mod); + if (brw_type_is_float(cmp->src[0].type) && + cmp->conditional_mod != BRW_CONDITIONAL_EQ && + cmp->conditional_mod != BRW_CONDITIONAL_NEQ) { + cmp = NULL; + } else { + cmp->conditional_mod = brw_negate_cmod(cmp->conditional_mod); + } } }