r600/sb: insert the else clause when we might depart from a loop
authorDave Airlie <airlied@redhat.com>
Tue, 30 Jan 2018 06:38:51 +0000 (16:38 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 30 Jan 2018 18:47:29 +0000 (04:47 +1000)
If there is a break inside the else clause and this means we
are breaking from a loop, the loop finalise will want to insert
the LOOP_BREAK/CONTINUE instruction, however if we don't emit
the else there is no where for these to end up, so they will end
up in the wrong place.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101442
Tested-By: Gert Wollny <gw.fossdev@gmail.com>
Cc: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/sb/sb_bc_finalize.cpp

index 099b295f18f34621d5562c6de0e1fe06900e5481..d3fab8002044ac66dff798420c578462c29dc349 100644 (file)
@@ -208,8 +208,25 @@ void bc_finalizer::finalize_if(region_node* r) {
                r->push_front(if_jump);
                r->push_back(if_pop);
 
+               /* the depart/repeat 1 is actually part of the "else" code.
+                * if it's a depart for an outer loop region it will want to
+                * insert a LOOP_BREAK or LOOP_CONTINUE in here, so we need
+                * to emit the else clause.
+                */
                bool has_else = n_if->next;
 
+               if (repdep1->is_depart()) {
+                       depart_node *dep1 = static_cast<depart_node*>(repdep1);
+                       if (dep1->target != r && dep1->target->is_loop())
+                               has_else = true;
+               }
+
+               if (repdep1->is_repeat()) {
+                       repeat_node *rep1 = static_cast<repeat_node*>(repdep1);
+                       if (rep1->target != r && rep1->target->is_loop())
+                               has_else = true;
+               }
+
                if (has_else) {
                        cf_node *nelse = sh.create_cf(CF_OP_ELSE);
                        n_if->insert_after(nelse);