<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 - (Simple)LoopUnswitch introduces branch on poison if call doesn't return"
   href="https://bugs.llvm.org/show_bug.cgi?id=51671">51671</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>(Simple)LoopUnswitch introduces branch on poison if 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>aeubanks@google.com, alina.sbirlea@gmail.com, florian_hahn@apple.com, llvm-bugs@lists.llvm.org, max.kazantsev@azul.com, nikita.ppv@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Tests:
 - Transforms/LoopUnswitch/preserve-analyses.ll
 - Transforms/SimpleLoopUnswitch/delete-dead-blocks.ll
 - Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll


In the test below, @pci_get_device may not return. In that case, the source
function will not branch on the undef %conv56.
The target function always branches on %conv56 regardless of whether
@pci_get_device returns or not.
The fix is to freeze the condition if the code doesn't provably reach the
branch.


define void @pnp_check_irq() {
%entry:
  %conv56 = trunc i64 undef to i32
  br label %while.cond.i

%while.cond.i:
  %call.i25 = call * @pci_get_device()
  br i1 undef, label %if.then65, label %while.body.i

%if.then65:
  assume i1 0

%while.body.i:
  br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge

%if.then31.i.i:
  switch i32 %conv56, label %while.cond.i.backedge [
    i32 14, label %if.then42.i.i
    i32 15, label %if.then42.i.i
  ]

%if.then42.i.i:
  %call.i25.lcssa48 = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
  assume i1 0

%while.cond.i.backedge:
  br label %while.cond.i
}
=>
define void @pnp_check_irq() {
%entry:
  %conv56 = trunc i64 undef to i32
  %0 = icmp eq i32 %conv56, 14
  br i1 %0, label %entry.split.us, label %entry.entry.split_crit_edge

%entry.entry.split_crit_edge:
  br label %entry.split

%entry.split:
  %1 = icmp eq i32 %conv56, 15
  br i1 %1, label %entry.split.split.us, label
%entry.split.entry.split.split_crit_edge

%entry.split.split.us:
  br label %while.cond.i.us1

%while.cond.i.us1:
  %call.i25.us2 = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us-lcssa.us, label %while.body.i.us3

%if.then65.us-lcssa.us-lcssa.us:
  br label %if.then65.us-lcssa

%while.body.i.us3:
  br i1 undef, label %if.then31.i.i.us4, label %while.cond.i.backedge.us5

%if.then31.i.i.us4:
  switch i32 15, label %while.cond.i.backedge.us5 [
    i32 14, label %if.then42.i.i.us-lcssa.us-lcssa.us
    i32 15, label %if.then42.i.i.us-lcssa.us-lcssa.us
  ]

%if.then42.i.i.us-lcssa.us-lcssa.us:
  %call.i25.lcssa48.ph.ph.us = phi * [ %call.i25.us2, %if.then31.i.i.us4 ], [
%call.i25.us2, %if.then31.i.i.us4 ]
  br label %if.then42.i.i.us-lcssa

%while.cond.i.backedge.us5:
  br label %while.cond.i.us1

%entry.split.entry.split.split_crit_edge:
  br label %entry.split.split

%entry.split.split:
  br label %while.cond.i

%while.cond.i:
  %call.i25 = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us-lcssa, label %while.body.i

%if.then65.us-lcssa.us-lcssa:
  br label %if.then65.us-lcssa

%if.then65.us-lcssa:
  br label %if.then65

%while.body.i:
  br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge

%if.then31.i.i:
  switch i32 %conv56, label %while.cond.i.backedge [
    i32 14, label %if.then42.i.i.us-lcssa.us-lcssa
    i32 15, label %if.then42.i.i.us-lcssa.us-lcssa
  ]

%if.then42.i.i.us-lcssa.us-lcssa:
  %call.i25.lcssa48.ph.ph = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
  br label %if.then42.i.i.us-lcssa

%if.then42.i.i.us-lcssa:
  %call.i25.lcssa48.ph = phi * [ %call.i25.lcssa48.ph.ph,
%if.then42.i.i.us-lcssa.us-lcssa ], [ %call.i25.lcssa48.ph.ph.us,
%if.then42.i.i.us-lcssa.us-lcssa.us ]
  br label %if.then42.i.i

%while.cond.i.backedge:
  br label %while.cond.i

%entry.split.us:
  br label %while.cond.i.us

%while.cond.i.us:
  %call.i25.us = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us, label %while.body.i.us

%if.then65.us-lcssa.us:
  br label %if.then65

%if.then65:
  assume i1 0

%while.body.i.us:
  br i1 undef, label %if.then31.i.i.us, label %while.cond.i.backedge.us

%if.then31.i.i.us:
  switch i32 14, label %while.cond.i.backedge.us [
    i32 14, label %if.then42.i.i.us-lcssa.us
    i32 15, label %if.then42.i.i.us-lcssa.us
  ]

%if.then42.i.i.us-lcssa.us:
  %call.i25.lcssa48.ph.us = phi * [ %call.i25.us, %if.then31.i.i.us ], [
%call.i25.us, %if.then31.i.i.us ]
  br label %if.then42.i.i

%if.then42.i.i:
  %call.i25.lcssa48 = phi * [ %call.i25.lcssa48.ph, %if.then42.i.i.us-lcssa ],
[ %call.i25.lcssa48.ph.us, %if.then42.i.i.us-lcssa.us ]
  assume i1 0

%while.cond.i.backedge.us:
  br label %while.cond.i.us
}
Transformation doesn't verify!
ERROR: Source is more defined than target

Example:

Source:
i32 %conv56 = any
* %call.i25 = poison

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 1        alloc type: 0
Block 1 >       size: 0 align: 1

Target:
i32 %conv56 = #xfffffff1 (4294967281, -15)
i1 %0 = #x0 (0)
i1 %1 = #x0 (0)
* %call.i25.us2 = poison
* %call.i25 = poison
* %call.i25.us = 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>