elk: Don't apply discard_if condition opt if it can change results

Replicates the change from 57344052b6 ("intel/brw: Don't apply
discard_if condition opt if it can change results")

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 0ba9497e66 ("intel/fs: Improve discard_if code generation")
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31604>
(cherry picked from commit 608d521086)
This commit is contained in:
Lionel Landwerlin 2024-10-12 12:42:49 +03:00 committed by Eric Engestrom
parent a0c910607f
commit 62d11bb250
3 changed files with 32 additions and 2 deletions

View file

@ -1484,7 +1484,7 @@
"description": "elk: Don't apply discard_if condition opt if it can change results",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "0ba9497e66a72e2f31e0e4d2b899d9bce686d698",
"notes": null

View file

@ -3796,8 +3796,28 @@ fs_nir_emit_fs_intrinsic(nir_to_elk_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 = elk_negate_cmod(cmp->conditional_mod);
if (elk_type_is_float(cmp->src[0].type) &&
cmp->conditional_mod != ELK_CONDITIONAL_EQ &&
cmp->conditional_mod != ELK_CONDITIONAL_NEQ) {
cmp = NULL;
} else {
cmp->conditional_mod = elk_negate_cmod(cmp->conditional_mod);
}
}
}

View file

@ -1347,6 +1347,16 @@ element_sz(struct elk_reg reg)
int elk_float_to_vf(float f);
float elk_vf_to_float(unsigned char vf);
static inline bool
elk_type_is_float(enum elk_reg_type type)
{
return type == ELK_REGISTER_TYPE_DF ||
type == ELK_REGISTER_TYPE_NF ||
type == ELK_REGISTER_TYPE_F ||
type == ELK_REGISTER_TYPE_VF ||
type == ELK_REGISTER_TYPE_HF;
}
#ifdef __cplusplus
}
#endif