r600/sb: fix rotated register in while loop
authorGert Wollny <gw.fossdev@gmail.com>
Thu, 31 May 2018 21:25:09 +0000 (23:25 +0200)
committerDave Airlie <airlied@redhat.com>
Mon, 25 Jun 2018 04:39:41 +0000 (05:39 +0100)
This patch is based on
https://lists.freedesktop.org/archives/mesa-dev/2018-February/185805.html

Dave Airlie:

 "A bunch of CTS tests led me to write
  tests/shaders/ssa/fs-while-loop-rotate-value.shader_test
  which r600/sb always fell over on.

  GCM seems to move some of the copies into other basic blocks,
  if we don't allow this to happen then it doesn't seem to schedule
  them badly.

  Everything I've read on SSA/phi copies say they have to happen
  in parallel, so keeping them in the same basic block seems like
  a good way to keep some of that property."

This patch differs from the one proposed by Dave in that it only adds
the NF_DONT_MOVE flag to copy_move instructions that are created by split_phi*
and that are located in loops.

Fixes piglit: tests/shaders/ssa/fs-while-loop-rotate-value.shader_test
(no regressions in the shader set). It also fixes all failing tests from

  dEQP-GLES3.functional.shaders.loops.*

Signed-off-by: Gert Wollny <gw.fossdev@gmail.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/sb/sb_ra_init.cpp

index 985e179452371991035cf9d22773d1212d62d90e..c557b86871d45d56ece2b6f97d9cd35fb0a2ee45 100644 (file)
@@ -545,10 +545,13 @@ void ra_split::split_phi_src(container_node *loc, container_node *c,
                        continue;
 
                value *t = sh.create_temp_value();
+               alu_node* n = sh.create_copy_mov(t, v);
+               if (loop)
+                       n->flags |= NF_DONT_MOVE;
                if (loop && id == 0)
-                       loc->insert_before(sh.create_copy_mov(t, v));
+                       loc->insert_before(n);
                else
-                       loc->push_back(sh.create_copy_mov(t, v));
+                       loc->push_back(n);
                v = t;
 
                sh.coal.add_edge(v, d, coalescer::phi_cost);
@@ -566,9 +569,10 @@ void ra_split::split_phi_dst(node* loc, container_node *c, bool loop) {
 
                value *t = sh.create_temp_value();
                node *cp = sh.create_copy_mov(v, t);
-               if (loop)
+               if (loop) {
+                       cp->flags |= NF_DONT_MOVE;
                        static_cast<container_node*>(loc)->push_front(cp);
-               else
+               else
                        loc->insert_after(cp);
                v = t;
        }