https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91459

            Bug ID: 91459
           Summary: Tail-Call Optimization is not performed when return
                    value is assumed.
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mike.k at digitalcarbide dot com
  Target Milestone: ---

In situations where a function either returns a specific value or does not
return at all, GCC fails to perform tail call optimizations. This appears to
occur on all GCC versions with -O1, -O2, -O3, and -Os. It occurs with both the
C and C++ front-ends.

Observe:

/* This function is guaranteed to only return the value '1', else it does not
return.
// This is meant to emulate a function such as 'exec'.
*/
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) {
    return function_returns_only_1_or_doesnt_return(a, b);
}


This results in the following output for -O3 on x86-64:

foo1(int, int):
  push rax
  call function_returns_only_1_or_doesnt_return(int, int)
  mov eax, 1
  pop rdx
  ret
foo3(int, int):
  jmp function_returns_only_1_or_doesnt_return(int, int)

While the behavior is correct, the tail-call optimization is far more optimal
and preserves the same semantics.

The same behavior occurs with other architectures as well, so it does not
appear to be a back-end issue.

Reply via email to