From 9c48ae751ab28f35eb878551d24c071be0ce11b0 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Thu, 8 Aug 2013 16:41:48 -0700 Subject: i965: Don't copy propagate bitcasts with source modifiers. Previously, copy propagation would cause bitcast_f2u(abs(float)) to be performed in a single step, but the application of source modifiers (abs, neg) happens after type conversion, leading to incorrect results. That is, for bitcast_f2u(abs(float)) we would in fact generate code to do abs(bitcast_f2u(float)). For example, whereas bitcast_f2u(abs(float)) might result in a register argument such as (abs)g2.2<0,1,0>UD v2: Set interfered = true and break in register_coalesce instead of returning false. Reviewed-by: Paul Berry --- src/mesa/drivers/dri/i965/brw_fs.cpp | 14 ++++++++++++++ src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp | 3 +++ src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp | 10 ++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 69e544aa4e1..d111cbd28cd 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2118,6 +2118,20 @@ fs_visitor::register_coalesce() } } + if (has_source_modifiers) { + for (int i = 0; i < 3; i++) { + if (scan_inst->src[i].file == GRF && + scan_inst->src[i].reg == inst->dst.reg && + scan_inst->src[i].reg_offset == inst->dst.reg_offset && + inst->dst.type != scan_inst->src[i].type) + { + interfered = true; + break; + } + } + } + + /* The gen6 MATH instruction can't handle source modifiers or * unusual register regions, so avoid coalescing those for * now. We should do something more specific. diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp index 234f8bd3870..61b2617a9e0 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp @@ -221,6 +221,9 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry) entry->src.smear != -1) && !can_do_source_mods(inst)) return false; + if (has_source_modifiers && entry->dst.type != inst->src[arg].type) + return false; + inst->src[arg].file = entry->src.file; inst->src[arg].reg = entry->src.reg; inst->src[arg].reg_offset = entry->src.reg_offset; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp index c28d0dee2d8..fdbe96c2e01 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp @@ -206,14 +206,16 @@ vec4_visitor::try_copy_propagation(vec4_instruction *inst, int arg, if (inst->src[arg].negate) value.negate = !value.negate; - bool has_source_modifiers = (value.negate || value.abs || - value.swizzle != BRW_SWIZZLE_XYZW || - value.file == UNIFORM); + bool has_source_modifiers = value.negate || value.abs; /* gen6 math and gen7+ SENDs from GRFs ignore source modifiers on * instructions. */ - if (has_source_modifiers && !can_do_source_mods(inst)) + if ((has_source_modifiers || value.file == UNIFORM || + value.swizzle != BRW_SWIZZLE_XYZW) && !can_do_source_mods(inst)) + return false; + + if (has_source_modifiers && value.type != inst->src[arg].type) return false; bool is_3src_inst = (inst->opcode == BRW_OPCODE_LRP || -- cgit v1.2.3