public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102209] New: NRVO for function parameters
@ 2021-09-05 19:55 federico.kircheis at gmail dot com
  2022-03-07 20:35 ` [Bug c++/102209] " pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: federico.kircheis at gmail dot com @ 2021-09-05 19:55 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102209
           Summary: NRVO for function parameters
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

I believe this is a missed optimization opportunity.

Given following class and functions:


----
struct s{ 
   s();
   s(const s&);
   s(s&&);
   void doit();
};

s bar0(){ 
  s v = s();
  v.doit();
  return v;
}
s bar1(s v = s()){
 v.doit(); 
 return v;
}


void foo0(){ auto v = bar0(); }
void foo1(){ auto v = bar1(); }
----

I can see that in bar0, the returned s is copy (and move) elided.
But for bar1, this is not the case.

I've tried different things, like changing function signature, adding
std::forward, change optimization level, disable exceptions, but I was never
able to obtain the desired result.
As in bar1 `v` is actually built a level higher on the stack, for this
code-snippet I would even have expected GCC to have less issue optimizing the
copy/move away.


For reference: https://godbolt.org/z/oe7W3nvcP

foo0():
        sub     rsp, 24
        call    construct()
        lea     rdi, [rsp+15]
        call    s::doit()
        call    destroy()
        add     rsp, 24
        ret
foo1():
        sub     rsp, 24
        call    construct()
        lea     rdi, [rsp+15]
        call    s::doit()
        call    move()
        call    destroy()
        add     rsp, 24
        jmp     destroy()

In both cases, bar* has been inlined.
It can be easily verified that in the case of bar0 everything is inlined, and
no copies are made.
In the case of foo1, a temporary is created, passed to bar without moving or
copying, but when bar1 returns, a move is made.

As s is passed by value, I do not think the move is necessary.
So either my assumption is wrong, or GCC is playing safe.

I would like to know if it is a missed optimization opportunity on the side of
the programmer or compiler (for those classes where even an unnecessary move
might be costly).

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/102209] NRVO for function parameters
  2021-09-05 19:55 [Bug c++/102209] New: NRVO for function parameters federico.kircheis at gmail dot com
@ 2022-03-07 20:35 ` pinskia at gcc dot gnu.org
  2022-03-08 12:25 ` [Bug middle-end/102209] " redi at gcc dot gnu.org
  2022-03-08 20:23 ` federico.kircheis at gmail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-03-07 20:35 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug middle-end/102209] NRVO for function parameters
  2021-09-05 19:55 [Bug c++/102209] New: NRVO for function parameters federico.kircheis at gmail dot com
  2022-03-07 20:35 ` [Bug c++/102209] " pinskia at gcc dot gnu.org
@ 2022-03-08 12:25 ` redi at gcc dot gnu.org
  2022-03-08 20:23 ` federico.kircheis at gmail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-08 12:25 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The standard does not permit copy elision for function parameters. The call to
the move constructor is observable, and cannot be elided.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug middle-end/102209] NRVO for function parameters
  2021-09-05 19:55 [Bug c++/102209] New: NRVO for function parameters federico.kircheis at gmail dot com
  2022-03-07 20:35 ` [Bug c++/102209] " pinskia at gcc dot gnu.org
  2022-03-08 12:25 ` [Bug middle-end/102209] " redi at gcc dot gnu.org
@ 2022-03-08 20:23 ` federico.kircheis at gmail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: federico.kircheis at gmail dot com @ 2022-03-08 20:23 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Federico Kircheis <federico.kircheis at gmail dot com> ---
Isn't the compiler allowed to do copy/move elision even if observable since
before c++17?

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-03-08 20:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-05 19:55 [Bug c++/102209] New: NRVO for function parameters federico.kircheis at gmail dot com
2022-03-07 20:35 ` [Bug c++/102209] " pinskia at gcc dot gnu.org
2022-03-08 12:25 ` [Bug middle-end/102209] " redi at gcc dot gnu.org
2022-03-08 20:23 ` federico.kircheis at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).