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

            Bug ID: 92811
           Summary: Odd optimisation differences with lambdas
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: david at westcontrol dot com
  Target Milestone: ---

While playing with lambdas for higher order functions (in particular, functions
that manipulate functions and return new ones), I saw some differences in the
optimisations depending on seemingly minor changes to how functions are
defined.  This is my sample code:

template <typename F>
auto twice(F f)
{
    return [f](int v) { return f(f(v)); };
};

int g1(int i)
{
    return i + 3;
};

auto g2 = [](int i) { return i + 3; };

int test(int i) {
    auto tw = twice(g1);
    return tw(i);
}

int test2(int i) {
    auto tw = twice(g1);
    auto tw2 = twice(tw);
    return tw2(i);
}

int test3(int i) {
    auto tw = twice(g2);
    return tw(i);
}

int test4(int i) {
    auto tw = twice(g2);
    auto tw2 = twice(tw);
    return tw2(i);
}


The generated assembly (x86-64) with -O2 or -O3 is:

g1(int):
        leal    3(%rdi), %eax
        ret
test(int):
        leal    6(%rdi), %eax
        ret
test2(int):
        addl    $6, %edi
        call    g1(int)
        movl    %eax, %edi
        jmp     g1(int)
test3(int):
        leal    6(%rdi), %eax
        ret
test4(int):
        leal    12(%rdi), %eax
        ret

With -O1, test3 and test4 (where the original function is a lambda) were still
fully optimised, while test1 and test2 had 2 and 4 calls to g1.

(For comparison, clang requires -O2 to get good code, but fully optimises all 4
test functions.)

Reply via email to