<html dir="ltr"><head></head><body style="text-align:left; direction:ltr;"><div>On Fri, 2019-02-08 at 15:39 -0600, Jason Ekstrand wrote:</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div dir="ltr"><div>I had a chat with Caio about this and I'm skeptical.  In general, users of the CF manipulation code shouldn't be stitching two blocks together where the first contains a jump and the second is non-empty.  If the caller knows that this case is ok, then they can check for it and empty out the one block before stitching.  Also, I'm not really seeing how peel_initial_if would hit this case from your example.</div><div><br></div><div><br></div></div></blockquote><div>The problem happens when moving the continous list to the end of continue block in loop; the former ends in a jump ("break") and the later also ends in a jump ("continue"), so stitch block complains because there will be an instruction (the "continue") after the jump (the "break").</div><div><br></div><div>As you mentioned, maybe the caller can detect this situation and just get rid of the jump instruction in the continue block, before the stitching. After all, after the merge it won't never be called.</div><div><br></div><div>I'm sending a new patch for this.</div><div><br></div><div><br></div><div>   J.A.</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div dir="ltr"><div>--Jason<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 25, 2019 at 11:37 AM Juan A. Suarez Romero <<a href="mailto:jasuarez@igalia.com">jasuarez@igalia.com</a>> wrote:<br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">When stitching two blocks A and B, where A's last instruction is a jump,<br>
it is not required that B is empty; it can be plainly removed.<br>
<br>
This can happen in a situation like this:<br>
<br>
vec1 1 ssa_1 = load_const (true)<br>
vec1 1 ssa_2 = load_const (false)<br>
block block_1:<br>
[...]<br>
loop {<br>
  vec1 ssa_3 = phi block_1: ssa_2, block_4: ssa_1<br>
  if ssa_3 {<br>
    block block_2:<br>
    [...]<br>
    break<br>
  } else {<br>
    block block_3:<br>
  }<br>
  vec1 ssa_4 = <alu operation><br>
  if ssa_4 {<br>
    block block_4:<br>
    continue<br>
  } else {<br>
    block block_5:<br>
  }<br>
  block block_6:<br>
  [...]<br>
}<br>
<br>
And opt_peel_loop_initial_if is applied. In this case, we would be<br>
ending up stitching block_2 (which finalizes with a jump) with<br>
block_4, which is not empty.<br>
<br>
CC: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>><br>
---<br>
 src/compiler/nir/nir_control_flow.c | 1 -<br>
 1 file changed, 1 deletion(-)<br>
<br>
diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c<br>
index ddba2e55b45..27508f230d6 100644<br>
--- a/src/compiler/nir/nir_control_flow.c<br>
+++ b/src/compiler/nir/nir_control_flow.c<br>
@@ -550,7 +550,6 @@ stitch_blocks(nir_block *before, nir_block *after)<br>
     */<br>
<br>
    if (nir_block_ends_in_jump(before)) {<br>
-      assert(exec_list_is_empty(&after->instr_list));<br>
       if (after->successors[0])<br>
          remove_phi_src(after->successors[0], after);<br>
       if (after->successors[1])<br>
</blockquote></div></blockquote></body></html>