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

            Bug ID: 115581
           Summary: missed argument forwarding in lambda
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following piece of C++ code:
```
struct thing {
    int x[64];
};

void g(const thing &);

void f1(thing x)
{
    g(x);
}

auto *f2 = +[](thing x) {
    g(x);
};

struct f3 {
    void operator()(thing);
};
void f3::operator()(thing x) {
    g(x);
}
```

Checking the generated code on an x86-64 linux system at -O2, note that `f1()`
and `f3::operator()()` simply "forward" their by-value arguments to `g()`:

```
f1(thing):
        sub     rsp, 8
        lea     rdi, [rsp+16]
        call    g(thing const&)
        add     rsp, 8
        ret
```

Notice that this is not done in the case of `f2`, the generated function from
the lambda makes a copy of `x`:

```
f2::{lambda(thing)#1}::_FUN(thing):
        sub     rsp, 264
        movdqu  xmm0, XMMWORD PTR [rsp+272]
        mov     rdi, rsp
        movaps  XMMWORD PTR [rsp], xmm0
        movdqu  xmm0, XMMWORD PTR [rsp+288]
        [...]
        movdqu  xmm0, XMMWORD PTR [rsp+512]
        movaps  XMMWORD PTR [rsp+240], xmm0
        call    g(thing const&)
        add     rsp, 264
        ret
```

See https://gcc.godbolt.org/z/n43a6MPjY, clang does the same copy, so maybe
there is a rule in C++ that prevents this optimization and that I failed to
consider?

Reply via email to