<div dir="ltr">Bah!  This one's bogus too.  I think it messes up register coalesce but I'm not 100% sure...<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 4, 2017 at 8:22 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Cc: <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.<wbr>org</a><br>
---<br>
 src/intel/compiler/brw_fs_<wbr>live_variables.cpp | 55 ++++++++++++++++++++++++++++<br>
 1 file changed, 55 insertions(+)<br>
<br>
diff --git a/src/intel/compiler/brw_fs_<wbr>live_variables.cpp b/src/intel/compiler/brw_fs_<wbr>live_variables.cpp<br>
index c449672..23ec280 100644<br>
--- a/src/intel/compiler/brw_fs_<wbr>live_variables.cpp<br>
+++ b/src/intel/compiler/brw_fs_<wbr>live_variables.cpp<br>
@@ -223,6 +223,61 @@ fs_live_variables::compute_<wbr>start_end()<br>
          }<br>
       }<br>
    }<br>
+<br>
+   /* Due to the explicit way the SIMD data is handled on GEN, we need to be a<br>
+    * bit more careful with live ranges and loops.  Consider the following<br>
+    * example:<br>
+    *<br>
+    *    vec4 color2;<br>
+    *    while (1) {<br>
+    *       vec4 color = texture();<br>
+    *       if (...) {<br>
+    *          color2 = color * 2;<br>
+    *          break;<br>
+    *       }<br>
+    *    }<br>
+    *    gl_FragColor = color2;<br>
+    *<br>
+    * In this case, the definition of color2 dominates the use because the<br>
+    * loop only has the one exit.  This means that the live range interval for<br>
+    * color2 goes from the statement in the if to it's use below the loop.<br>
+    * Now suppose that the texture operation has a header register that gets<br>
+    * assigned one of the registers used for color2.  If the loop condition is<br>
+    * non-uniform and some of the threads will take the and others will<br>
+    * continue.  In this case, the next pass through the loop, the WE_all<br>
+    * setup of the header register will stomp the disabled channels of color2<br>
+    * and corrupt the value.<br>
+    *<br>
+    * This same problem can occur if you have a mix of 64, 32, and 16-bit<br>
+    * registers because the channels do not line up or if you have a SIMD16<br>
+    * program and the first half of one value overlaps the second half of the<br>
+    * other.<br>
+    *<br>
+    * To solve this problem, we take any VGRFs whose live ranges cross the<br>
+    * while instruction of a loop and extend their live ranges to the top of<br>
+    * the loop.  This more accurately models the hardware because the value in<br>
+    * the VGRF needs to be carried through subsequent loop iterations in order<br>
+    * to remain valid when we finally do break.<br>
+    */<br>
+   foreach_block (block, cfg) {<br>
+      if (block->end()->opcode != BRW_OPCODE_WHILE)<br>
+         continue;<br>
+<br>
+      /* This is a WHILE instrution. Find the DO block. */<br>
+      bblock_t *do_block = NULL;<br>
+      foreach_list_typed(bblock_<wbr>link, child_link, link, &block->children) {<br>
+         if (child_link->block->start_ip < block->end_ip) {<br>
+            assert(do_block == NULL);<br>
+            do_block = child_link->block;<br>
+         }<br>
+      }<br>
+      assert(do_block);<br>
+<br>
+      for (int i = 0; i < num_vars; i++) {<br>
+         if (start[i] < block->end_ip && end[i] > block->end_ip)<br>
+            start[i] = do_block->start_ip;<br>
+      }<br>
+   }<br>
 }<br>
<br>
 fs_live_variables::fs_live_<wbr>variables(fs_visitor *v, const cfg_t *cfg)<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div>