From 024c5de569e8c57a37e007e9506454857144cae3 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 (cherry picked from commit bdbfe8de4d82eee77f10ba9fb0e8da351785b3cf) Part-of: --- .pick_status.json | 2 +- .../compiler/elk/elk_fs_cmod_propagation.cpp | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index bd84cd4ef09..8ec7f718adc 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2224,7 +2224,7 @@ "description": "elk/cmod: Don't propagate from CMP to possible Inf + (-Inf)", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "020b0055e7a085a6a8c961ad12ce94e58606a1ae", "notes": null diff --git a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp index 57a25141ebf..dc5faa23960 100644 --- a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp +++ b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp @@ -24,6 +24,7 @@ #include "elk_fs.h" #include "elk_cfg.h" #include "elk_eu.h" +#include "util/half_float.h" /** @file elk_fs_cmod_propagation.cpp * @@ -50,6 +51,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) @@ -57,6 +78,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() &&