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

            Bug ID: 122780
           Summary: Unnecessary stack allocation and copy for
                    copy/move-assignment of trivial type
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: m.cencora at gmail dot com
  Target Milestone: ---

Given following code compiled with C++17 or newer, the 'foo_not_ok' function
could be optimized to same byte-code as 'foo_ok'.
The optimization should be safe to perform for any
trivially-copy/move-assignable type,
because even if address of 'obj_on_heap' escapes to 'create()' via other means,
any stores performed by 'create()' on this object, would be overwritten by the
assignment operator after call returned to 'foo_not_ok' - so for trivial types
these side-effects won't ever be observable.

#include <type_traits>

struct bar
{
    char data[1024 * 1024];
};

static_assert(std::is_trivially_copy_assignable_v<bar>);
static_assert(std::is_trivially_move_assignable_v<bar>);

bar create() noexcept;

void foo_ok()
{
    static bar static_obj;
    // optimal, 'static_obj' is passed as invisible param to 'create'
    static_obj = create();
}

void foo_not_ok(bar& obj_on_heap)
{
    // not optimal, temporary materialization + memcpy
    obj_on_heap = create();
}

Reply via email to