<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 - Missed Tail Call Optimization when specifying function return value with __builtin_unreachable or __builtin_assume"
   href="https://bugs.llvm.org/show_bug.cgi?id=43007">43007</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Missed Tail Call Optimization when specifying function return value with __builtin_unreachable or __builtin_assume
          </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>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Scalar Optimizations
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>mike.k@digitalcarbide.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When explicitly specifying that a function can only return a specific value
using either __builtin_unreachable or __builtin_assume, the optimizer fails to
perform tail call optimization.

This is observed for all architectures.

Example:

extern int function_returns_only_1_or_doesnt_return(int, int);

int foo1(int a, int b) {
    const int result = function_returns_only_1_or_doesnt_return(a, b);
    if (result == 1) {
        return result;
    }
    else {
        __builtin_unreachable();
    }
}

int foo2(int a, int b) {
    const int result = function_returns_only_1_or_doesnt_return(a, b);
    __builtin_assume(result == 1);
    return result;
}

int foo3(int a, int b) {
    return function_returns_only_1_or_doesnt_return(a, b);
}

For the flags '-O3' for an x86-64 target, this emits the following assembly:

foo1(int, int): # @foo1(int, int)
  push rax
  call function_returns_only_1_or_doesnt_return(int, int)
  mov eax, 1
  pop rcx
  ret
foo2(int, int): # @foo2(int, int)
  push rax
  call function_returns_only_1_or_doesnt_return(int, int)
  mov eax, 1
  pop rcx
  ret
foo3(int, int): # @foo3(int, int)
  jmp function_returns_only_1_or_doesnt_return(int, int) # TAILCALL

It would be expected that all three would perform tail call optimization.</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>