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();
}