From bdbfe8de4d82eee77f10ba9fb0e8da351785b3cf Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 17 Feb 2026 12:00:11 -0800 Subject: [PATCH] elk/cmod: Don't propagate from CMP to possible Inf + (-Inf) This is a backport of BRW e26270249b1c. 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: 020b0055e7a ("i965/fs: Propagate conditional modifiers from compares to adds") Reviewed-by: Matt Turner Part-of: --- .../compiler/elk/elk_fs_cmod_propagation.cpp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp index b4db0ba0f83..3257fb7d55d 100644 --- a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp +++ b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp @@ -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) AB 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 AB 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() &&