<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - LoopUnroll: runtime check introduces branch on poison if fn call doesn't return"
   href="https://bugs.llvm.org/show_bug.cgi?id=51670">51670</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>LoopUnroll: runtime check introduces branch on poison if fn call doesn't return
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Keywords</th>
          <td>miscompilation
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Loop Optimizer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>nunoplopes@sapo.pt
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>atrick@apple.com, haicheng@codeaurora.org, llvm-bugs@lists.llvm.org, meheff@google.com, nikita.ppv@gmail.com, zhaoshiz@quicinc.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Test: Transforms/LoopUnroll/loop-remarks.ll

In the test below, @baz may not return. In that case, the source function will
not branch on the possibly poison %exitcond (poison if %n poison).
The target function always branches on %n regardless of whether @baz returns or
not.
The fix is to freeze %n if the code doesn't provably reach the branch.


define i32 @runtime(i32 %n) {
%entry:
  br label %for.body

%for.body:
  %s.06 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
  %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %add = add nsw i32 %i.05, 4
  %call = call i32 @baz(i32 %add)
  %add1 = add nsw i32 %call, %s.06
  %inc = add nsw i32 %i.05, 1
  %exitcond = icmp eq i32 %inc, %n
  br i1 %exitcond, label %for.end, label %for.body

%for.end:
  ret i32 %add1
}
=>
define i32 @runtime(i32 %n) {
%entry:
  %0 = add i32 %n, 4294967295
  %xtraiter = and i32 %n, 3
  %1 = icmp ult i32 %0, 3
  br i1 %1, label %for.end.unr-lcssa, label %entry.new

%entry.new:
  %unroll_iter = sub i32 %n, %xtraiter
  br label %for.body

%for.body:
  %s.06 = phi i32 [ 0, %entry.new ], [ %add1.3, %for.body ]
  %i.05 = phi i32 [ 0, %entry.new ], [ %inc.3, %for.body ]
  %niter = phi i32 [ %unroll_iter, %entry.new ], [ %niter.nsub.3, %for.body ]
  %add = add nsw i32 %i.05, 4
  %call = call i32 @baz(i32 %add)
  %add1 = add nsw i32 %call, %s.06
  %inc = add nsw nuw i32 %i.05, 1
  %niter.nsub = sub i32 %niter, 1
  %add.1 = add nsw i32 %inc, 4
  %call.1 = call i32 @baz(i32 %add.1)
  %add1.1 = add nsw i32 %call.1, %add1
  %inc.1 = add nsw nuw i32 %inc, 1
  %niter.nsub.1 = sub i32 %niter.nsub, 1
  %add.2 = add nsw i32 %inc.1, 4
  %call.2 = call i32 @baz(i32 %add.2)
  %add1.2 = add nsw i32 %call.2, %add1.1
  %inc.2 = add nsw nuw i32 %inc.1, 1
  %niter.nsub.2 = sub i32 %niter.nsub.1, 1
  %add.3 = add nsw i32 %inc.2, 4
  %call.3 = call i32 @baz(i32 %add.3)
  %add1.3 = add nsw i32 %call.3, %add1.2
  %inc.3 = add nsw i32 %inc.2, 1
  %niter.nsub.3 = sub i32 %niter.nsub.2, 1
  %niter.ncmp.3 = icmp eq i32 %niter.nsub.3, 0
  br i1 %niter.ncmp.3, label %for.end.unr-lcssa.loopexit, label %for.body

%for.end.unr-lcssa.loopexit:
  %add1.lcssa.ph.ph = phi i32 [ %add1.3, %for.body ]
  %s.06.unr.ph = phi i32 [ %add1.3, %for.body ]
  %i.05.unr.ph = phi i32 [ %inc.3, %for.body ]
  br label %for.end.unr-lcssa

%for.end.unr-lcssa:
  %add1.lcssa.ph = phi i32 [ undef, %entry ], [ %add1.lcssa.ph.ph,
%for.end.unr-lcssa.loopexit ]
  %s.06.unr = phi i32 [ 0, %entry ], [ %s.06.unr.ph,
%for.end.unr-lcssa.loopexit ]
  %i.05.unr = phi i32 [ 0, %entry ], [ %i.05.unr.ph,
%for.end.unr-lcssa.loopexit ]
  %lcmp.mod = icmp ne i32 %xtraiter, 0
  br i1 %lcmp.mod, label %for.body.epil.preheader, label %for.end

%for.body.epil.preheader:
  br label %for.body.epil

%for.body.epil:
  %add.epil = add nsw i32 %i.05.unr, 4
  %call.epil = call i32 @baz(i32 %add.epil)
  %add1.epil = add nsw i32 %call.epil, %s.06.unr
  %inc.epil = add nsw i32 %i.05.unr, 1
  %epil.iter.sub = sub i32 %xtraiter, 1
  %epil.iter.cmp = icmp ne i32 %epil.iter.sub, 0
  br i1 %epil.iter.cmp, label %for.body.epil.1, label %for.end.epilog-lcssa

%for.body.epil.1:
  %add.epil.1 = add nsw i32 %inc.epil, 4
  %call.epil.1 = call i32 @baz(i32 %add.epil.1)
  %add1.epil.1 = add nsw i32 %call.epil.1, %add1.epil
  %inc.epil.1 = add nsw i32 %inc.epil, 1
  %epil.iter.sub.1 = sub i32 %epil.iter.sub, 1
  %epil.iter.cmp.1 = icmp ne i32 %epil.iter.sub.1, 0
  br i1 %epil.iter.cmp.1, label %for.body.epil.2, label %for.end.epilog-lcssa

%for.body.epil.2:
  %add.epil.2 = add nsw i32 %inc.epil.1, 4
  %call.epil.2 = call i32 @baz(i32 %add.epil.2)
  %add1.epil.2 = add nsw i32 %call.epil.2, %add1.epil.1
  br label %for.end.epilog-lcssa

%for.end.epilog-lcssa:
  %add1.lcssa.ph1 = phi i32 [ %add1.epil, %for.body.epil ], [ %add1.epil.1,
%for.body.epil.1 ], [ %add1.epil.2, %for.body.epil.2 ]
  br label %for.end

%for.end:
  %add1.lcssa = phi i32 [ %add1.lcssa.ph, %for.end.unr-lcssa ], [
%add1.lcssa.ph1, %for.end.epilog-lcssa ]
  ret i32 %add1.lcssa
}
Transformation doesn't verify!
ERROR: Source is more defined than target

Example:
i32 %n = poison

Source:
i32 %s.06 = #x00000000 (0)
i32 %i.05 = #x00000000 (0)
i32 %add = #x00000004 (4)
i32 %call = poison
i32 %add1 = poison
i32 %inc = #x00000001 (1)
i1 %exitcond = poison

Target:
i32 %0 = poison
i32 %xtraiter = poison
i1 %1 = poison</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>