From: Ian Romanick <ian.d.roman...@intel.com>

The kill mask and the initial assignment mask must be tracked with
each constant in the set.  Otherwise the wrong component can be
selected after earlier components have been killed.

NOTE: This is a candidate for the 7.10 and 7.11 branches.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=37383
Cc: Eric Anholt <e...@anholt.net>
Cc: Kenneth Graunke <kenn...@whitecape.org>
Cc: Matthias Bentrup <matthias.bent...@googlemail.com>
---
 src/glsl/opt_constant_propagation.cpp |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/src/glsl/opt_constant_propagation.cpp 
b/src/glsl/opt_constant_propagation.cpp
index 4425f42..414f0f2 100644
--- a/src/glsl/opt_constant_propagation.cpp
+++ b/src/glsl/opt_constant_propagation.cpp
@@ -51,11 +51,13 @@ public:
       this->var = var;
       this->write_mask = write_mask;
       this->constant = constant;
+      this->kill_mask = 0;
    }
 
    ir_variable *var;
    ir_constant *constant;
    unsigned write_mask;
+   unsigned kill_mask;
 };
 
 
@@ -169,10 +171,11 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue 
**rvalue)
         return;
 
       int rhs_channel = 0;
+      const unsigned mask = found->write_mask | found->kill_mask;
       for (int j = 0; j < 4; j++) {
         if (j == channel)
            break;
-        if (found->write_mask & (1 << j))
+        if (mask & (1 << j))
            rhs_channel++;
       }
 
@@ -369,6 +372,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, 
unsigned write_mask)
 
       if (entry->var == var) {
         entry->write_mask &= ~write_mask;
+        entry->kill_mask |= write_mask;
         if (entry->write_mask == 0)
            entry->remove();
       }
-- 
1.7.4.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to