diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 050b027fbe565ae83ea1251ff47107b04532f8fa..9704fd601493bb9a52a3e20c21d03804782f428a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-26  Marc Glisse  <marc.glisse@inria.fr>
+
+	* include/bits/stl_vector.h (_Vector_impl_data::_M_copy_data): New.
+	(_Vector_impl_data::_M_swap_data): Use _M_copy_data.
+	(vector::_M_move_assign): Reorder the swaps.
+
 2018-07-26  Jonathan Wakely  <jwakely@redhat.com>
 
 	PR libstdc++/86676
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index d2be98883b3f1207aed4fa8bcbfb1b52f8a6054e..424971a02f20f188dada12361b290ad674764262 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -102,12 +102,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	{ __x._M_start = __x._M_finish = __x._M_end_of_storage = pointer(); }
 #endif
 
+	void
+	_M_copy_data(_Vector_impl_data const& __x) _GLIBCXX_NOEXCEPT
+	{
+	  _M_start = __x._M_start;
+	  _M_finish = __x._M_finish;
+	  _M_end_of_storage = __x._M_end_of_storage;
+	}
+
 	void
 	_M_swap_data(_Vector_impl_data& __x) _GLIBCXX_NOEXCEPT
 	{
-	  std::swap(_M_start, __x._M_start);
-	  std::swap(_M_finish, __x._M_finish);
-	  std::swap(_M_end_of_storage, __x._M_end_of_storage);
+	  // Do not use std::swap(_M_start, __x._M_start), etc as it loses
+	  // information used by TBAA.
+	  _Vector_impl_data __tmp;
+	  __tmp._M_copy_data(*this);
+	  _M_copy_data(__x);
+	  __x._M_copy_data(__tmp);
 	}
       };
 
@@ -1731,8 +1742,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_move_assign(vector&& __x, true_type) noexcept
       {
 	vector __tmp(get_allocator());
-	this->_M_impl._M_swap_data(__tmp._M_impl);
 	this->_M_impl._M_swap_data(__x._M_impl);
+	__tmp._M_impl._M_swap_data(__x._M_impl);
 	std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator());
       }