<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 - JumpThreading pass causes wrong optimization results in combination with indirect branches (indirectbr)"
   href="https://bugs.llvm.org/show_bug.cgi?id=40992">40992</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>JumpThreading pass causes wrong optimization results in combination with indirect branches (indirectbr)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </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>Severity</th>
          <td>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>matthias.liedtke@sap.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=21574" name="attach_21574" title="Testcase">attachment 21574</a> <a href="attachment.cgi?id=21574&action=edit" title="Testcase">[details]</a></span>
Testcase

Hi,

it seems that I have encountered a bug in the JumpThreading pass that is caused
by the fact that predecessors which terminate with an indirect branch
instruction are skipped in the pass.

I added the corresponding testcase as an attachment.

This is how the testcase works:

There is a condition "%cond" that is evaluated in the beginning. The
interesting path is the one where this condition is true.
In the true case we jump to "condTrue" where we have a select to select between
two different targets. The first target "indirectA" isn't the interesting one
but it seems to be necessary to cause the failure. The second target
"indirectB" jumps to the same block that would also be reachable if "%cond" was
false in the beginning which is labeled "condFalse".
In condFalse we have a branch on "%cond".
What happens here: The JumpThreading sees the branch and checks the
predecessors and finds out that there is one predecessor where we know that
"%cond" is false (the one if coming from basicblock "start"). The other one has
an indirect branch instruction and is skipped because of the indirect branch.
The JumpThreading thinks "Great, only one predecessor to take care of and that
one knows that %cond is false, so I can remove the block condFalse and set all
predecessors to condStillFalse."
It just doesn't notice the indirect branch that then will point to
"condStillFalse" instead of the expected result "condFalse" or "condStillTrue"
if optimization would work correctly.

I have encountered this issue on LLVM5.0 but it also exists in the current
master branch on github.

I was able to apply a fix for the problem:
In the JumpThreading there is the following coding:
    // If the predecessor ends with an indirect goto, we can't change its
    // destination. Same for CallBr.
    if (isa<IndirectBrInst>(Pred->getTerminator()) ||
        isa<CallBrInst>(Pred->getTerminator()))
      continue;

If the "continue;" is replaced by a "return false;" the problem is gone because
we completely skip the JumpThreading optimization as soon as one of the
predecessors finishes with an indirect branch instruction. (The CallBrInst has
been added recently for asm-goto support and I don't know if it has the same
issue but I'd expect so.)
Obviously this will prevent optimizations that beforehand had been possible and
might have been correct.
This fix will break the test callbr-edge-split.ll which has been added
recently. I am not sure if this failure is caused by a missed optimization.

If you agree on the issue and agree with the fix, I can contribute it.
Otherwise I'd be interested in details how this issue could be fixed in a way
that doesn't completely stop the JumpThreading optimization when indirect
branches are involved.

Thanks in advance and best regards,
Matthias</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>