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

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Marc Glisse from comment #2)
> If I make __is_bitwise_relocatable<int> false, we don't get memmove/memcpy
> for foo_int either.

If we didn't use __relocate at all, we'd also get memcpy. Because we'd relocate
with std::uninitialized_move followed by std::destroy_n. On paper that means
two loops, but because the destructor is trivial, destroy_n is a no-op. And the
uninitialized_move would be optimized to memcpy.

So the relocate "optimization" hurts here.

The __relocate optimization makes sense for types that are actually bitwise
relocatable, and for types that are not trivially destructible, but for this
case we'd be better off with:

--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -1267,6 +1267,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        _ValueType2;
       static_assert(std::is_same<_ValueType, _ValueType2>::value,
          "relocation is only possible for values of the same type");
+
+      if _GLIBCXX_CONSTEXPR (__is_trivially_destructible(_ValueType))
+       {
+         __result = std::uninitialized_move(__first, __last, __result);
+         std::_Destroy(__first, __last); // will be optimized away
+         return __result
+       }
+
       _ForwardIterator __cur = __result;
       for (; __first != __last; ++__first, (void)++__cur)
        std::__relocate_object_a(std::addressof(*__cur),


Or we could just change the definition of __bitwise_relocatable.

Reply via email to