mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 15:40:31 +01:00
elk/cmod: Don't propagate from CMP to possible Inf + (-Inf)
This is a backport of BRWe26270249b. 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:
parent
d1614cd6db
commit
bdbfe8de4d
1 changed files with 51 additions and 0 deletions
|
|
@ -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() &&
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue