diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1631,7 +1631,7 @@
 
 // copy
 template <class _Iter>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 _Iter
 __unwrap_iter(_Iter __i)
 {
@@ -1639,7 +1639,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1653,7 +1653,7 @@
 #if _LIBCPP_DEBUG_LEVEL < 2
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1665,7 +1665,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1679,7 +1679,7 @@
 #else
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1860,17 +1860,25 @@
 // move
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 _OutputIterator
-__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
     for (; __first != __last; ++__first, (void) ++__result)
         *__result = _VSTD::move(*__first);
     return __result;
 }
 
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_OutputIterator
+__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return __move_constexpr(__first, __last, __result);
+}
+
 template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_same<typename remove_const<_Tp>::type, _Up>::value &&
@@ -1879,6 +1887,13 @@
 >::type
 __move(_Tp* __first, _Tp* __last, _Up* __result)
 {
+#ifndef _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
+    if (is_constant_evaluated())
+        // "__move_constexpr" exists so that this function doesn't call itself.
+        return __move_constexpr(__first, __last, __result);
+#elif _LIBCPP_STD_VER > 17 // We must assume we are in a constexpr after C++17.
+    return __move_constexpr(__first, __last, __result);
+#endif // _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
     const size_t __n = static_cast<size_t>(__last - __first);
     if (__n > 0)
         _VSTD::memmove(__result, __first, __n * sizeof(_Up));
@@ -1886,7 +1901,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
@@ -1896,17 +1911,25 @@
 // move_backward
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 _OutputIterator
-__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
     while (__first != __last)
         *--__result = _VSTD::move(*--__last);
     return __result;
 }
 
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+_OutputIterator
+__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return __move_backward_constexpr(__first, __last, __result);
+}
+
 template <class _Tp, class _Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_same<typename remove_const<_Tp>::type, _Up>::value &&
@@ -1915,6 +1938,13 @@
 >::type
 __move_backward(_Tp* __first, _Tp* __last, _Up* __result)
 {
+#ifndef _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
+    if (is_constant_evaluated())
+        // "__move_backward_constexpr" exists so that this function doesn't call itself.
+        return __move_backward_constexpr(__first, __last, __result);
+#elif _LIBCPP_STD_VER > 17 // We must assume we are in a constexpr after C++17.
+    return __move_backward_constexpr(__first, __last, __result);
+#endif // _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED
     const size_t __n = static_cast<size_t>(__last - __first);
     if (__n > 0)
     {
@@ -1925,7 +1955,7 @@
 }
 
 template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 _BidirectionalIterator2
 move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
               _BidirectionalIterator2 __result)
@@ -2333,7 +2363,7 @@
 // rotate
 
 template <class _ForwardIterator>
-_ForwardIterator
+_LIBCPP_CONSTEXPR _ForwardIterator
 __rotate_left(_ForwardIterator __first, _ForwardIterator __last)
 {
     typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
@@ -2344,7 +2374,7 @@
 }
 
 template <class _BidirectionalIterator>
-_BidirectionalIterator
+_LIBCPP_CONSTEXPR _BidirectionalIterator
 __rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
 {
     typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
@@ -2356,7 +2386,7 @@
 }
 
 template <class _ForwardIterator>
-_ForwardIterator
+_LIBCPP_CONSTEXPR _ForwardIterator
 __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
 {
     _ForwardIterator __i = __middle;
@@ -2392,7 +2422,7 @@
 
 template<typename _Integral>
 inline _LIBCPP_INLINE_VISIBILITY
-_Integral
+_LIBCPP_CONSTEXPR _Integral
 __algo_gcd(_Integral __x, _Integral __y)
 {
     do
@@ -2405,7 +2435,7 @@
 }
 
 template<typename _RandomAccessIterator>
-_RandomAccessIterator
+_LIBCPP_CONSTEXPR _RandomAccessIterator
 __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
 {
     typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@@ -2441,7 +2471,7 @@
 
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
+_LIBCPP_CONSTEXPR _ForwardIterator
 __rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
          _VSTD::forward_iterator_tag)
 {
@@ -2456,7 +2486,7 @@
 
 template <class _BidirectionalIterator>
 inline _LIBCPP_INLINE_VISIBILITY
-_BidirectionalIterator
+_LIBCPP_CONSTEXPR _BidirectionalIterator
 __rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
          _VSTD::bidirectional_iterator_tag)
 {
@@ -2473,7 +2503,7 @@
 
 template <class _RandomAccessIterator>
 inline _LIBCPP_INLINE_VISIBILITY
-_RandomAccessIterator
+_LIBCPP_CONSTEXPR _RandomAccessIterator
 __rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
          _VSTD::random_access_iterator_tag)
 {
@@ -2491,7 +2521,7 @@
 
 template <class _ForwardIterator>
 inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
+_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
 rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
 {
     if (__first == __middle)
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -1372,15 +1372,26 @@
 __wrap_iter<_Iter>
 operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
 
-template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op);
-template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2);
-template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);
-template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);
+template <class _Ip, class _Op>
+_Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+copy(_Ip, _Ip, _Op);
+
+template <class _B1, class _B2>
+_B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+copy_backward(_B1, _B1, _B2);
+
+template <class _Ip, class _Op>
+_Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+move(_Ip, _Ip, _Op);
+
+template <class _B1, class _B2>
+_B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+move_backward(_B1, _B1, _B2);
 
 #if _LIBCPP_DEBUG_LEVEL < 2
 
 template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1391,7 +1402,7 @@
 #else
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
 typename enable_if
 <
     is_trivially_copy_assignable<_Tp>::value,
@@ -1585,12 +1596,12 @@
 
     template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op);
     template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2);
-    template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
-    template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
+    template <class _Ip, class _Op> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op move(_Ip, _Ip, _Op);
+    template <class _B1, class _B2> friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 move_backward(_B1, _B1, _B2);
 
 #if _LIBCPP_DEBUG_LEVEL < 2
     template <class _Tp>
-    _LIBCPP_CONSTEXPR_IF_NODEBUG friend
+    _LIBCPP_CONSTEXPR friend
     typename enable_if
     <
         is_trivially_copy_assignable<_Tp>::value,
@@ -1599,7 +1610,7 @@
     __unwrap_iter(__wrap_iter<_Tp*>);
 #else
   template <class _Tp>
-  inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
+  inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
   typename enable_if
   <
       is_trivially_copy_assignable<_Tp>::value,
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
@@ -21,11 +21,11 @@
 #include "test_iterators.h"
 
 template <class InIter, class OutIter>
-void
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 test()
 {
     const unsigned N = 1000;
-    int ia[N];
+    int ia[N] = {};
     for (unsigned i = 0; i < N; ++i)
         ia[i] = i;
     int ib[N] = {0};
@@ -34,6 +34,8 @@
     assert(base(r) == ib+N);
     for (unsigned i = 0; i < N; ++i)
         assert(ia[i] == ib[i]);
+
+    return true;
 }
 
 #if TEST_STD_VER >= 11
@@ -128,5 +130,37 @@
     test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
 #endif // TEST_STD_VER >= 11
 
+#if TEST_STD_VER > 17
+    static_assert(test<input_iterator<const int*>, input_iterator<int*> >());
+    static_assert(test<input_iterator<const int*>, forward_iterator<int*> >());
+    static_assert(test<input_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<input_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<input_iterator<const int*>, int*>());
+
+    static_assert(test<forward_iterator<const int*>, input_iterator<int*> >());
+    static_assert(test<forward_iterator<const int*>, forward_iterator<int*> >());
+    static_assert(test<forward_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<forward_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<forward_iterator<const int*>, int*>());
+
+    static_assert(test<bidirectional_iterator<const int*>, input_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, forward_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, int*>());
+
+    static_assert(test<random_access_iterator<const int*>, input_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, forward_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, int*>());
+
+    static_assert(test<const int*, input_iterator<int*> >());
+    static_assert(test<const int*, forward_iterator<int*> >());
+    static_assert(test<const int*, bidirectional_iterator<int*> >());
+    static_assert(test<const int*, random_access_iterator<int*> >());
+    static_assert(test<const int*, int*>());
+#endif  // TEST_STD_VER > 17
+
   return 0;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
@@ -21,11 +21,11 @@
 #include "test_iterators.h"
 
 template <class InIter, class OutIter>
-void
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 test()
 {
     const unsigned N = 1000;
-    int ia[N];
+    int ia[N] = {};
     for (unsigned i = 0; i < N; ++i)
         ia[i] = i;
     int ib[N] = {0};
@@ -34,6 +34,8 @@
     assert(base(r) == ib);
     for (unsigned i = 0; i < N; ++i)
         assert(ia[i] == ib[i]);
+
+    return true;
 }
 
 #if TEST_STD_VER >= 11
@@ -82,5 +84,19 @@
     test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
 #endif // TEST_STD_VER >= 11
 
+#if TEST_STD_VER > 17
+    static_assert(test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<const int*>, int*>());
+
+    static_assert(test<random_access_iterator<const int*>, bidirectional_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, random_access_iterator<int*> >());
+    static_assert(test<random_access_iterator<const int*>, int*>());
+
+    static_assert(test<const int*, bidirectional_iterator<int*> >());
+    static_assert(test<const int*, random_access_iterator<int*> >());
+    static_assert(test<const int*, int*>());
+#endif  // TEST_STD_VER > 17
+
   return 0;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate.pass.cpp
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate.pass.cpp
@@ -20,7 +20,7 @@
 #include "test_iterators.h"
 
 template <class Iter>
-void
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
 test()
 {
     int ia[] = {0};
@@ -209,6 +209,8 @@
     assert(ig[3] == 0);
     assert(ig[4] == 1);
     assert(ig[5] == 2);
+
+    return true;
 }
 
 #if TEST_STD_VER >= 11
@@ -435,5 +437,12 @@
 
 #endif
 
+#if TEST_STD_VER > 17
+    static_assert(test<forward_iterator<int*> >());
+    static_assert(test<bidirectional_iterator<int*> >());
+    static_assert(test<random_access_iterator<int*> >());
+    static_assert(test<int*>());
+#endif  // TEST_STD_VER > 17
+
   return 0;
 }