<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 - Improve merging of identical branches"
   href="https://bugs.llvm.org/show_bug.cgi?id=32618">32618</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Improve merging of identical branches
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

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

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

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

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>cuoq@trust-in-soft.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following code:

  va_list ap;
  void *result;

  va_start(ap, ptr_type);

  switch (ptr_type) {
    case 0: result = va_arg(ap, int*); break;
    case 1: result = va_arg(ap, char*); break;
    case 2: result = va_arg(ap, short*); break;
    default: result = va_arg(ap, void*); break;
  }

  va_end(ap);

Clang correctly recognizes that the assembly code for all four branches is
identical, which is the difficult part (the source code for the branches is
different and cannot be merged by the programmer unless
<a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Document that va_arg(ap, void*) can be used to consume any pointer argument"
   href="show_bug.cgi?id=32616">https://bugs.llvm.org/show_bug.cgi?id=32616</a> is resolved). At the time of
writing, the Compiler Explorer trunk version produces:

        cmpl    $2, %edi
        je      .LBB0_5
        cmpl    $1, %edi
        je      .LBB0_5
        testl   %edi, %edi
.LBB0_5:

(Compiler Explorer link: <a href="https://godbolt.org/g/0NvnSX">https://godbolt.org/g/0NvnSX</a> )

This shows that Clang correctly manages to eliminate the conditional branch in
the pattern:

jcc L
L:

Unfortunately, Clang leaves the “testl   %edi, %edi” that preceded the
conditional branch (and is now useless), and this prevents it from eliminating
all the other conditional branches.

It would be nice if all of the assembly snippet posted above could be
eliminated, especially since there are code patterns that must be different at
the source level and identical in assembly, and Clang already recognizes those.</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>