elk/cmod: Don't propagate from CMP to possible Inf + (-Inf)

This is a backport of BRW e26270249b.

shader-db:

All Intel platforms had similar results. (Broadwell shown)
total instructions in shared programs: 18623918 -> 18624594 (<.01%)
instructions in affected programs: 125179 -> 125855 (0.54%)
helped: 0 / HURT: 139

total cycles in shared programs: 957073100 -> 957072484 (<.01%)
cycles in affected programs: 16534168 -> 16533552 (<.01%)
helped: 42 / HURT: 68

Fixes: 020b0055e7 ("i965/fs: Propagate conditional modifiers from compares to adds")
Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39967>
This commit is contained in:
Ian Romanick 2026-02-17 12:00:11 -08:00 committed by Marge Bot
parent d1614cd6db
commit bdbfe8de4d

View file

@ -6,6 +6,7 @@
#include "elk_fs.h"
#include "elk_cfg.h"
#include "elk_eu.h"
#include "util/half_float.h"
/** @file elk_fs_cmod_propagation.cpp
*
@ -32,6 +33,26 @@
using namespace elk;
static double
src_as_float(const elk_fs_reg &src)
{
assert(src.file == IMM);
switch (src.type) {
case ELK_REGISTER_TYPE_HF:
return _mesa_half_to_float((uint16_t)src.d);
case ELK_REGISTER_TYPE_F:
return src.f;
case ELK_REGISTER_TYPE_DF:
return src.df;
default:
UNREACHABLE("Invalid float type.");
}
}
static bool
cmod_propagate_cmp_to_add(const intel_device_info *devinfo, elk_bblock_t *block,
elk_fs_inst *inst)
@ -39,6 +60,36 @@ cmod_propagate_cmp_to_add(const intel_device_info *devinfo, elk_bblock_t *block,
bool read_flag = false;
const unsigned flags_written = inst->flags_written(devinfo);
/* The floating point comparison can only be removed if we can prove that
* either the addition is not ±Inf - (±Inf) or that ±Inf - (±Inf) compared
* with zero has the same result as ±Inf compared with ±Inf.
*
* The former can only be proven at this point in compilation if src[1] is
* an immediate value. Otherwise we can't know that nether value is
* ±Inf. For the latter, consider this table:
*
* A B A+(-B) A<B A-B<0 A<=B A-B<=0 A>B A-B>0 A>=B A-B>=0 A==B A-B==0 A!=B A-B!=0
* Inf Inf NaN F F T F F F T F T F F T
* Inf -Inf Inf F F F F T T T T F F T T
* -Inf Inf -Inf T T T T F F F F F F T T
* -Inf -Inf NaN F F T F F F T F T F F T
*
* The column for A<B and A-B<0 is identical, and the column for A>B and
* A-B>0 are identical.
*
* If src[1] is NaN, the transformation is always valid.
*/
if (elk_reg_type_is_floating_point(inst->src[0].type)) {
if (inst->conditional_mod != ELK_CONDITIONAL_L &&
inst->conditional_mod != ELK_CONDITIONAL_G) {
if (inst->src[1].file != IMM)
return false;
if (isinf(src_as_float(inst->src[1])) != 0)
return false;
}
}
foreach_inst_in_block_reverse_starting_from(elk_fs_inst, scan_inst, inst) {
if (scan_inst->opcode == ELK_OPCODE_ADD &&
!scan_inst->is_partial_write() &&