X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_fs_cmod_propagation.cpp;h=af1e3ebbaa2a698b784da790dca98acc0fd7e56e;hb=93d2b5c57632f5cc57e71511bc6e33f8474e40fd;hp=883e8d2a49f78aa4ddb3e9c4299721df3b9858e7;hpb=fed60e3c73c7be7c1e2194054daf29381d0ddc18;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp index 883e8d2a49f..af1e3ebbaa2 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp @@ -22,8 +22,8 @@ */ #include "brw_fs.h" -#include "brw_fs_live_variables.h" #include "brw_cfg.h" +#include "brw_eu.h" /** @file brw_fs_cmod_propagation.cpp * @@ -49,7 +49,7 @@ */ static bool -opt_cmod_propagation_local(bblock_t *block) +opt_cmod_propagation_local(const brw_device_info *devinfo, bblock_t *block) { bool progress = false; int ip = block->end_ip + 1; @@ -62,7 +62,7 @@ opt_cmod_propagation_local(bblock_t *block) inst->opcode != BRW_OPCODE_MOV) || inst->predicate != BRW_PREDICATE_NONE || !inst->dst.is_null() || - inst->src[0].file != GRF || + inst->src[0].file != VGRF || inst->src[0].abs) continue; @@ -90,7 +90,8 @@ opt_cmod_propagation_local(bblock_t *block) foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst) { if (scan_inst->overwrites_reg(inst->src[0])) { if (scan_inst->is_partial_write() || - scan_inst->dst.reg_offset != inst->src[0].reg_offset) + scan_inst->dst.reg_offset != inst->src[0].reg_offset || + scan_inst->exec_size != inst->exec_size) break; /* CMP's result is the same regardless of dest type. */ @@ -122,12 +123,24 @@ opt_cmod_propagation_local(bblock_t *block) */ if (inst->conditional_mod == BRW_CONDITIONAL_NZ && !inst->src[0].negate && - scan_inst->writes_flag()) { + scan_inst->flags_written()) { inst->remove(block); progress = true; break; } + /* The conditional mod of the CMP/CMPN instructions behaves + * specially because the flag output is not calculated from the + * result of the instruction, but the other way around, which + * means that even if the condmod to propagate and the condmod + * from the CMP instruction are the same they will in general give + * different results because they are evaluated based on different + * inputs. + */ + if (scan_inst->opcode == BRW_OPCODE_CMP || + scan_inst->opcode == BRW_OPCODE_CMPN) + break; + /* Otherwise, try propagating the conditional. */ enum brw_conditional_mod cond = inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod) @@ -143,10 +156,10 @@ opt_cmod_propagation_local(bblock_t *block) break; } - if (scan_inst->writes_flag()) + if (scan_inst->flags_written()) break; - read_flag = read_flag || scan_inst->reads_flag(); + read_flag = read_flag || scan_inst->flags_read(devinfo); } } @@ -159,7 +172,7 @@ fs_visitor::opt_cmod_propagation() bool progress = false; foreach_block_reverse(block, cfg) { - progress = opt_cmod_propagation_local(block) || progress; + progress = opt_cmod_propagation_local(devinfo, block) || progress; } if (progress)