https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97891
--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Andrew Pinski from comment #7)
> There is a padding which causes some of the issue.
> If I change the constructor to be constexpr, C++ front-end produces:
> (void) (*(p + (sizetype) ((long unsigned int) i * 48)) = *(struct A &)
> &TARGET_EXPR <D.4646, {.a=0, .b=0, .c=0, .d=0, .x=0, .y=0, .z=0, .p=0B}>)
> >>>>>;
>
>
> But then the gimplifier messes up and does a store for each field for x86_64.
> insted of just `= {}` (which it does for aarch64).
This is because gimplify_init_constructor has
else if (num_ctor_elements - num_nonzero_elements
> CLEAR_RATIO (optimize_function_for_speed_p (cfun))
&& num_nonzero_elements < num_ctor_elements / 4)
/* If there are "lots" of zeros, it's more efficient to clear
the memory and then set the nonzero elements. */
cleared = true;
For x86, CLEAR_RATIO (optimize_function_for_speed_p (cfun)) is 10. We don't
want to lower CLEAR_RATIO on x86. Should we add a new target hook to decide
how a backend clears constructor?