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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I think we can use this condition:

      const bool __load_outside_loop =
#if __has_builtin(__is_trivially_constructible) \
      && __has_builtin(__is_trivially_assignable)
            __is_trivially_constructible(_Tp, const _Tp&)
            && __is_trivially_assignable(__decltype(*__first), const _Tp&)
#else
            __is_trivially_copyable(_Tp)
            && __is_same(_Tp, __typeof__(*__first))
#endif
            && sizeof(_Tp) <= sizeof(long long);

We need to know that making a copy of the object has no side effects, i.e. is
trivial.
We need to know that assigning the object to *__first is a trivial assignment.
And we probably don't want to make a local copy if it's very large.

This will disable the optimization when it's not correct to use it, as in
comment 1 and comment 2, and will enable it for other scalar types like enums,
and for sufficiently small structs where the assignment is trivial.

Reply via email to