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 <sviatoslav.peleshko@globallogic.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31042>
This commit is contained in:
Sviatoslav Peleshko 2024-09-05 13:41:19 +03:00 committed by Marge Bot
parent 93372ea9af
commit 57344052b6

View file

@ -4235,10 +4235,30 @@ 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.
*/
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);
}
}
}
if (cmp == NULL) {
cmp = bld.CMP(bld.null_reg_f(), get_nir_src(ntb, instr->src[0]),