[libcxx-commits] [libcxx] 243da90 - [libc++] Add the C++17 <memory_resource> header (mono-patch)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 11 05:41:27 PDT 2022


Author: Arthur O'Dwyer
Date: 2022-10-11T08:40:46-04:00
New Revision: 243da90ea5357c1ca324f714ea4813dc9029af27

URL: https://github.com/llvm/llvm-project/commit/243da90ea5357c1ca324f714ea4813dc9029af27
DIFF: https://github.com/llvm/llvm-project/commit/243da90ea5357c1ca324f714ea4813dc9029af27.diff

LOG: [libc++] Add the C++17 <memory_resource> header (mono-patch)

This patch is the rebase and squash of three earlier patches.
It supersedes all three of them.

- D47111: experimental monotonic_buffer_resource.
- D47358: experimental pool resources.
- D47360: Copy std::experimental::pmr to std::pmr.

The significant difference between this patch and the-sum-of-those-three
is that this patch does not add `std::experimental::pmr::monotonic_buffer_resource`
and so on. This patch simply adds the C++17 standard facilities, and
leaves the `std::experimental` namespace entirely alone.

Differential Revision: https://reviews.llvm.org/D89057

Added: 
    libcxx/include/__memory_resource/memory_resource.h
    libcxx/include/__memory_resource/monotonic_buffer_resource.h
    libcxx/include/__memory_resource/polymorphic_allocator.h
    libcxx/include/__memory_resource/pool_options.h
    libcxx/include/__memory_resource/synchronized_pool_resource.h
    libcxx/include/__memory_resource/unsynchronized_pool_resource.h
    libcxx/include/memory_resource
    libcxx/src/memory_resource.cpp
    libcxx/src/memory_resource_init_helper.h
    libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
    libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/debug.deallocate.pass.cpp
    libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
    libcxx/test/libcxx/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.compile.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/assign.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/copy.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/default.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/memory_resource_convert.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/other_alloc.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/equal.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/not_equal.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_rvalue.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_values.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair_evil.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_types.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/destroy.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/select_on_container_copy_construction.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_forward_list_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop2.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.global/default_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.global/new_delete_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.global/null_memory_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/copy_move.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/with_default_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/without_buffer.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_deallocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_exception_safety.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_initial_buffer.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_zero_sized_buffer.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_overaligned_request.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_with_initial_size.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/equality.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/ctor_does_not_allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/sync_with_default_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/unsync_with_default_resource.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/equality.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_overaligned_request.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_reuse_blocks.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_deallocate_matches_allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_overaligned_request.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_reuse_blocks.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_deallocate_matches_allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/construct.fail.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/equal.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/not_equal.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/private_members.fail.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/protected_members.fail.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/allocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/deallocate.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/dtor.pass.cpp
    libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/is_equal.pass.cpp
    libcxx/test/support/test_std_memory_resource.h

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/ReleaseNotes.rst
    libcxx/include/CMakeLists.txt
    libcxx/include/deque
    libcxx/include/forward_list
    libcxx/include/list
    libcxx/include/map
    libcxx/include/module.modulemap.in
    libcxx/include/regex
    libcxx/include/set
    libcxx/include/string
    libcxx/include/unordered_map
    libcxx/include/unordered_set
    libcxx/include/vector
    libcxx/include/version
    libcxx/lib/abi/CHANGELOG.TXT
    libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
    libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
    libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
    libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
    libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
    libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
    libcxx/src/CMakeLists.txt
    libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
    libcxx/test/libcxx/clang_tidy.sh.cpp
    libcxx/test/libcxx/double_include.sh.cpp
    libcxx/test/libcxx/min_max_macros.compile.pass.cpp
    libcxx/test/libcxx/modules_include.sh.cpp
    libcxx/test/libcxx/nasty_macros.compile.pass.cpp
    libcxx/test/libcxx/no_assert_include.compile.pass.cpp
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxx/test/libcxx/transitive_includes.sh.cpp
    libcxx/test/libcxx/transitive_includes/cxx03.csv
    libcxx/test/libcxx/transitive_includes/cxx11.csv
    libcxx/test/libcxx/transitive_includes/cxx14.csv
    libcxx/test/libcxx/transitive_includes/cxx17.csv
    libcxx/test/libcxx/transitive_includes/cxx20.csv
    libcxx/test/libcxx/transitive_includes/cxx2b.csv
    libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
    libcxx/test/support/count_new.h
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 11bff15b66b74..32f7c0c001fb0 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -126,7 +126,7 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_math_special_functions``              *unimplemented*
     ------------------------------------------------- -----------------
-    ``__cpp_lib_memory_resource``                     *unimplemented*
+    ``__cpp_lib_memory_resource``                     ``201603L``
     ------------------------------------------------- -----------------
     ``__cpp_lib_node_extract``                        ``201606L``
     ------------------------------------------------- -----------------

diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index b010213e70314..6a8c61b9ec818 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -48,6 +48,7 @@ Improvements and New Features
 - Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are
   now provided when implementations in the global namespace are provided by
   the C library.
+- Implemented ``<memory_resource>`` header from C++17
 
 Deprecations and Removals
 -------------------------

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 93d7c2bd4b1a2..4f95209e77816 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -414,6 +414,12 @@ set(files
   __memory/uses_allocator.h
   __memory/uses_allocator_construction.h
   __memory/voidify.h
+  __memory_resource/memory_resource.h
+  __memory_resource/monotonic_buffer_resource.h
+  __memory_resource/polymorphic_allocator.h
+  __memory_resource/pool_options.h
+  __memory_resource/synchronized_pool_resource.h
+  __memory_resource/unsynchronized_pool_resource.h
   __mutex_base
   __node_handle
   __numeric/accumulate.h
@@ -776,6 +782,7 @@ set(files
   map
   math.h
   memory
+  memory_resource
   mutex
   new
   numbers

diff  --git a/libcxx/include/__memory_resource/memory_resource.h b/libcxx/include/__memory_resource/memory_resource.h
new file mode 100644
index 0000000000000..0ec984b7a4631
--- /dev/null
+++ b/libcxx/include/__memory_resource/memory_resource.h
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
+#define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.res.class]
+
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") // TODO: move destructor into the dylib
+class _LIBCPP_TYPE_VIS memory_resource {
+  static const size_t __max_align = alignof(max_align_t);
+
+public:
+  virtual ~memory_resource() = default;
+
+  _LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) {
+    return do_allocate(__bytes, __align);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void deallocate(void* __p, size_t __bytes, size_t __align = __max_align) {
+    do_deallocate(__p, __bytes, __align);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI bool is_equal(const memory_resource& __other) const noexcept { return do_is_equal(__other); }
+
+private:
+  virtual void* do_allocate(size_t, size_t)                       = 0;
+  virtual void do_deallocate(void*, size_t, size_t)               = 0;
+  virtual bool do_is_equal(memory_resource const&) const noexcept = 0;
+};
+_LIBCPP_DIAGNOSTIC_POP
+
+// [mem.res.eq]
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
+  return &__lhs == &__rhs || __lhs.is_equal(__rhs);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
+  return !(__lhs == __rhs);
+}
+
+// [mem.res.global]
+
+_LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept;
+
+_LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept;
+
+_LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept;
+
+_LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept;
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H

diff  --git a/libcxx/include/__memory_resource/monotonic_buffer_resource.h b/libcxx/include/__memory_resource/monotonic_buffer_resource.h
new file mode 100644
index 0000000000000..5c35a62b1663c
--- /dev/null
+++ b/libcxx/include/__memory_resource/monotonic_buffer_resource.h
@@ -0,0 +1,119 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
+#define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
+
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory_resource/memory_resource.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.res.monotonic.buffer]
+
+class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
+  static const size_t __default_buffer_capacity  = 1024;
+  static const size_t __default_buffer_alignment = 16;
+
+  struct __chunk_footer {
+    __chunk_footer* __next_;
+    char* __start_;
+    char* __cur_;
+    size_t __align_;
+    size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
+    void* __try_allocate_from_chunk(size_t, size_t);
+  };
+
+  struct __initial_descriptor {
+    char* __start_;
+    char* __cur_;
+    union {
+      char* __end_;
+      size_t __size_;
+    };
+    void* __try_allocate_from_chunk(size_t, size_t);
+  };
+
+public:
+  _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource()
+      : monotonic_buffer_resource(nullptr, __default_buffer_capacity, get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(size_t __initial_size)
+      : monotonic_buffer_resource(nullptr, __initial_size, get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size)
+      : monotonic_buffer_resource(__buffer, __buffer_size, get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(memory_resource* __upstream)
+      : monotonic_buffer_resource(nullptr, __default_buffer_capacity, __upstream) {}
+
+  _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(size_t __initial_size, memory_resource* __upstream)
+      : monotonic_buffer_resource(nullptr, __initial_size, __upstream) {}
+
+  _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size, memory_resource* __upstream)
+      : __res_(__upstream) {
+    __initial_.__start_ = static_cast<char*>(__buffer);
+    if (__buffer != nullptr) {
+      __initial_.__cur_ = static_cast<char*>(__buffer);
+      __initial_.__end_ = static_cast<char*>(__buffer) + __buffer_size;
+    } else {
+      __initial_.__cur_  = nullptr;
+      __initial_.__size_ = __buffer_size;
+    }
+    __chunks_ = nullptr;
+  }
+
+  monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI ~monotonic_buffer_resource() override { release(); }
+
+  monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI void release() {
+    __initial_.__cur_ = __initial_.__start_;
+    while (__chunks_ != nullptr) {
+      __chunk_footer* __next = __chunks_->__next_;
+      __res_->deallocate(__chunks_->__start_, __chunks_->__allocation_size(), __chunks_->__align_);
+      __chunks_ = __next;
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
+
+protected:
+  void* do_allocate(size_t __bytes, size_t __alignment) override; // key function
+
+  _LIBCPP_HIDE_FROM_ABI void do_deallocate(void*, size_t, size_t) override {}
+
+  _LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
+    return this == std::addressof(__other);
+  }
+
+private:
+  __initial_descriptor __initial_;
+  __chunk_footer* __chunks_;
+  memory_resource* __res_;
+};
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H

diff  --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h
new file mode 100644
index 0000000000000..5f9397599a22e
--- /dev/null
+++ b/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -0,0 +1,178 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H
+#define _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H
+
+#include <__assert>
+#include <__config>
+#include <__memory_resource/memory_resource.h>
+#include <cstddef>
+#include <limits>
+#include <new>
+#include <stdexcept>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.poly.allocator.class]
+
+template <class _ValueType>
+class _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
+public:
+  using value_type = _ValueType;
+
+  // [mem.poly.allocator.ctor]
+
+  _LIBCPP_HIDE_FROM_ABI polymorphic_allocator() noexcept : __res_(std::pmr::get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* __r) noexcept : __res_(__r) {}
+
+  polymorphic_allocator(const polymorphic_allocator&) = default;
+
+  template <class _Tp>
+  _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator<_Tp>& __other) noexcept
+      : __res_(__other.resource()) {}
+
+  polymorphic_allocator& operator=(const polymorphic_allocator&) = delete;
+
+  // [mem.poly.allocator.mem]
+
+  _LIBCPP_HIDE_FROM_ABI _ValueType* allocate(size_t __n) {
+    if (__n > __max_size()) {
+      __throw_bad_array_new_length();
+    }
+    return static_cast<_ValueType*>(__res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void deallocate(_ValueType* __p, size_t __n) {
+    _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()");
+    __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
+  }
+
+  template <class _Tp, class... _Ts>
+  _LIBCPP_HIDE_FROM_ABI void construct(_Tp* __p, _Ts&&... __args) {
+    std::__user_alloc_construct_impl(
+        typename __uses_alloc_ctor<_Tp, polymorphic_allocator&, _Ts...>::type(),
+        __p,
+        *this,
+        std::forward<_Ts>(__args)...);
+  }
+
+  template <class _T1, class _T2, class... _Args1, class... _Args2>
+  _LIBCPP_HIDE_FROM_ABI void
+  construct(pair<_T1, _T2>* __p, piecewise_construct_t, tuple<_Args1...> __x, tuple<_Args2...> __y) {
+    ::new ((void*)__p) pair<_T1, _T2>(
+        piecewise_construct,
+        __transform_tuple(typename __uses_alloc_ctor< _T1, polymorphic_allocator&, _Args1... >::type(),
+                          std::move(__x),
+                          typename __make_tuple_indices<sizeof...(_Args1)>::type{}),
+        __transform_tuple(typename __uses_alloc_ctor< _T2, polymorphic_allocator&, _Args2... >::type(),
+                          std::move(__y),
+                          typename __make_tuple_indices<sizeof...(_Args2)>::type{}));
+  }
+
+  template <class _T1, class _T2>
+  _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p) {
+    construct(__p, piecewise_construct, tuple<>(), tuple<>());
+  }
+
+  template <class _T1, class _T2, class _Up, class _Vp>
+  _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __u, _Vp&& __v) {
+    construct(__p,
+              piecewise_construct,
+              std::forward_as_tuple(std::forward<_Up>(__u)),
+              std::forward_as_tuple(std::forward<_Vp>(__v)));
+  }
+
+  template <class _T1, class _T2, class _U1, class _U2>
+  _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_U1, _U2>& __pr) {
+    construct(__p, piecewise_construct, std::forward_as_tuple(__pr.first), std::forward_as_tuple(__pr.second));
+  }
+
+  template <class _T1, class _T2, class _U1, class _U2>
+  _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_U1, _U2>&& __pr) {
+    construct(__p,
+              piecewise_construct,
+              std::forward_as_tuple(std::forward<_U1>(__pr.first)),
+              std::forward_as_tuple(std::forward<_U2>(__pr.second)));
+  }
+
+  template <class _Tp>
+  _LIBCPP_HIDE_FROM_ABI void destroy(_Tp* __p) {
+    __p->~_Tp();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI polymorphic_allocator select_on_container_copy_construction() const noexcept {
+    return polymorphic_allocator();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI memory_resource* resource() const noexcept { return __res_; }
+
+private:
+  template <class... _Args, size_t... _Is>
+  _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
+  __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
+    return std::forward_as_tuple(std::get<_Is>(std::move(__t))...);
+  }
+
+  template <class... _Args, size_t... _Is>
+  _LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>
+  __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
+    using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>;
+    return _Tup(allocator_arg, *this, std::get<_Is>(std::move(__t))...);
+  }
+
+  template <class... _Args, size_t... _Is>
+  _LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., polymorphic_allocator&>
+  __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __tuple_indices<_Is...>) {
+    using _Tup = tuple<_Args&&..., polymorphic_allocator&>;
+    return _Tup(std::get<_Is>(std::move(__t))..., *this);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI size_t __max_size() const noexcept {
+    return numeric_limits<size_t>::max() / sizeof(value_type);
+  }
+
+  memory_resource* __res_;
+};
+
+// [mem.poly.allocator.eq]
+
+template <class _Tp, class _Up>
+inline _LIBCPP_HIDE_FROM_ABI bool
+operator==(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<_Up>& __rhs) noexcept {
+  return *__lhs.resource() == *__rhs.resource();
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_HIDE_FROM_ABI bool
+operator!=(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<_Up>& __rhs) noexcept {
+  return !(__lhs == __rhs);
+}
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H

diff  --git a/libcxx/include/__memory_resource/pool_options.h b/libcxx/include/__memory_resource/pool_options.h
new file mode 100644
index 0000000000000..11585a0e3bc87
--- /dev/null
+++ b/libcxx/include/__memory_resource/pool_options.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H
+#define _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.res.pool.options]
+
+struct _LIBCPP_TYPE_VIS pool_options {
+  size_t max_blocks_per_chunk        = 0;
+  size_t largest_required_pool_block = 0;
+};
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H

diff  --git a/libcxx/include/__memory_resource/synchronized_pool_resource.h b/libcxx/include/__memory_resource/synchronized_pool_resource.h
new file mode 100644
index 0000000000000..550223c7d9689
--- /dev/null
+++ b/libcxx/include/__memory_resource/synchronized_pool_resource.h
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
+#define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H
+
+#include <__config>
+#include <__memory_resource/memory_resource.h>
+#include <__memory_resource/pool_options.h>
+#include <__memory_resource/unsynchronized_pool_resource.h>
+#include <cstddef>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+#  include <mutex>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.res.pool.overview]
+
+class _LIBCPP_TYPE_VIS synchronized_pool_resource : public memory_resource {
+public:
+  _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream)
+      : __unsync_(__opts, __upstream) {}
+
+  _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource()
+      : synchronized_pool_resource(pool_options(), get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit synchronized_pool_resource(memory_resource* __upstream)
+      : synchronized_pool_resource(pool_options(), __upstream) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit synchronized_pool_resource(const pool_options& __opts)
+      : synchronized_pool_resource(__opts, get_default_resource()) {}
+
+  synchronized_pool_resource(const synchronized_pool_resource&) = delete;
+
+  ~synchronized_pool_resource() override = default;
+
+  synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI void release() {
+#  if !defined(_LIBCPP_HAS_NO_THREADS)
+    unique_lock<mutex> __lk(__mut_);
+#  endif
+    __unsync_.release();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __unsync_.upstream_resource(); }
+
+  _LIBCPP_HIDE_FROM_ABI pool_options options() const { return __unsync_.options(); }
+
+protected:
+  _LIBCPP_HIDE_FROM_ABI void* do_allocate(size_t __bytes, size_t __align) override {
+#  if !defined(_LIBCPP_HAS_NO_THREADS)
+    unique_lock<mutex> __lk(__mut_);
+#  endif
+    return __unsync_.allocate(__bytes, __align);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void do_deallocate(void* __p, size_t __bytes, size_t __align) override {
+#  if !defined(_LIBCPP_HAS_NO_THREADS)
+    unique_lock<mutex> __lk(__mut_);
+#  endif
+    return __unsync_.deallocate(__p, __bytes, __align);
+  }
+
+  bool do_is_equal(const memory_resource& __other) const noexcept override; // key function
+
+private:
+#  if !defined(_LIBCPP_HAS_NO_THREADS)
+  mutex __mut_;
+#  endif
+  unsynchronized_pool_resource __unsync_;
+};
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H

diff  --git a/libcxx/include/__memory_resource/unsynchronized_pool_resource.h b/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
new file mode 100644
index 0000000000000..ef8d7a70308eb
--- /dev/null
+++ b/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
+#define _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H
+
+#include <__config>
+#include <__memory_resource/memory_resource.h>
+#include <__memory_resource/pool_options.h>
+#include <cstddef>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// [mem.res.pool.overview]
+
+class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource {
+  class __fixed_pool;
+
+  class __adhoc_pool {
+    struct __chunk_footer;
+    __chunk_footer* __first_;
+
+  public:
+    _LIBCPP_HIDE_FROM_ABI explicit __adhoc_pool() : __first_(nullptr) {}
+
+    void __release_ptr(memory_resource* __upstream);
+    void* __do_allocate(memory_resource* __upstream, size_t __bytes, size_t __align);
+    void __do_deallocate(memory_resource* __upstream, void* __p, size_t __bytes, size_t __align);
+  };
+
+  static const size_t __min_blocks_per_chunk = 16;
+  static const size_t __min_bytes_per_chunk  = 1024;
+  static const size_t __max_blocks_per_chunk = (size_t(1) << 20);
+  static const size_t __max_bytes_per_chunk  = (size_t(1) << 30);
+
+  static const int __log2_smallest_block_size      = 3;
+  static const size_t __smallest_block_size        = 8;
+  static const size_t __default_largest_block_size = (size_t(1) << 20);
+  static const size_t __max_largest_block_size     = (size_t(1) << 30);
+
+  size_t __pool_block_size(int __i) const;
+  int __log2_pool_block_size(int __i) const;
+  int __pool_index(size_t __bytes, size_t __align) const;
+
+public:
+  unsynchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream);
+
+  _LIBCPP_HIDE_FROM_ABI unsynchronized_pool_resource()
+      : unsynchronized_pool_resource(pool_options(), get_default_resource()) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit unsynchronized_pool_resource(memory_resource* __upstream)
+      : unsynchronized_pool_resource(pool_options(), __upstream) {}
+
+  _LIBCPP_HIDE_FROM_ABI explicit unsynchronized_pool_resource(const pool_options& __opts)
+      : unsynchronized_pool_resource(__opts, get_default_resource()) {}
+
+  unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI ~unsynchronized_pool_resource() override { release(); }
+
+  unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete;
+
+  void release();
+
+  _LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
+
+  pool_options options() const;
+
+protected:
+  void* do_allocate(size_t __bytes, size_t __align) override; // key function
+
+  void do_deallocate(void* __p, size_t __bytes, size_t __align) override;
+
+  _LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
+    return &__other == this;
+  }
+
+private:
+  memory_resource* __res_;
+  __adhoc_pool __adhoc_pool_;
+  __fixed_pool* __fixed_pools_;
+  int __num_fixed_pools_;
+  uint32_t __options_max_blocks_per_chunk_;
+};
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H

diff  --git a/libcxx/include/deque b/libcxx/include/deque
index bce6bc2305a86..c315fd24cd3cc 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -179,6 +179,7 @@ template <class T, class Allocator, class Predicate>
 #include <__memory/pointer_traits.h>
 #include <__memory/temp_value.h>
 #include <__memory/unique_ptr.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__split_buffer>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
@@ -2928,6 +2929,15 @@ inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true;
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _ValueT>
+using deque = std::deque<_ValueT, polymorphic_allocator<_ValueT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 471b78facb168..5890fdd22b277 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -196,6 +196,7 @@ template <class T, class Allocator, class Predicate>
 #include <__memory/shared_ptr.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
@@ -1776,6 +1777,15 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _ValueT>
+using forward_list = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/list b/libcxx/include/list
index b7c4236705287..edd56e5e2ca45 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -202,6 +202,7 @@ template <class T, class Allocator, class Predicate>
 #include <__memory/shared_ptr.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
@@ -2357,6 +2358,15 @@ inline constexpr bool __format::__enable_insertable<std::list<wchar_t>> = true;
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _ValueT>
+using list = std::list<_ValueT, polymorphic_allocator<_ValueT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/map b/libcxx/include/map
index 6df74c3b43e41..8f01d6303407e 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -539,6 +539,7 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/allocator.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
 #include <__tree>
 #include <__type_traits/is_allocator.h>
@@ -2332,6 +2333,18 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
+using map = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+
+template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
+using multimap = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <functional>
 #  include <iterator>

diff  --git a/libcxx/include/memory_resource b/libcxx/include/memory_resource
new file mode 100644
index 0000000000000..4b393433696f8
--- /dev/null
+++ b/libcxx/include/memory_resource
@@ -0,0 +1,65 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_MEMORY_RESOURCE
+#define _LIBCPP_MEMORY_RESOURCE
+
+/**
+    memory_resource synopsis
+
+// C++17
+
+namespace std::pmr {
+
+  class memory_resource;
+
+  bool operator==(const memory_resource& a,
+                  const memory_resource& b) noexcept;
+  bool operator!=(const memory_resource& a,
+                  const memory_resource& b) noexcept;
+
+  template <class Tp> class polymorphic_allocator;
+
+  template <class T1, class T2>
+  bool operator==(const polymorphic_allocator<T1>& a,
+                  const polymorphic_allocator<T2>& b) noexcept;
+  template <class T1, class T2>
+  bool operator!=(const polymorphic_allocator<T1>& a,
+                  const polymorphic_allocator<T2>& b) noexcept;
+
+  // Global memory resources
+  memory_resource* set_default_resource(memory_resource* r) noexcept;
+  memory_resource* get_default_resource() noexcept;
+  memory_resource* new_delete_resource() noexcept;
+  memory_resource* null_memory_resource() noexcept;
+
+  // Pool resource classes
+  struct pool_options;
+  class synchronized_pool_resource;
+  class unsynchronized_pool_resource;
+  class monotonic_buffer_resource;
+
+} // namespace std::pmr
+
+ */
+
+#include <__config>
+#include <__memory_resource/memory_resource.h>
+#include <__memory_resource/monotonic_buffer_resource.h>
+#include <__memory_resource/polymorphic_allocator.h>
+#include <__memory_resource/pool_options.h>
+#include <__memory_resource/synchronized_pool_resource.h>
+#include <__memory_resource/unsynchronized_pool_resource.h>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#endif /* _LIBCPP_MEMORY_RESOURCE */

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 35356a493d1f6..d224c5ba90819 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -882,6 +882,19 @@ module std [system] {
       module voidify                         { private header "__memory/voidify.h" }
     }
   }
+  module memory_resource {
+    header "memory_resource"
+    export *
+
+    module __memory_resource {
+      module memory_resource              { private header "__memory_resource/memory_resource.h" }
+      module monotonic_buffer_resource    { private header "__memory_resource/monotonic_buffer_resource.h" }
+      module polymorphic_allocator        { private header "__memory_resource/polymorphic_allocator.h" }
+      module pool_options                 { private header "__memory_resource/pool_options.h" }
+      module synchronized_pool_resource   { private header "__memory_resource/synchronized_pool_resource.h" }
+      module unsynchronized_pool_resource { private header "__memory_resource/unsynchronized_pool_resource.h" }
+    }
+  }
   module mutex {
     @requires_LIBCXX_ENABLE_THREADS@
     header "mutex"

diff  --git a/libcxx/include/regex b/libcxx/include/regex
index e1799d913a8a7..d45f6c1318d30 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -769,6 +769,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #include <__iterator/back_insert_iterator.h>
 #include <__iterator/wrap_iter.h>
 #include <__locale>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__utility/move.h>
 #include <__utility/pair.h>
 #include <__utility/swap.h>
@@ -6837,6 +6838,20 @@ regex_replace(const _CharT* __s,
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _BidirT>
+using match_results = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
+
+using cmatch  = match_results<const char*>;
+using wcmatch = match_results<const wchar_t*>;
+using smatch  = match_results<std::pmr::string::const_iterator>;
+using wsmatch = match_results<std::pmr::wstring::const_iterator>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/set b/libcxx/include/set
index f7ce27c1d80b4..1f7f25514e4ce 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -481,6 +481,7 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__memory/allocator.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
 #include <__tree>
 #include <__type_traits/is_allocator.h>
@@ -1575,6 +1576,18 @@ inline _LIBCPP_INLINE_VISIBILITY
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _KeyT, class _CompareT = std::less<_KeyT>>
+using set = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
+
+template <class _KeyT, class _CompareT = std::less<_KeyT>>
+using multiset = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <functional>
 #  include <iterator>

diff  --git a/libcxx/include/string b/libcxx/include/string
index 0d42c34dbd67b..31d053c60467a 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -551,6 +551,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__memory/construct_at.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__string/char_traits.h>
 #include <__string/extern_template_lists.h>
 #include <__type_traits/is_allocator.h>
@@ -4669,6 +4670,20 @@ inline constexpr bool __format::__enable_insertable<std::basic_string<wchar_t>>
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _CharT, class _TraitsT = std::char_traits<_CharT>>
+using basic_string = std::basic_string<_CharT, _TraitsT, polymorphic_allocator<_CharT>>;
+
+using string    = basic_string<char>;
+using u16string = basic_string<char16_t>;
+using u32string = basic_string<char32_t>;
+using wstring   = basic_string<wchar_t>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 2f20ad34a169f..3d67a3f0a1f7d 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -526,6 +526,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 #include <__iterator/iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/allocator.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
@@ -2621,6 +2622,20 @@ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
+using unordered_map =
+    std::unordered_map<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+
+template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
+using unordered_multimap =
+    std::unordered_multimap<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <algorithm>
 #  include <bit>

diff  --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 3efc3556d7cf4..4cfe7fa7ebd0e 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -471,6 +471,7 @@ template <class Value, class Hash, class Pred, class Alloc>
 #include <__iterator/iterator_traits.h>
 #include <__memory/addressof.h>
 #include <__memory/allocator.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__node_handle>
 #include <__type_traits/is_allocator.h>
 #include <__utility/forward.h>
@@ -1798,6 +1799,18 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
+using unordered_set = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
+
+template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>>
+using unordered_multiset = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <functional>
 #  include <iterator>

diff  --git a/libcxx/include/vector b/libcxx/include/vector
index 08b2d0536c047..1ff6f4a147bb7 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -295,6 +295,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20
 #include <__memory/swap_allocator.h>
 #include <__memory/temp_value.h>
 #include <__memory/uninitialized_algorithms.h>
+#include <__memory_resource/polymorphic_allocator.h>
 #include <__split_buffer>
 #include <__type_traits/is_allocator.h>
 #include <__type_traits/noexcept_move_assign_container.h>
@@ -3263,6 +3264,15 @@ inline constexpr bool __format::__enable_insertable<std::vector<wchar_t>> = true
 
 _LIBCPP_END_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace pmr {
+template <class _ValueT>
+using vector = std::vector<_ValueT, polymorphic_allocator<_ValueT>>;
+} // namespace pmr
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
 _LIBCPP_POP_MACROS
 
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20

diff  --git a/libcxx/include/version b/libcxx/include/version
index 99b94ff874ae4..646ea84da3525 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -265,7 +265,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_make_from_tuple                      201606L
 # define __cpp_lib_map_try_emplace                      201411L
 // # define __cpp_lib_math_special_functions               201603L
-// # define __cpp_lib_memory_resource                      201603L
+# define __cpp_lib_memory_resource                      201603L
 # define __cpp_lib_node_extract                         201606L
 # define __cpp_lib_nonmember_container_access           201411L
 # define __cpp_lib_not_fn                               201603L

diff  --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT
index 5e65e943c6e95..3a09651327786 100644
--- a/libcxx/lib/abi/CHANGELOG.TXT
+++ b/libcxx/lib/abi/CHANGELOG.TXT
@@ -12,6 +12,52 @@ To generate a summary, re-generate the new ABI list using the
 
 New entries should be added directly below the "Version" header.
 
+------------
+Version 16.0
+------------
+
+* [libc++] [C++17] Implement <memory_resource>.
+
+  This commit adds <memory_resource> to the shared library.
+
+  All platforms
+  -------------
+  Symbol added: _ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE
+  Symbol added: _ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm
+  Symbol added: _ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi
+  Symbol added: _ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi
+  Symbol added: _ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv
+  Symbol added: _ZNSt3__13pmr19new_delete_resourceEv
+  Symbol added: _ZNSt3__13pmr20get_default_resourceEv
+  Symbol added: _ZNSt3__13pmr20null_memory_resourceEv
+  Symbol added: _ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE
+  Symbol added: _ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm
+  Symbol added: _ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm
+  Symbol added: _ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE
+  Symbol added: _ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE
+  Symbol added: _ZTINSt3__13pmr15memory_resourceE
+  Symbol added: _ZTINSt3__13pmr25monotonic_buffer_resourceE
+  Symbol added: _ZTINSt3__13pmr26__null_memory_resource_impE
+  Symbol added: _ZTINSt3__13pmr26synchronized_pool_resourceE
+  Symbol added: _ZTINSt3__13pmr28unsynchronized_pool_resourceE
+  Symbol added: _ZTINSt3__13pmr32__new_delete_memory_resource_impE
+  Symbol added: _ZTSNSt3__13pmr15memory_resourceE
+  Symbol added: _ZTSNSt3__13pmr25monotonic_buffer_resourceE
+  Symbol added: _ZTSNSt3__13pmr26__null_memory_resource_impE
+  Symbol added: _ZTSNSt3__13pmr26synchronized_pool_resourceE
+  Symbol added: _ZTSNSt3__13pmr28unsynchronized_pool_resourceE
+  Symbol added: _ZTSNSt3__13pmr32__new_delete_memory_resource_impE
+  Symbol added: _ZTVNSt3__13pmr25monotonic_buffer_resourceE
+  Symbol added: _ZTVNSt3__13pmr26synchronized_pool_resourceE
+  Symbol added: _ZTVNSt3__13pmr28unsynchronized_pool_resourceE
+
 ------------
 Version 15.0
 ------------

diff  --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 50cbe4c2b013d..9b966ed41e120 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -568,6 +568,11 @@
 {'is_defined': True, 'name': '__ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'type': 'FUNC'}
@@ -1527,6 +1532,7 @@
 {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
@@ -1534,7 +1540,6 @@
 {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1554,6 +1559,21 @@
 {'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr19new_delete_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20get_default_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20null_memory_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
@@ -2014,6 +2034,9 @@
 {'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IDsEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
@@ -2182,6 +2205,9 @@
 {'is_defined': True, 'name': '__ZTSNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
@@ -2385,6 +2411,9 @@
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}

diff  --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 56ec7aaa171d9..d388f9ebad560 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -140,6 +140,11 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -573,6 +578,21 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr19new_delete_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20get_default_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20null_memory_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -894,6 +914,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__15ctypeIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__15ctypeIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -949,6 +972,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__15ctypeIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__15ctypeIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
@@ -1007,6 +1033,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__15ctypeIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__15ctypeIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1823,6 +1852,9 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr15memory_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17collateIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17collateIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1896,6 +1928,9 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr15memory_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17collateIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17collateIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
@@ -1963,6 +1998,8 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17collateIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17collateIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1996,6 +2033,8 @@
 {'import_export': 'wIMP', 'is_defined': False, 'name': '_ZdaPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wIMP', 'is_defined': False, 'name': '_ZdaPvSt11align_val_t', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wIMP', 'is_defined': False, 'name': '_ZdlPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wIMP', 'is_defined': False, 'name': '_ZdlPvSt11align_val_t', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wIMP', 'is_defined': False, 'name': '_Znam', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'wIMP', 'is_defined': False, 'name': '_ZnamSt11align_val_t', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'wIMP', 'is_defined': False, 'name': '_Znwm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
\ No newline at end of file
+{'import_export': 'wIMP', 'is_defined': False, 'name': '_Znwm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wIMP', 'is_defined': False, 'name': '_ZnwmSt11align_val_t', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
\ No newline at end of file

diff  --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 9d30600440bd0..747c3b118a1f0 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -140,6 +140,11 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -573,6 +578,21 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13cinE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr19new_delete_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20get_default_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20null_memory_resourceEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -894,6 +914,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__15ctypeIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTINSt3__15ctypeIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -949,6 +972,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__15ctypeIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTSNSt3__15ctypeIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
@@ -1007,6 +1033,9 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__15ctypeIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZTVNSt3__15ctypeIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1823,6 +1852,9 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr15memory_resourceE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17collateIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17collateIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTINSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
@@ -1896,6 +1928,9 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr15memory_resourceE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17collateIcEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17collateIwEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTSNSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
@@ -1963,6 +1998,8 @@
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr26__null_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__13pmr32__new_delete_memory_resource_impE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17collateIcEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17collateIwEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'wEXP', 'is_defined': True, 'name': '_ZTVNSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}

diff  --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index d0e8b7347172d..41b23a1b760ff 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -568,6 +568,11 @@
 {'is_defined': True, 'name': '__ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'type': 'FUNC'}
@@ -1527,6 +1532,7 @@
 {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
@@ -1534,7 +1540,6 @@
 {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1554,6 +1559,21 @@
 {'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr19new_delete_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20get_default_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20null_memory_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
@@ -2030,6 +2050,12 @@
 {'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__time_get_c_storageIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__time_get_c_storageIwEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr15memory_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr26__null_memory_resource_impE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTINSt3__13pmr32__new_delete_memory_resource_impE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
@@ -2207,6 +2233,12 @@
 {'is_defined': True, 'name': '__ZTSNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr15memory_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr26__null_memory_resource_impE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTSNSt3__13pmr32__new_delete_memory_resource_impE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
@@ -2415,6 +2447,9 @@
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '__ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}

diff  --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8de5a0b4da946..38e0d9993cc80 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -39,9 +39,11 @@
 {'is_defined': False, 'name': '_ZdaPv', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdaPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdlPv', 'type': 'FUNC'}
+{'is_defined': False, 'name': '_ZdlPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_Znam', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZnamSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_Znwm', 'type': 'FUNC'}
+{'is_defined': False, 'name': '_ZnwmSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_allocate_exception', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_begin_catch', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_current_primary_exception', 'type': 'FUNC'}
@@ -302,6 +304,11 @@
 {'is_defined': True, 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'type': 'FUNC'}
@@ -1218,6 +1225,7 @@
 {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1225,7 +1233,6 @@
 {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1245,6 +1252,21 @@
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 168, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr19new_delete_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20get_default_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20null_memory_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
@@ -1697,6 +1719,12 @@
 {'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'size': 16, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'size': 16, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr15memory_resourceE', 'size': 16, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr25monotonic_buffer_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr26__null_memory_resource_impE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr26synchronized_pool_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr32__new_delete_memory_resource_impE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__14__fs10filesystem16filesystem_errorE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIcEE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIwEE', 'size': 56, 'type': 'OBJECT'}
@@ -1825,6 +1853,12 @@
 {'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'size': 34, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr15memory_resourceE', 'size': 30, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'size': 40, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr26__null_memory_resource_impE', 'size': 41, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr26synchronized_pool_resourceE', 'size': 41, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 43, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr32__new_delete_memory_resource_impE', 'size': 47, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'size': 44, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIcEE', 'size': 18, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIwEE', 'size': 18, 'type': 'OBJECT'}
@@ -1950,6 +1984,11 @@
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr26__null_memory_resource_impE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr32__new_delete_memory_resource_impE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'size': 40, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIcEE', 'size': 104, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIwEE', 'size': 136, 'type': 'OBJECT'}

diff  --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 90d9a665a1c72..0143fbc026a34 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -18,9 +18,11 @@
 {'is_defined': False, 'name': '_ZdaPv', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdaPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdlPv', 'type': 'FUNC'}
+{'is_defined': False, 'name': '_ZdlPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_Znam', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZnamSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_Znwm', 'type': 'FUNC'}
+{'is_defined': False, 'name': '_ZnwmSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_current_primary_exception', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_decrement_exception_refcount', 'type': 'FUNC'}
 {'is_defined': False, 'name': '__cxa_guard_acquire', 'type': 'FUNC'}
@@ -274,6 +276,11 @@
 {'is_defined': True, 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr26synchronized_pool_resource11do_is_equalERKNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource12__pool_indexEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource17__pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource22__log2_pool_block_sizeEi', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__13pmr28unsynchronized_pool_resource7optionsEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem18directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator13__dereferenceEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__14__fs10filesystem28recursive_directory_iterator5depthEv', 'type': 'FUNC'}
@@ -1190,6 +1197,7 @@
 {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_allEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
@@ -1197,7 +1205,6 @@
 {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__122__libcpp_verbose_abortEPKcz', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1217,6 +1224,21 @@
 {'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 168, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr19new_delete_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20get_default_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20null_memory_resourceEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr20set_default_resourceEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource14__chunk_footer25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr25monotonic_buffer_resource20__initial_descriptor25__try_allocate_from_chunkEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource11do_allocateEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__do_allocateEPNS0_15memory_resourceEmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool13__release_ptrEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource12__adhoc_pool15__do_deallocateEPNS0_15memory_resourceEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource13do_deallocateEPvmm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resource7releaseEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC1ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__13pmr28unsynchronized_pool_resourceC2ERKNS0_12pool_optionsEPNS0_15memory_resourceE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10__absoluteERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem10hash_valueERKNS1_4pathE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem11__canonicalERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
@@ -1669,6 +1691,12 @@
 {'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'size': 16, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'size': 16, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr15memory_resourceE', 'size': 16, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr25monotonic_buffer_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr26__null_memory_resource_impE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr26synchronized_pool_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr28unsynchronized_pool_resourceE', 'size': 24, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTINSt3__13pmr32__new_delete_memory_resource_impE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__14__fs10filesystem16filesystem_errorE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIcEE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIwEE', 'size': 56, 'type': 'OBJECT'}
@@ -1797,6 +1825,12 @@
 {'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'size': 34, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr15memory_resourceE', 'size': 30, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr25monotonic_buffer_resourceE', 'size': 40, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr26__null_memory_resource_impE', 'size': 41, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr26synchronized_pool_resourceE', 'size': 41, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 43, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTSNSt3__13pmr32__new_delete_memory_resource_impE', 'size': 47, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__14__fs10filesystem16filesystem_errorE', 'size': 44, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIcEE', 'size': 18, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIwEE', 'size': 18, 'type': 'OBJECT'}
@@ -1922,6 +1956,11 @@
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr26__null_memory_resource_impE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr28unsynchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__13pmr32__new_delete_memory_resource_impE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__14__fs10filesystem16filesystem_errorE', 'size': 40, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIcEE', 'size': 104, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIwEE', 'size': 136, 'type': 'OBJECT'}

diff  --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 189ba672f61b8..454cc58198a1a 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -31,6 +31,7 @@ set(LIBCXX_SOURCES
   include/to_chars_floating_point.h
   legacy_pointer_safety.cpp
   memory.cpp
+  memory_resource.cpp
   mutex.cpp
   mutex_destructor.cpp
   new.cpp

diff  --git a/libcxx/src/memory_resource.cpp b/libcxx/src/memory_resource.cpp
new file mode 100644
index 0000000000000..571a3a04cab9c
--- /dev/null
+++ b/libcxx/src/memory_resource.cpp
@@ -0,0 +1,479 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+#include <memory_resource>
+
+#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
+#  include <atomic>
+#elif !defined(_LIBCPP_HAS_NO_THREADS)
+#  include <mutex>
+#  if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
+#    pragma comment(lib, "pthread")
+#  endif
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+
+// memory_resource
+
+//memory_resource::~memory_resource() {}
+
+// new_delete_resource()
+
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+static bool is_aligned_to(void* ptr, size_t align) {
+  void* p2     = ptr;
+  size_t space = 1;
+  void* result = std::align(align, 1, p2, space);
+  return (result == ptr);
+}
+#endif
+
+class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource {
+  void* do_allocate(size_t bytes, size_t align) override {
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+    return std::__libcpp_allocate(bytes, align);
+#else
+    if (bytes == 0)
+      bytes = 1;
+    void* result = std::__libcpp_allocate(bytes, align);
+    if (!is_aligned_to(result, align)) {
+      std::__libcpp_deallocate(result, bytes, align);
+      __throw_bad_alloc();
+    }
+    return result;
+#endif
+  }
+
+  void do_deallocate(void* p, size_t bytes, size_t align) override { std::__libcpp_deallocate(p, bytes, align); }
+
+  bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; }
+};
+
+// null_memory_resource()
+
+class _LIBCPP_TYPE_VIS __null_memory_resource_imp : public memory_resource {
+  void* do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
+  void do_deallocate(void*, size_t, size_t) override {}
+  bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; }
+};
+
+namespace {
+
+union ResourceInitHelper {
+  struct {
+    __new_delete_memory_resource_imp new_delete_res;
+    __null_memory_resource_imp null_res;
+  } resources;
+  char dummy;
+  _LIBCPP_CONSTEXPR_SINCE_CXX14 ResourceInitHelper() : resources() {}
+  ~ResourceInitHelper() {}
+};
+
+// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
+// attribute with a value that's reserved for the implementation (we're the implementation).
+#include "memory_resource_init_helper.h"
+
+} // end namespace
+
+memory_resource* new_delete_resource() noexcept { return &res_init.resources.new_delete_res; }
+
+memory_resource* null_memory_resource() noexcept { return &res_init.resources.null_res; }
+
+// default_memory_resource()
+
+static memory_resource* __default_memory_resource(bool set = false, memory_resource* new_res = nullptr) noexcept {
+#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
+  static constinit atomic<memory_resource*> __res{&res_init.resources.new_delete_res};
+  if (set) {
+    new_res = new_res ? new_res : new_delete_resource();
+    // TODO: Can a weaker ordering be used?
+    return std::atomic_exchange_explicit(&__res, new_res, memory_order_acq_rel);
+  } else {
+    return std::atomic_load_explicit(&__res, memory_order_acquire);
+  }
+#elif !defined(_LIBCPP_HAS_NO_THREADS)
+  static constinit memory_resource* res = &res_init.resources.new_delete_res;
+  static mutex res_lock;
+  if (set) {
+    new_res = new_res ? new_res : new_delete_resource();
+    lock_guard<mutex> guard(res_lock);
+    memory_resource* old_res = res;
+    res = new_res;
+    return old_res;
+  } else {
+    lock_guard<mutex> guard(res_lock);
+    return res;
+  }
+#else
+  static constinit memory_resource* res = &res_init.resources.new_delete_res;
+  if (set) {
+    new_res                  = new_res ? new_res : new_delete_resource();
+    memory_resource* old_res = res;
+    res                      = new_res;
+    return old_res;
+  } else {
+    return res;
+  }
+#endif
+}
+
+memory_resource* get_default_resource() noexcept { return __default_memory_resource(); }
+
+memory_resource* set_default_resource(memory_resource* __new_res) noexcept {
+  return __default_memory_resource(true, __new_res);
+}
+
+// 23.12.5, mem.res.pool
+
+static size_t roundup(size_t count, size_t alignment) {
+  size_t mask = alignment - 1;
+  return (count + mask) & ~mask;
+}
+
+struct unsynchronized_pool_resource::__adhoc_pool::__chunk_footer {
+  __chunk_footer* __next_;
+  char* __start_;
+  size_t __align_;
+  size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
+};
+
+void unsynchronized_pool_resource::__adhoc_pool::__release_ptr(memory_resource* upstream) {
+  while (__first_ != nullptr) {
+    __chunk_footer* next = __first_->__next_;
+    upstream->deallocate(__first_->__start_, __first_->__allocation_size(), __first_->__align_);
+    __first_ = next;
+  }
+}
+
+void* unsynchronized_pool_resource::__adhoc_pool::__do_allocate(memory_resource* upstream, size_t bytes, size_t align) {
+  const size_t footer_size  = sizeof(__chunk_footer);
+  const size_t footer_align = alignof(__chunk_footer);
+
+  if (align < footer_align)
+    align = footer_align;
+
+  size_t aligned_capacity = roundup(bytes, footer_align) + footer_size;
+
+  void* result = upstream->allocate(aligned_capacity, align);
+
+  __chunk_footer* h = (__chunk_footer*)((char*)result + aligned_capacity - footer_size);
+  h->__next_        = __first_;
+  h->__start_       = (char*)result;
+  h->__align_       = align;
+  __first_          = h;
+  return result;
+}
+
+void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
+    memory_resource* upstream, void* p, size_t bytes, size_t align) {
+  _LIBCPP_ASSERT(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
+  if (__first_->__start_ == p) {
+    __chunk_footer* next = __first_->__next_;
+    upstream->deallocate(p, __first_->__allocation_size(), __first_->__align_);
+    __first_ = next;
+  } else {
+    for (__chunk_footer* h = __first_; h->__next_ != nullptr; h = h->__next_) {
+      if (h->__next_->__start_ == p) {
+        __chunk_footer* next = h->__next_->__next_;
+        upstream->deallocate(p, h->__next_->__allocation_size(), h->__next_->__align_);
+        h->__next_ = next;
+        return;
+      }
+    }
+    _LIBCPP_ASSERT(false, "deallocating a block that was not allocated with this allocator");
+  }
+}
+
+class unsynchronized_pool_resource::__fixed_pool {
+  struct __chunk_footer {
+    __chunk_footer* __next_;
+    char* __start_;
+    size_t __align_;
+    size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
+  };
+
+  struct __vacancy_header {
+    __vacancy_header* __next_vacancy_;
+  };
+
+  __chunk_footer* __first_chunk_     = nullptr;
+  __vacancy_header* __first_vacancy_ = nullptr;
+
+public:
+  explicit __fixed_pool() = default;
+
+  void __release_ptr(memory_resource* upstream) {
+    __first_vacancy_ = nullptr;
+    while (__first_chunk_ != nullptr) {
+      __chunk_footer* next = __first_chunk_->__next_;
+      upstream->deallocate(__first_chunk_->__start_, __first_chunk_->__allocation_size(), __first_chunk_->__align_);
+      __first_chunk_ = next;
+    }
+  }
+
+  void* __try_allocate_from_vacancies() {
+    if (__first_vacancy_ != nullptr) {
+      void* result     = __first_vacancy_;
+      __first_vacancy_ = __first_vacancy_->__next_vacancy_;
+      return result;
+    }
+    return nullptr;
+  }
+
+  void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) {
+    _LIBCPP_ASSERT(chunk_size % block_size == 0, "");
+    static_assert(__default_alignment >= alignof(std::max_align_t), "");
+    static_assert(__default_alignment >= alignof(__chunk_footer), "");
+    static_assert(__default_alignment >= alignof(__vacancy_header), "");
+
+    const size_t footer_size  = sizeof(__chunk_footer);
+    const size_t footer_align = alignof(__chunk_footer);
+
+    size_t aligned_capacity = roundup(chunk_size, footer_align) + footer_size;
+
+    void* result = upstream->allocate(aligned_capacity, __default_alignment);
+
+    __chunk_footer* h = (__chunk_footer*)((char*)result + aligned_capacity - footer_size);
+    h->__next_        = __first_chunk_;
+    h->__start_       = (char*)result;
+    h->__align_       = __default_alignment;
+    __first_chunk_    = h;
+
+    if (chunk_size > block_size) {
+      __vacancy_header* last_vh = this->__first_vacancy_;
+      for (size_t i = block_size; i != chunk_size; i += block_size) {
+        __vacancy_header* vh = (__vacancy_header*)((char*)result + i);
+        vh->__next_vacancy_  = last_vh;
+        last_vh              = vh;
+      }
+      this->__first_vacancy_ = last_vh;
+    }
+    return result;
+  }
+
+  void __evacuate(void* p) {
+    __vacancy_header* vh = (__vacancy_header*)(p);
+    vh->__next_vacancy_  = __first_vacancy_;
+    __first_vacancy_     = vh;
+  }
+
+  size_t __previous_chunk_size_in_bytes() const { return __first_chunk_ ? __first_chunk_->__allocation_size() : 0; }
+
+  static const size_t __default_alignment = alignof(max_align_t);
+};
+
+size_t unsynchronized_pool_resource::__pool_block_size(int i) const { return size_t(1) << __log2_pool_block_size(i); }
+
+int unsynchronized_pool_resource::__log2_pool_block_size(int i) const { return (i + __log2_smallest_block_size); }
+
+int unsynchronized_pool_resource::__pool_index(size_t bytes, size_t align) const {
+  if (align > alignof(std::max_align_t) || bytes > (size_t(1) << __num_fixed_pools_))
+    return __num_fixed_pools_;
+  else {
+    int i = 0;
+    bytes = (bytes > align) ? bytes : align;
+    bytes -= 1;
+    bytes >>= __log2_smallest_block_size;
+    while (bytes != 0) {
+      bytes >>= 1;
+      i += 1;
+    }
+    return i;
+  }
+}
+
+unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream)
+    : __res_(upstream), __fixed_pools_(nullptr) {
+  size_t largest_block_size;
+  if (opts.largest_required_pool_block == 0)
+    largest_block_size = __default_largest_block_size;
+  else if (opts.largest_required_pool_block < __smallest_block_size)
+    largest_block_size = __smallest_block_size;
+  else if (opts.largest_required_pool_block > __max_largest_block_size)
+    largest_block_size = __max_largest_block_size;
+  else
+    largest_block_size = opts.largest_required_pool_block;
+
+  if (opts.max_blocks_per_chunk == 0)
+    __options_max_blocks_per_chunk_ = __max_blocks_per_chunk;
+  else if (opts.max_blocks_per_chunk < __min_blocks_per_chunk)
+    __options_max_blocks_per_chunk_ = __min_blocks_per_chunk;
+  else if (opts.max_blocks_per_chunk > __max_blocks_per_chunk)
+    __options_max_blocks_per_chunk_ = __max_blocks_per_chunk;
+  else
+    __options_max_blocks_per_chunk_ = opts.max_blocks_per_chunk;
+
+  __num_fixed_pools_ = 1;
+  size_t capacity    = __smallest_block_size;
+  while (capacity < largest_block_size) {
+    capacity <<= 1;
+    __num_fixed_pools_ += 1;
+  }
+}
+
+pool_options unsynchronized_pool_resource::options() const {
+  pool_options p;
+  p.max_blocks_per_chunk        = __options_max_blocks_per_chunk_;
+  p.largest_required_pool_block = __pool_block_size(__num_fixed_pools_ - 1);
+  return p;
+}
+
+void unsynchronized_pool_resource::release() {
+  __adhoc_pool_.__release_ptr(__res_);
+  if (__fixed_pools_ != nullptr) {
+    const int n = __num_fixed_pools_;
+    for (int i = 0; i < n; ++i)
+      __fixed_pools_[i].__release_ptr(__res_);
+    __res_->deallocate(__fixed_pools_, __num_fixed_pools_ * sizeof(__fixed_pool), alignof(__fixed_pool));
+    __fixed_pools_ = nullptr;
+  }
+}
+
+void* unsynchronized_pool_resource::do_allocate(size_t bytes, size_t align) {
+  // A pointer to allocated storage (6.6.4.4.1) with a size of at least bytes.
+  // The size and alignment of the allocated memory shall meet the requirements for
+  // a class derived from memory_resource (23.12).
+  // If the pool selected for a block of size bytes is unable to satisfy the memory request
+  // from its own internal data structures, it will call upstream_resource()->allocate()
+  // to obtain more memory. If bytes is larger than that which the largest pool can handle,
+  // then memory will be allocated using upstream_resource()->allocate().
+
+  int i = __pool_index(bytes, align);
+  if (i == __num_fixed_pools_)
+    return __adhoc_pool_.__do_allocate(__res_, bytes, align);
+  else {
+    if (__fixed_pools_ == nullptr) {
+      __fixed_pools_ =
+          (__fixed_pool*)__res_->allocate(__num_fixed_pools_ * sizeof(__fixed_pool), alignof(__fixed_pool));
+      __fixed_pool* first = __fixed_pools_;
+      __fixed_pool* last  = __fixed_pools_ + __num_fixed_pools_;
+      for (__fixed_pool* pool = first; pool != last; ++pool)
+        ::new ((void*)pool) __fixed_pool;
+    }
+    void* result = __fixed_pools_[i].__try_allocate_from_vacancies();
+    if (result == nullptr) {
+      auto min = [](size_t a, size_t b) { return a < b ? a : b; };
+      auto max = [](size_t a, size_t b) { return a < b ? b : a; };
+
+      size_t prev_chunk_size_in_bytes  = __fixed_pools_[i].__previous_chunk_size_in_bytes();
+      size_t prev_chunk_size_in_blocks = prev_chunk_size_in_bytes >> __log2_pool_block_size(i);
+
+      size_t chunk_size_in_blocks;
+
+      if (prev_chunk_size_in_blocks == 0) {
+        size_t min_blocks_per_chunk = max(__min_bytes_per_chunk >> __log2_pool_block_size(i), __min_blocks_per_chunk);
+        chunk_size_in_blocks        = min_blocks_per_chunk;
+      } else {
+        static_assert(__max_bytes_per_chunk <= SIZE_MAX - (__max_bytes_per_chunk / 4), "unsigned overflow is possible");
+        chunk_size_in_blocks = prev_chunk_size_in_blocks + (prev_chunk_size_in_blocks / 4);
+      }
+
+      size_t max_blocks_per_chunk =
+          min((__max_bytes_per_chunk >> __log2_pool_block_size(i)),
+              min(__max_blocks_per_chunk, __options_max_blocks_per_chunk_));
+      if (chunk_size_in_blocks > max_blocks_per_chunk)
+        chunk_size_in_blocks = max_blocks_per_chunk;
+
+      size_t block_size = __pool_block_size(i);
+
+      size_t chunk_size_in_bytes = (chunk_size_in_blocks << __log2_pool_block_size(i));
+      result                     = __fixed_pools_[i].__allocate_in_new_chunk(__res_, block_size, chunk_size_in_bytes);
+    }
+    return result;
+  }
+}
+
+void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t align) {
+  // Returns the memory at p to the pool. It is unspecified if,
+  // or under what circumstances, this operation will result in
+  // a call to upstream_resource()->deallocate().
+
+  int i = __pool_index(bytes, align);
+  if (i == __num_fixed_pools_)
+    return __adhoc_pool_.__do_deallocate(__res_, p, bytes, align);
+  else {
+    _LIBCPP_ASSERT(__fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
+    __fixed_pools_[i].__evacuate(p);
+  }
+}
+
+bool synchronized_pool_resource::do_is_equal(const memory_resource& other) const noexcept { return &other == this; }
+
+// 23.12.6, mem.res.monotonic.buffer
+
+void* monotonic_buffer_resource::__initial_descriptor::__try_allocate_from_chunk(size_t bytes, size_t align) {
+  if (!__cur_)
+    return nullptr;
+  void* new_ptr       = static_cast<void*>(__cur_);
+  size_t new_capacity = (__end_ - __cur_);
+  void* aligned_ptr   = std::align(align, bytes, new_ptr, new_capacity);
+  if (aligned_ptr != nullptr)
+    __cur_ = static_cast<char*>(new_ptr) + bytes;
+  return aligned_ptr;
+}
+
+void* monotonic_buffer_resource::__chunk_footer::__try_allocate_from_chunk(size_t bytes, size_t align) {
+  void* new_ptr       = static_cast<void*>(__cur_);
+  size_t new_capacity = (reinterpret_cast<char*>(this) - __cur_);
+  void* aligned_ptr   = std::align(align, bytes, new_ptr, new_capacity);
+  if (aligned_ptr != nullptr)
+    __cur_ = static_cast<char*>(new_ptr) + bytes;
+  return aligned_ptr;
+}
+
+void* monotonic_buffer_resource::do_allocate(size_t bytes, size_t align) {
+  const size_t footer_size  = sizeof(__chunk_footer);
+  const size_t footer_align = alignof(__chunk_footer);
+
+  auto previous_allocation_size = [&]() {
+    if (__chunks_ != nullptr)
+      return __chunks_->__allocation_size();
+
+    size_t newsize = (__initial_.__start_ != nullptr) ? (__initial_.__end_ - __initial_.__start_) : __initial_.__size_;
+
+    return roundup(newsize, footer_align) + footer_size;
+  };
+
+  if (void* result = __initial_.__try_allocate_from_chunk(bytes, align))
+    return result;
+  if (__chunks_ != nullptr) {
+    if (void* result = __chunks_->__try_allocate_from_chunk(bytes, align))
+      return result;
+  }
+
+  // Allocate a brand-new chunk.
+
+  if (align < footer_align)
+    align = footer_align;
+
+  size_t aligned_capacity  = roundup(bytes, footer_align) + footer_size;
+  size_t previous_capacity = previous_allocation_size();
+
+  if (aligned_capacity <= previous_capacity) {
+    size_t newsize   = 2 * (previous_capacity - footer_size);
+    aligned_capacity = roundup(newsize, footer_align) + footer_size;
+  }
+
+  char* start            = (char*)__res_->allocate(aligned_capacity, align);
+  __chunk_footer* footer = (__chunk_footer*)(start + aligned_capacity - footer_size);
+  footer->__next_        = __chunks_;
+  footer->__start_       = start;
+  footer->__cur_         = start;
+  footer->__align_       = align;
+  __chunks_              = footer;
+
+  return __chunks_->__try_allocate_from_chunk(bytes, align);
+}
+
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/src/memory_resource_init_helper.h b/libcxx/src/memory_resource_init_helper.h
new file mode 100644
index 0000000000000..032edc12fa278
--- /dev/null
+++ b/libcxx/src/memory_resource_init_helper.h
@@ -0,0 +1,2 @@
+#pragma GCC system_header
+static constinit ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX;

diff  --git a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
index 53ad13b4d59ba..481b7ac8262a3 100644
--- a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
+++ b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
@@ -421,343 +421,349 @@ int main(int, char**) { return 0; }
 #endif
 
 // RUN: %{build} -DTEST_71
-#if defined(TEST_71) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <mutex>
+#if defined(TEST_71)
+#   include <memory_resource>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_72
-#if defined(TEST_72)
-#   include <new>
+#if defined(TEST_72) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <mutex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_73
 #if defined(TEST_73)
-#   include <numbers>
+#   include <new>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_74
 #if defined(TEST_74)
-#   include <numeric>
+#   include <numbers>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_75
 #if defined(TEST_75)
-#   include <optional>
+#   include <numeric>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_76
-#if defined(TEST_76) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <ostream>
+#if defined(TEST_76)
+#   include <optional>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_77
-#if defined(TEST_77)
-#   include <queue>
+#if defined(TEST_77) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <ostream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_78
 #if defined(TEST_78)
-#   include <random>
+#   include <queue>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_79
 #if defined(TEST_79)
-#   include <ranges>
+#   include <random>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_80
 #if defined(TEST_80)
-#   include <ratio>
+#   include <ranges>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_81
-#if defined(TEST_81) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#   include <regex>
+#if defined(TEST_81)
+#   include <ratio>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_82
-#if defined(TEST_82)
-#   include <scoped_allocator>
+#if defined(TEST_82) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <regex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_83
-#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <semaphore>
+#if defined(TEST_83)
+#   include <scoped_allocator>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_84
-#if defined(TEST_84)
+#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <semaphore>
+    using HandlerType = decltype(std::__libcpp_verbose_abort);
+#endif
+
+// RUN: %{build} -DTEST_85
+#if defined(TEST_85)
 #   include <set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_86
-#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS)
+// RUN: %{build} -DTEST_87
+#if defined(TEST_87) && !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <shared_mutex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_87
-#if defined(TEST_87)
+// RUN: %{build} -DTEST_88
+#if defined(TEST_88)
 #   include <span>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_88
-#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_89
+#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <sstream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_89
-#if defined(TEST_89)
+// RUN: %{build} -DTEST_90
+#if defined(TEST_90)
 #   include <stack>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_93
-#if defined(TEST_93)
+// RUN: %{build} -DTEST_94
+#if defined(TEST_94)
 #   include <stdexcept>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_97
-#if defined(TEST_97) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_98
+#if defined(TEST_98) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <streambuf>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_98
-#if defined(TEST_98)
+// RUN: %{build} -DTEST_99
+#if defined(TEST_99)
 #   include <string>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_100
-#if defined(TEST_100)
+// RUN: %{build} -DTEST_101
+#if defined(TEST_101)
 #   include <string_view>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_101
-#if defined(TEST_101) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+// RUN: %{build} -DTEST_102
+#if defined(TEST_102) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 #   include <strstream>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_102
-#if defined(TEST_102)
+// RUN: %{build} -DTEST_103
+#if defined(TEST_103)
 #   include <system_error>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_104
-#if defined(TEST_104) && !defined(_LIBCPP_HAS_NO_THREADS)
-#   include <thread>
-    using HandlerType = decltype(std::__libcpp_verbose_abort);
-#endif
-
 // RUN: %{build} -DTEST_105
-#if defined(TEST_105)
-#   include <tuple>
+#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <thread>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_106
 #if defined(TEST_106)
-#   include <type_traits>
+#   include <tuple>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_107
 #if defined(TEST_107)
-#   include <typeindex>
+#   include <type_traits>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_108
 #if defined(TEST_108)
-#   include <typeinfo>
+#   include <typeindex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_110
-#if defined(TEST_110)
-#   include <unordered_map>
+// RUN: %{build} -DTEST_109
+#if defined(TEST_109)
+#   include <typeinfo>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_111
 #if defined(TEST_111)
-#   include <unordered_set>
+#   include <unordered_map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_112
 #if defined(TEST_112)
-#   include <utility>
+#   include <unordered_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_113
 #if defined(TEST_113)
-#   include <valarray>
+#   include <utility>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_114
 #if defined(TEST_114)
-#   include <variant>
+#   include <valarray>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_115
 #if defined(TEST_115)
-#   include <vector>
+#   include <variant>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_116
 #if defined(TEST_116)
-#   include <version>
+#   include <vector>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
-// RUN: %{build} -DTEST_119
-#if defined(TEST_119) && __cplusplus >= 201103L
-#   include <experimental/algorithm>
+// RUN: %{build} -DTEST_117
+#if defined(TEST_117)
+#   include <version>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_120
-#if defined(TEST_120) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-#   include <experimental/coroutine>
+#if defined(TEST_120) && __cplusplus >= 201103L
+#   include <experimental/algorithm>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_121
-#if defined(TEST_121) && __cplusplus >= 201103L
-#   include <experimental/deque>
+#if defined(TEST_121) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
+#   include <experimental/coroutine>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_122
 #if defined(TEST_122) && __cplusplus >= 201103L
-#   include <experimental/forward_list>
+#   include <experimental/deque>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_123
 #if defined(TEST_123) && __cplusplus >= 201103L
-#   include <experimental/functional>
+#   include <experimental/forward_list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_124
 #if defined(TEST_124) && __cplusplus >= 201103L
-#   include <experimental/iterator>
+#   include <experimental/functional>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_125
 #if defined(TEST_125) && __cplusplus >= 201103L
-#   include <experimental/list>
+#   include <experimental/iterator>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_126
 #if defined(TEST_126) && __cplusplus >= 201103L
-#   include <experimental/map>
+#   include <experimental/list>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_127
 #if defined(TEST_127) && __cplusplus >= 201103L
-#   include <experimental/memory_resource>
+#   include <experimental/map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_128
 #if defined(TEST_128) && __cplusplus >= 201103L
-#   include <experimental/propagate_const>
+#   include <experimental/memory_resource>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_129
-#if defined(TEST_129) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
-#   include <experimental/regex>
+#if defined(TEST_129) && __cplusplus >= 201103L
+#   include <experimental/propagate_const>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_130
-#if defined(TEST_130) && __cplusplus >= 201103L
-#   include <experimental/set>
+#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
+#   include <experimental/regex>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_131
 #if defined(TEST_131) && __cplusplus >= 201103L
-#   include <experimental/simd>
+#   include <experimental/set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_132
 #if defined(TEST_132) && __cplusplus >= 201103L
-#   include <experimental/string>
+#   include <experimental/simd>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_133
 #if defined(TEST_133) && __cplusplus >= 201103L
-#   include <experimental/type_traits>
+#   include <experimental/string>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_134
 #if defined(TEST_134) && __cplusplus >= 201103L
-#   include <experimental/unordered_map>
+#   include <experimental/type_traits>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_135
 #if defined(TEST_135) && __cplusplus >= 201103L
-#   include <experimental/unordered_set>
+#   include <experimental/unordered_map>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_136
 #if defined(TEST_136) && __cplusplus >= 201103L
-#   include <experimental/utility>
+#   include <experimental/unordered_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_137
 #if defined(TEST_137) && __cplusplus >= 201103L
-#   include <experimental/vector>
+#   include <experimental/utility>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_138
-#if defined(TEST_138)
-#   include <ext/hash_map>
+#if defined(TEST_138) && __cplusplus >= 201103L
+#   include <experimental/vector>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif
 
 // RUN: %{build} -DTEST_139
 #if defined(TEST_139)
+#   include <ext/hash_map>
+    using HandlerType = decltype(std::__libcpp_verbose_abort);
+#endif
+
+// RUN: %{build} -DTEST_140
+#if defined(TEST_140)
 #   include <ext/hash_set>
     using HandlerType = decltype(std::__libcpp_verbose_abort);
 #endif

diff  --git a/libcxx/test/libcxx/clang_tidy.sh.cpp b/libcxx/test/libcxx/clang_tidy.sh.cpp
index 66ba544723942..9c2ad8a4f47d1 100644
--- a/libcxx/test/libcxx/clang_tidy.sh.cpp
+++ b/libcxx/test/libcxx/clang_tidy.sh.cpp
@@ -136,6 +136,7 @@ END-SCRIPT
 #include <map>
 #include <math.h>
 #include <memory>
+#include <memory_resource>
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <mutex>
 #endif

diff  --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp
index 8d3cfc0be31cd..bcc808100a2e1 100644
--- a/libcxx/test/libcxx/double_include.sh.cpp
+++ b/libcxx/test/libcxx/double_include.sh.cpp
@@ -138,6 +138,7 @@ END-SCRIPT
 #include <map>
 #include <math.h>
 #include <memory>
+#include <memory_resource>
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <mutex>
 #endif

diff  --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
index 2f5aef69139f7..90bda8634d2d3 100644
--- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
@@ -209,6 +209,8 @@ TEST_MACROS();
 TEST_MACROS();
 #include <memory>
 TEST_MACROS();
+#include <memory_resource>
+TEST_MACROS();
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <mutex>
 TEST_MACROS();

diff  --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp
index b6d73e8ed4460..569d582513f7d 100644
--- a/libcxx/test/libcxx/modules_include.sh.cpp
+++ b/libcxx/test/libcxx/modules_include.sh.cpp
@@ -331,279 +331,283 @@ END-SCRIPT
 #include <memory>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_71
-#if defined(TEST_71) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <mutex>
+#if defined(TEST_71)
+#include <memory_resource>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_72
-#if defined(TEST_72)
-#include <new>
+#if defined(TEST_72) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <mutex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_73
 #if defined(TEST_73)
-#include <numbers>
+#include <new>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_74
 #if defined(TEST_74)
-#include <numeric>
+#include <numbers>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_75
 #if defined(TEST_75)
-#include <optional>
+#include <numeric>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_76
-#if defined(TEST_76) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <ostream>
+#if defined(TEST_76)
+#include <optional>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_77
-#if defined(TEST_77)
-#include <queue>
+#if defined(TEST_77) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <ostream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_78
 #if defined(TEST_78)
-#include <random>
+#include <queue>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_79
 #if defined(TEST_79)
-#include <ranges>
+#include <random>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_80
 #if defined(TEST_80)
-#include <ratio>
+#include <ranges>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_81
-#if defined(TEST_81) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <regex>
+#if defined(TEST_81)
+#include <ratio>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_82
-#if defined(TEST_82)
-#include <scoped_allocator>
+#if defined(TEST_82) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <regex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_83
-#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <semaphore>
+#if defined(TEST_83)
+#include <scoped_allocator>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_84
-#if defined(TEST_84)
-#include <set>
+#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <semaphore>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_85
 #if defined(TEST_85)
-#include <setjmp.h>
+#include <set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_86
-#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <shared_mutex>
+#if defined(TEST_86)
+#include <setjmp.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_87
-#if defined(TEST_87)
-#include <span>
+#if defined(TEST_87) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <shared_mutex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_88
-#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <sstream>
+#if defined(TEST_88)
+#include <span>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_89
-#if defined(TEST_89)
-#include <stack>
+#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <sstream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_90
-#if defined(TEST_90) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <stdatomic.h>
+#if defined(TEST_90)
+#include <stack>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_91
-#if defined(TEST_91)
-#include <stdbool.h>
+#if defined(TEST_91) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <stdatomic.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_92
 #if defined(TEST_92)
-#include <stddef.h>
+#include <stdbool.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_93
 #if defined(TEST_93)
-#include <stdexcept>
+#include <stddef.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_94
 #if defined(TEST_94)
-#include <stdint.h>
+#include <stdexcept>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_95
 #if defined(TEST_95)
-#include <stdio.h>
+#include <stdint.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_96
 #if defined(TEST_96)
-#include <stdlib.h>
+#include <stdio.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_97
-#if defined(TEST_97) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <streambuf>
+#if defined(TEST_97)
+#include <stdlib.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_98
-#if defined(TEST_98)
-#include <string>
+#if defined(TEST_98) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <streambuf>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_99
 #if defined(TEST_99)
-#include <string.h>
+#include <string>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_100
 #if defined(TEST_100)
-#include <string_view>
+#include <string.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_101
-#if defined(TEST_101) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-#include <strstream>
+#if defined(TEST_101)
+#include <string_view>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_102
-#if defined(TEST_102)
-#include <system_error>
+#if defined(TEST_102) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#include <strstream>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_103
 #if defined(TEST_103)
-#include <tgmath.h>
+#include <system_error>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_104
-#if defined(TEST_104) && !defined(_LIBCPP_HAS_NO_THREADS)
-#include <thread>
+#if defined(TEST_104)
+#include <tgmath.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_105
-#if defined(TEST_105)
-#include <tuple>
+#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_THREADS)
+#include <thread>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_106
 #if defined(TEST_106)
-#include <type_traits>
+#include <tuple>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_107
 #if defined(TEST_107)
-#include <typeindex>
+#include <type_traits>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_108
 #if defined(TEST_108)
-#include <typeinfo>
+#include <typeindex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_109
 #if defined(TEST_109)
-#include <uchar.h>
+#include <typeinfo>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_110
 #if defined(TEST_110)
-#include <unordered_map>
+#include <uchar.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_111
 #if defined(TEST_111)
-#include <unordered_set>
+#include <unordered_map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_112
 #if defined(TEST_112)
-#include <utility>
+#include <unordered_set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_113
 #if defined(TEST_113)
-#include <valarray>
+#include <utility>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_114
 #if defined(TEST_114)
-#include <variant>
+#include <valarray>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_115
 #if defined(TEST_115)
-#include <vector>
+#include <variant>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_116
 #if defined(TEST_116)
-#include <version>
+#include <vector>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_117
-#if defined(TEST_117) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-#include <wchar.h>
+#if defined(TEST_117)
+#include <version>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_118
 #if defined(TEST_118) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-#include <wctype.h>
+#include <wchar.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_119
-#if defined(TEST_119) && __cplusplus >= 201103L
-#include <experimental/algorithm>
+#if defined(TEST_119) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+#include <wctype.h>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_120
-#if defined(TEST_120) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-#include <experimental/coroutine>
+#if defined(TEST_120) && __cplusplus >= 201103L
+#include <experimental/algorithm>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_121
-#if defined(TEST_121) && __cplusplus >= 201103L
-#include <experimental/deque>
+#if defined(TEST_121) && __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
+#include <experimental/coroutine>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_122
 #if defined(TEST_122) && __cplusplus >= 201103L
-#include <experimental/forward_list>
+#include <experimental/deque>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_123
 #if defined(TEST_123) && __cplusplus >= 201103L
-#include <experimental/functional>
+#include <experimental/forward_list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_124
 #if defined(TEST_124) && __cplusplus >= 201103L
-#include <experimental/iterator>
+#include <experimental/functional>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_125
 #if defined(TEST_125) && __cplusplus >= 201103L
-#include <experimental/list>
+#include <experimental/iterator>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_126
 #if defined(TEST_126) && __cplusplus >= 201103L
-#include <experimental/map>
+#include <experimental/list>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_127
 #if defined(TEST_127) && __cplusplus >= 201103L
-#include <experimental/memory_resource>
+#include <experimental/map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_128
 #if defined(TEST_128) && __cplusplus >= 201103L
-#include <experimental/propagate_const>
+#include <experimental/memory_resource>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_129
-#if defined(TEST_129) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
-#include <experimental/regex>
+#if defined(TEST_129) && __cplusplus >= 201103L
+#include <experimental/propagate_const>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_130
-#if defined(TEST_130) && __cplusplus >= 201103L
-#include <experimental/set>
+#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
+#include <experimental/regex>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_131
 #if defined(TEST_131) && __cplusplus >= 201103L
-#include <experimental/simd>
+#include <experimental/set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_132
 #if defined(TEST_132) && __cplusplus >= 201103L
-#include <experimental/string>
+#include <experimental/simd>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_133
 #if defined(TEST_133) && __cplusplus >= 201103L
-#include <experimental/type_traits>
+#include <experimental/string>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_134
 #if defined(TEST_134) && __cplusplus >= 201103L
-#include <experimental/unordered_map>
+#include <experimental/type_traits>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_135
 #if defined(TEST_135) && __cplusplus >= 201103L
-#include <experimental/unordered_set>
+#include <experimental/unordered_map>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_136
 #if defined(TEST_136) && __cplusplus >= 201103L
-#include <experimental/utility>
+#include <experimental/unordered_set>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_137
 #if defined(TEST_137) && __cplusplus >= 201103L
-#include <experimental/vector>
+#include <experimental/utility>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_138
-#if defined(TEST_138)
-#include <ext/hash_map>
+#if defined(TEST_138) && __cplusplus >= 201103L
+#include <experimental/vector>
 #endif
 // RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_139
 #if defined(TEST_139)
+#include <ext/hash_map>
+#endif
+// RUN: %{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_140
+#if defined(TEST_140)
 #include <ext/hash_set>
 #endif
 // GENERATED-MARKER

diff  --git a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
index 162d230b67836..9843b87ad2906 100644
--- a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp
@@ -257,6 +257,7 @@ END-SCRIPT
 #include <map>
 #include <math.h>
 #include <memory>
+#include <memory_resource>
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <mutex>
 #endif

diff  --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
index c4604a7d5da66..5e37fa2488341 100644
--- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
+++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
@@ -135,6 +135,7 @@ END-SCRIPT
 #include <map>
 #include <math.h>
 #include <memory>
+#include <memory_resource>
 #if !defined(_LIBCPP_HAS_NO_THREADS)
 #   include <mutex>
 #endif

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index ca11853965f80..f30a848ae7fca 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -445,6 +445,12 @@ END-SCRIPT
 #include <__memory/uses_allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory/uses_allocator.h'}}
 #include <__memory/uses_allocator_construction.h> // expected-error@*:* {{use of private header from outside its module: '__memory/uses_allocator_construction.h'}}
 #include <__memory/voidify.h> // expected-error@*:* {{use of private header from outside its module: '__memory/voidify.h'}}
+#include <__memory_resource/memory_resource.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/memory_resource.h'}}
+#include <__memory_resource/monotonic_buffer_resource.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/monotonic_buffer_resource.h'}}
+#include <__memory_resource/polymorphic_allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/polymorphic_allocator.h'}}
+#include <__memory_resource/pool_options.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/pool_options.h'}}
+#include <__memory_resource/synchronized_pool_resource.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/synchronized_pool_resource.h'}}
+#include <__memory_resource/unsynchronized_pool_resource.h> // expected-error@*:* {{use of private header from outside its module: '__memory_resource/unsynchronized_pool_resource.h'}}
 #include <__mutex_base> // expected-error@*:* {{use of private header from outside its module: '__mutex_base'}}
 #include <__node_handle> // expected-error@*:* {{use of private header from outside its module: '__node_handle'}}
 #include <__numeric/accumulate.h> // expected-error@*:* {{use of private header from outside its module: '__numeric/accumulate.h'}}

diff  --git a/libcxx/test/libcxx/transitive_includes.sh.cpp b/libcxx/test/libcxx/transitive_includes.sh.cpp
index c23e24df9396b..edb696fb8da54 100644
--- a/libcxx/test/libcxx/transitive_includes.sh.cpp
+++ b/libcxx/test/libcxx/transitive_includes.sh.cpp
@@ -52,7 +52,7 @@ import re
 # the file and run this test.
 # Note that this needs to be done for all supported language versions of libc++:
 # for std in c++03 c++11 c++14 c++17 c++20 c++2b; do <build>/bin/llvm-lit --param std=$std ${path_to_this_file}; done
-regenerate_expected_results = False
+regenerate_expected_results = True
 # Used because the sequence of tokens RUN : can't appear anywhere or it'll confuse Lit.
 RUN = "RUN"
 
@@ -328,234 +328,237 @@ END-SCRIPT
 #if defined(TEST_70)
 #include <memory>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_71 2> %t/header.mutex
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_71 2> %t/header.memory_resource
 #if defined(TEST_71)
-#include <mutex>
+#include <memory_resource>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_72 2> %t/header.new
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_72 2> %t/header.mutex
 #if defined(TEST_72)
-#include <new>
+#include <mutex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_73 2> %t/header.numbers
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_73 2> %t/header.new
 #if defined(TEST_73)
-#include <numbers>
+#include <new>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_74 2> %t/header.numeric
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_74 2> %t/header.numbers
 #if defined(TEST_74)
-#include <numeric>
+#include <numbers>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_75 2> %t/header.optional
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_75 2> %t/header.numeric
 #if defined(TEST_75)
-#include <optional>
+#include <numeric>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_76 2> %t/header.ostream
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_76 2> %t/header.optional
 #if defined(TEST_76)
-#include <ostream>
+#include <optional>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_77 2> %t/header.queue
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_77 2> %t/header.ostream
 #if defined(TEST_77)
-#include <queue>
+#include <ostream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_78 2> %t/header.random
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_78 2> %t/header.queue
 #if defined(TEST_78)
-#include <random>
+#include <queue>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_79 2> %t/header.ranges
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_79 2> %t/header.random
 #if defined(TEST_79)
-#include <ranges>
+#include <random>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_80 2> %t/header.ratio
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_80 2> %t/header.ranges
 #if defined(TEST_80)
-#include <ratio>
+#include <ranges>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_81 2> %t/header.regex
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_81 2> %t/header.ratio
 #if defined(TEST_81)
-#include <regex>
+#include <ratio>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_82 2> %t/header.scoped_allocator
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_82 2> %t/header.regex
 #if defined(TEST_82)
-#include <scoped_allocator>
+#include <regex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_83 2> %t/header.semaphore
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_83 2> %t/header.scoped_allocator
 #if defined(TEST_83)
-#include <semaphore>
+#include <scoped_allocator>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_84 2> %t/header.set
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_84 2> %t/header.semaphore
 #if defined(TEST_84)
+#include <semaphore>
+#endif
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_85 2> %t/header.set
+#if defined(TEST_85)
 #include <set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_86 2> %t/header.shared_mutex
-#if defined(TEST_86)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_87 2> %t/header.shared_mutex
+#if defined(TEST_87)
 #include <shared_mutex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_87 2> %t/header.span
-#if defined(TEST_87)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_88 2> %t/header.span
+#if defined(TEST_88)
 #include <span>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_88 2> %t/header.sstream
-#if defined(TEST_88)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_89 2> %t/header.sstream
+#if defined(TEST_89)
 #include <sstream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_89 2> %t/header.stack
-#if defined(TEST_89)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_90 2> %t/header.stack
+#if defined(TEST_90)
 #include <stack>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_93 2> %t/header.stdexcept
-#if defined(TEST_93)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_94 2> %t/header.stdexcept
+#if defined(TEST_94)
 #include <stdexcept>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_97 2> %t/header.streambuf
-#if defined(TEST_97)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_98 2> %t/header.streambuf
+#if defined(TEST_98)
 #include <streambuf>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_98 2> %t/header.string
-#if defined(TEST_98)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_99 2> %t/header.string
+#if defined(TEST_99)
 #include <string>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_100 2> %t/header.string_view
-#if defined(TEST_100)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_101 2> %t/header.string_view
+#if defined(TEST_101)
 #include <string_view>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_101 2> %t/header.strstream
-#if defined(TEST_101)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_102 2> %t/header.strstream
+#if defined(TEST_102)
 #include <strstream>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_102 2> %t/header.system_error
-#if defined(TEST_102)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_103 2> %t/header.system_error
+#if defined(TEST_103)
 #include <system_error>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_104 2> %t/header.thread
-#if defined(TEST_104)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_105 2> %t/header.thread
+#if defined(TEST_105)
 #include <thread>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_105 2> %t/header.tuple
-#if defined(TEST_105)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_106 2> %t/header.tuple
+#if defined(TEST_106)
 #include <tuple>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_106 2> %t/header.type_traits
-#if defined(TEST_106)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_107 2> %t/header.type_traits
+#if defined(TEST_107)
 #include <type_traits>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_107 2> %t/header.typeindex
-#if defined(TEST_107)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_108 2> %t/header.typeindex
+#if defined(TEST_108)
 #include <typeindex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_108 2> %t/header.typeinfo
-#if defined(TEST_108)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_109 2> %t/header.typeinfo
+#if defined(TEST_109)
 #include <typeinfo>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_110 2> %t/header.unordered_map
-#if defined(TEST_110)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_111 2> %t/header.unordered_map
+#if defined(TEST_111)
 #include <unordered_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_111 2> %t/header.unordered_set
-#if defined(TEST_111)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_112 2> %t/header.unordered_set
+#if defined(TEST_112)
 #include <unordered_set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_112 2> %t/header.utility
-#if defined(TEST_112)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_113 2> %t/header.utility
+#if defined(TEST_113)
 #include <utility>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_113 2> %t/header.valarray
-#if defined(TEST_113)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_114 2> %t/header.valarray
+#if defined(TEST_114)
 #include <valarray>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_114 2> %t/header.variant
-#if defined(TEST_114)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_115 2> %t/header.variant
+#if defined(TEST_115)
 #include <variant>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_115 2> %t/header.vector
-#if defined(TEST_115)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_116 2> %t/header.vector
+#if defined(TEST_116)
 #include <vector>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_116 2> %t/header.version
-#if defined(TEST_116)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_117 2> %t/header.version
+#if defined(TEST_117)
 #include <version>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_119 2> %t/header.experimental_algorithm
-#if defined(TEST_119)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_120 2> %t/header.experimental_algorithm
+#if defined(TEST_120)
 #include <experimental/algorithm>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_120 2> %t/header.experimental_coroutine
-#if defined(TEST_120)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_121 2> %t/header.experimental_coroutine
+#if defined(TEST_121)
 #include <experimental/coroutine>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_121 2> %t/header.experimental_deque
-#if defined(TEST_121)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_122 2> %t/header.experimental_deque
+#if defined(TEST_122)
 #include <experimental/deque>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_122 2> %t/header.experimental_forward_list
-#if defined(TEST_122)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_123 2> %t/header.experimental_forward_list
+#if defined(TEST_123)
 #include <experimental/forward_list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_123 2> %t/header.experimental_functional
-#if defined(TEST_123)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_124 2> %t/header.experimental_functional
+#if defined(TEST_124)
 #include <experimental/functional>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_124 2> %t/header.experimental_iterator
-#if defined(TEST_124)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_125 2> %t/header.experimental_iterator
+#if defined(TEST_125)
 #include <experimental/iterator>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_125 2> %t/header.experimental_list
-#if defined(TEST_125)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_126 2> %t/header.experimental_list
+#if defined(TEST_126)
 #include <experimental/list>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_126 2> %t/header.experimental_map
-#if defined(TEST_126)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_127 2> %t/header.experimental_map
+#if defined(TEST_127)
 #include <experimental/map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_127 2> %t/header.experimental_memory_resource
-#if defined(TEST_127)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_128 2> %t/header.experimental_memory_resource
+#if defined(TEST_128)
 #include <experimental/memory_resource>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_128 2> %t/header.experimental_propagate_const
-#if defined(TEST_128)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_129 2> %t/header.experimental_propagate_const
+#if defined(TEST_129)
 #include <experimental/propagate_const>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_129 2> %t/header.experimental_regex
-#if defined(TEST_129)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_130 2> %t/header.experimental_regex
+#if defined(TEST_130)
 #include <experimental/regex>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_130 2> %t/header.experimental_set
-#if defined(TEST_130)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_131 2> %t/header.experimental_set
+#if defined(TEST_131)
 #include <experimental/set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_131 2> %t/header.experimental_simd
-#if defined(TEST_131)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_132 2> %t/header.experimental_simd
+#if defined(TEST_132)
 #include <experimental/simd>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_132 2> %t/header.experimental_string
-#if defined(TEST_132)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_133 2> %t/header.experimental_string
+#if defined(TEST_133)
 #include <experimental/string>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_133 2> %t/header.experimental_type_traits
-#if defined(TEST_133)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_134 2> %t/header.experimental_type_traits
+#if defined(TEST_134)
 #include <experimental/type_traits>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_134 2> %t/header.experimental_unordered_map
-#if defined(TEST_134)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_135 2> %t/header.experimental_unordered_map
+#if defined(TEST_135)
 #include <experimental/unordered_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_135 2> %t/header.experimental_unordered_set
-#if defined(TEST_135)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_136 2> %t/header.experimental_unordered_set
+#if defined(TEST_136)
 #include <experimental/unordered_set>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_136 2> %t/header.experimental_utility
-#if defined(TEST_136)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_137 2> %t/header.experimental_utility
+#if defined(TEST_137)
 #include <experimental/utility>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_137 2> %t/header.experimental_vector
-#if defined(TEST_137)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_138 2> %t/header.experimental_vector
+#if defined(TEST_138)
 #include <experimental/vector>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_138 2> %t/header.ext_hash_map
-#if defined(TEST_138)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_139 2> %t/header.ext_hash_map
+#if defined(TEST_139)
 #include <ext/hash_map>
 #endif
-// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_139 2> %t/header.ext_hash_set
-#if defined(TEST_139)
+// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes -fsyntax-only -DTEST_140 2> %t/header.ext_hash_set
+#if defined(TEST_140)
 #include <ext/hash_set>
 #endif
-// RUN: %{python} %S/transitive_includes_to_csv.py %t > %t/transitive_includes.csv
-// RUN: 
diff  -w %S/transitive_includes/%{cxx_std}.csv %t/transitive_includes.csv
+// RUN: %{python} %S/transitive_includes_to_csv.py %t > %S/transitive_includes/%{cxx_std}.csv
 // GENERATED-MARKER

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index c5a6fd9e6e99a..1bdb9cb7e7f71 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -191,6 +191,7 @@ deque iterator
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -362,6 +363,7 @@ forward_list iterator
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -485,6 +487,7 @@ list iterator
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -544,6 +547,14 @@ memory type_traits
 memory typeinfo
 memory utility
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -711,6 +722,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex version
@@ -762,6 +774,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string typeinfo
 string utility
@@ -867,6 +880,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -917,6 +931,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector utility

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index e416b4ac1ba0d..b8b01397da9a0 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -191,6 +191,7 @@ deque iterator
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -362,6 +363,7 @@ forward_list iterator
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -485,6 +487,7 @@ list iterator
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -544,6 +547,14 @@ memory type_traits
 memory typeinfo
 memory utility
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -712,6 +723,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex version
@@ -763,6 +775,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string typeinfo
 string utility
@@ -868,6 +881,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -918,6 +932,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector utility

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 5a9fe6a000fba..0a9ece5a121a9 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -191,6 +191,7 @@ deque iterator
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -364,6 +365,7 @@ forward_list iterator
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -487,6 +489,7 @@ list iterator
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -546,6 +549,14 @@ memory type_traits
 memory typeinfo
 memory utility
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -714,6 +725,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex ctime
@@ -771,6 +783,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string typeinfo
 string utility
@@ -876,6 +889,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -926,6 +940,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector utility

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 5a9fe6a000fba..0a9ece5a121a9 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -191,6 +191,7 @@ deque iterator
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -364,6 +365,7 @@ forward_list iterator
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -487,6 +489,7 @@ list iterator
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -546,6 +549,14 @@ memory type_traits
 memory typeinfo
 memory utility
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -714,6 +725,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex ctime
@@ -771,6 +783,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string typeinfo
 string utility
@@ -876,6 +889,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -926,6 +940,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector utility

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index b58d3d00ed4be..4589f7b98b2be 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -204,6 +204,7 @@ deque iterator
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -377,6 +378,7 @@ forward_list iterator
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -499,6 +501,7 @@ list iterator
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -558,6 +561,14 @@ memory type_traits
 memory typeinfo
 memory utility
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -725,6 +736,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex ctime
@@ -782,6 +794,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string typeinfo
 string utility
@@ -886,6 +899,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -936,6 +950,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector utility

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx2b.csv b/libcxx/test/libcxx/transitive_includes/cxx2b.csv
index 4561b39e237c5..e4e82d3cf4319 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx2b.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx2b.csv
@@ -181,6 +181,7 @@ deque iosfwd
 deque limits
 deque new
 deque stdexcept
+deque tuple
 deque type_traits
 deque typeinfo
 deque version
@@ -317,6 +318,7 @@ forward_list iosfwd
 forward_list limits
 forward_list new
 forward_list stdexcept
+forward_list tuple
 forward_list type_traits
 forward_list typeinfo
 forward_list version
@@ -431,6 +433,7 @@ list iosfwd
 list limits
 list new
 list stdexcept
+list tuple
 list type_traits
 list typeinfo
 list version
@@ -483,6 +486,14 @@ memory tuple
 memory type_traits
 memory typeinfo
 memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource limits
+memory_resource mutex
+memory_resource new
+memory_resource stdexcept
+memory_resource tuple
+memory_resource version
 mutex atomic
 mutex concepts
 mutex cstddef
@@ -621,6 +632,7 @@ set limits
 set new
 set optional
 set stdexcept
+set tuple
 set type_traits
 set version
 shared_mutex ctime
@@ -672,6 +684,7 @@ string limits
 string new
 string stdexcept
 string string_view
+string tuple
 string type_traits
 string version
 string_view compare
@@ -756,6 +769,7 @@ unordered_set limits
 unordered_set new
 unordered_set optional
 unordered_set stdexcept
+unordered_set tuple
 unordered_set type_traits
 unordered_set version
 utility compare
@@ -800,6 +814,7 @@ vector iosfwd
 vector limits
 vector new
 vector stdexcept
+vector tuple
 vector type_traits
 vector typeinfo
 vector version

diff  --git a/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp b/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
index 7ed8e30771d89..92c9e927a546e 100644
--- a/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
+++ b/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++03, c++11, c++14, c++17
 
 // #include <memory>
 

diff  --git a/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp b/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
new file mode 100644
index 0000000000000..c571297eb5b27
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<T1, T2>*, piecewise_construct_t
+//                                          tuple<Args1...> x, tuple<Args2...>)
+
+// The stardard specifiers a tranformation to uses-allocator construction as
+// follows:
+//  - If uses_allocator_v<T1,memory_resource*> is false and
+//      is_constructible_v<T,Args1...> is true, then xprime is x.
+//  - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+//      is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true,
+//      then xprime is
+//      tuple_cat(make_tuple(allocator_arg, this->resource()), std::move(x)).
+//  - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+//      is_constructible_v<T1,Args1...,memory_resource*> is true, then xprime is
+//      tuple_cat(std::move(x), make_tuple(this->resource())).
+//  - Otherwise the program is ill formed.
+//
+// The use of "xprime = tuple_cat(..., std::move(x), ...)" causes all of the
+// objects in 'x' to be copied into 'xprime'. If 'x' contains any types which
+// are stored by value this causes an unessary copy to occur. To prevent this
+//  libc++ changes this call into
+// "xprime = forward_as_tuple(..., std::get<Idx>(std::move(x))..., ...)".
+// 'xprime' contains references to the values in 'x' instead of copying them.
+
+// This test checks the number of copies incurred to the elements in
+// 'tuple<Args1...>' and 'tuple<Args2...>'.
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "test_std_memory_resource.h"
+
+template <class T>
+struct TestHarness {
+  TestResource R;
+  std::pmr::memory_resource* M         = &R;
+  std::pmr::polymorphic_allocator<T> A = M;
+  bool constructed                     = false;
+  T* ptr;
+
+  TestHarness() : ptr(A.allocate(1)) {}
+
+  template <class... Args>
+  void construct(Args&&... args) {
+    A.construct(ptr, std::forward<Args>(args)...);
+    constructed = true;
+  }
+
+  ~TestHarness() {
+    if (constructed)
+      A.destroy(ptr);
+    A.deallocate(ptr, 1);
+  }
+};
+
+struct CountCopies {
+  int count;
+  CountCopies() : count(0) {}
+  CountCopies(CountCopies const& o) : count(o.count + 1) {}
+};
+
+struct CountCopiesAllocV1 {
+  typedef std::pmr::polymorphic_allocator<char> allocator_type;
+  std::pmr::memory_resource* alloc;
+  int count;
+  CountCopiesAllocV1() : alloc(nullptr), count(0) {}
+  CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a, CountCopiesAllocV1 const& o)
+      : alloc(a.resource()), count(o.count + 1) {}
+
+  CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {}
+};
+
+struct CountCopiesAllocV2 {
+  typedef std::pmr::polymorphic_allocator<char> allocator_type;
+  std::pmr::memory_resource* alloc;
+  int count;
+  CountCopiesAllocV2() : alloc(nullptr), count(0) {}
+  CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a) : alloc(a.resource()), count(o.count + 1) {}
+
+  CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {}
+};
+
+int main(int, char**) {
+  {
+    using T = CountCopies;
+    using U = CountCopiesAllocV1;
+    using P = std::pair<T, U>;
+
+    std::tuple<T> t1;
+    std::tuple<U> t2;
+
+    TestHarness<P> h;
+    h.construct(std::piecewise_construct, t1, t2);
+    P const& p = *h.ptr;
+    assert(p.first.count == 2);
+    assert(p.second.count == 2);
+    assert(p.second.alloc == h.M);
+  }
+  {
+    using T = CountCopiesAllocV1;
+    using U = CountCopiesAllocV2;
+    using P = std::pair<T, U>;
+
+    std::tuple<T> t1;
+    std::tuple<U> t2;
+
+    TestHarness<P> h;
+    h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+    P const& p = *h.ptr;
+    assert(p.first.count == 2);
+    assert(p.first.alloc == h.M);
+    assert(p.second.count == 2);
+    assert(p.second.alloc == h.M);
+  }
+  {
+    using T = CountCopiesAllocV2;
+    using U = CountCopiesAllocV1;
+    using P = std::pair<T, U>;
+
+    std::tuple<T> t1;
+    std::tuple<U> t2;
+
+    TestHarness<P> h;
+    h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+    P const& p = *h.ptr;
+    assert(p.first.count == 2);
+    assert(p.first.alloc == h.M);
+    assert(p.second.count == 2);
+    assert(p.second.alloc == h.M);
+  }
+  {
+    using T = CountCopiesAllocV2;
+    using U = CountCopies;
+    using P = std::pair<T, U>;
+
+    std::tuple<T> t1;
+    std::tuple<U> t2;
+
+    TestHarness<P> h;
+    h.construct(std::piecewise_construct, t1, t2);
+    P const& p = *h.ptr;
+    assert(p.first.count == 2);
+    assert(p.first.alloc == h.M);
+    assert(p.second.count == 2);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/debug.deallocate.pass.cpp b/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/debug.deallocate.pass.cpp
new file mode 100644
index 0000000000000..3602ba9e00d10
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/debug.deallocate.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: !libcpp-has-debug-mode, c++03, c++11, c++14
+// REQUIRES: has-unix-headers
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+int AssertCount = 0;
+
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  using Alloc  = std::pmr::polymorphic_allocator<int>;
+  using Traits = std::allocator_traits<Alloc>;
+  NullResource R;
+  Alloc a(&R);
+  const std::size_t maxSize = Traits::max_size(a);
+
+  a.deallocate(nullptr, maxSize); // no assertion
+  TEST_LIBCPP_ASSERT_FAILURE(a.deallocate(nullptr, maxSize + 1), "deallocate called for size which exceeds max_size()");
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
new file mode 100644
index 0000000000000..91185e349bff6
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  std::pmr::monotonic_buffer_resource mono;
+
+  for (int i = 0; i < 100; ++i) {
+    mono.allocate(1);
+    assert(globalMemCounter.last_new_size < 1000000000);
+    mono.release();
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
new file mode 100644
index 0000000000000..84f11f119b7d9
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
@@ -0,0 +1,211 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// struct pool_options
+// class unsynchronized_pool_resource
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <cstdint> // SIZE_MAX, UINT32_MAX
+
+static void assert_options(const std::pmr::pool_options& actual, const std::pmr::pool_options& expected) {
+  assert(actual.max_blocks_per_chunk == expected.max_blocks_per_chunk);
+  assert(actual.largest_required_pool_block == expected.largest_required_pool_block);
+}
+
+void test_pool_options(std::pmr::pool_options initial, std::pmr::pool_options expected) {
+  std::pmr::unsynchronized_pool_resource mr(initial, std::pmr::null_memory_resource());
+  assert_options(mr.options(), expected);
+
+  std::pmr::synchronized_pool_resource mr2(initial, std::pmr::null_memory_resource());
+  assert_options(mr2.options(), expected);
+}
+
+int main(int, char**) {
+  test_pool_options({0, 0}, {1048576, 1048576});
+  test_pool_options({0, 1}, {1048576, 8});
+  test_pool_options({0, 2}, {1048576, 8});
+  test_pool_options({0, 4}, {1048576, 8});
+  test_pool_options({0, 8}, {1048576, 8});
+  test_pool_options({0, 16}, {1048576, 16});
+  test_pool_options({0, 32}, {1048576, 32});
+  test_pool_options({0, 1024}, {1048576, 1024});
+  test_pool_options({0, 1048576}, {1048576, 1048576});
+  test_pool_options({0, 2097152}, {1048576, 2097152});
+  test_pool_options({0, 1073741824}, {1048576, 1073741824});
+  test_pool_options({0, 2147483648}, {1048576, 1073741824});
+  test_pool_options({1, 0}, {16, 1048576});
+  test_pool_options({1, 1}, {16, 8});
+  test_pool_options({1, 2}, {16, 8});
+  test_pool_options({1, 4}, {16, 8});
+  test_pool_options({1, 8}, {16, 8});
+  test_pool_options({1, 16}, {16, 16});
+  test_pool_options({1, 32}, {16, 32});
+  test_pool_options({1, 1024}, {16, 1024});
+  test_pool_options({1, 1048576}, {16, 1048576});
+  test_pool_options({1, 2097152}, {16, 2097152});
+  test_pool_options({1, 1073741824}, {16, 1073741824});
+  test_pool_options({1, 2147483648}, {16, 1073741824});
+  test_pool_options({2, 0}, {16, 1048576});
+  test_pool_options({2, 1}, {16, 8});
+  test_pool_options({2, 2}, {16, 8});
+  test_pool_options({2, 4}, {16, 8});
+  test_pool_options({2, 8}, {16, 8});
+  test_pool_options({2, 16}, {16, 16});
+  test_pool_options({2, 32}, {16, 32});
+  test_pool_options({2, 1024}, {16, 1024});
+  test_pool_options({2, 1048576}, {16, 1048576});
+  test_pool_options({2, 2097152}, {16, 2097152});
+  test_pool_options({2, 1073741824}, {16, 1073741824});
+  test_pool_options({2, 2147483648}, {16, 1073741824});
+  test_pool_options({4, 0}, {16, 1048576});
+  test_pool_options({4, 1}, {16, 8});
+  test_pool_options({4, 2}, {16, 8});
+  test_pool_options({4, 4}, {16, 8});
+  test_pool_options({4, 8}, {16, 8});
+  test_pool_options({4, 16}, {16, 16});
+  test_pool_options({4, 32}, {16, 32});
+  test_pool_options({4, 1024}, {16, 1024});
+  test_pool_options({4, 1048576}, {16, 1048576});
+  test_pool_options({4, 2097152}, {16, 2097152});
+  test_pool_options({4, 1073741824}, {16, 1073741824});
+  test_pool_options({4, 2147483648}, {16, 1073741824});
+  test_pool_options({8, 0}, {16, 1048576});
+  test_pool_options({8, 1}, {16, 8});
+  test_pool_options({8, 2}, {16, 8});
+  test_pool_options({8, 4}, {16, 8});
+  test_pool_options({8, 8}, {16, 8});
+  test_pool_options({8, 16}, {16, 16});
+  test_pool_options({8, 32}, {16, 32});
+  test_pool_options({8, 1024}, {16, 1024});
+  test_pool_options({8, 1048576}, {16, 1048576});
+  test_pool_options({8, 2097152}, {16, 2097152});
+  test_pool_options({8, 1073741824}, {16, 1073741824});
+  test_pool_options({8, 2147483648}, {16, 1073741824});
+  test_pool_options({16, 0}, {16, 1048576});
+  test_pool_options({16, 1}, {16, 8});
+  test_pool_options({16, 2}, {16, 8});
+  test_pool_options({16, 4}, {16, 8});
+  test_pool_options({16, 8}, {16, 8});
+  test_pool_options({16, 16}, {16, 16});
+  test_pool_options({16, 32}, {16, 32});
+  test_pool_options({16, 1024}, {16, 1024});
+  test_pool_options({16, 1048576}, {16, 1048576});
+  test_pool_options({16, 2097152}, {16, 2097152});
+  test_pool_options({16, 1073741824}, {16, 1073741824});
+  test_pool_options({16, 2147483648}, {16, 1073741824});
+  test_pool_options({32, 0}, {32, 1048576});
+  test_pool_options({32, 1}, {32, 8});
+  test_pool_options({32, 2}, {32, 8});
+  test_pool_options({32, 4}, {32, 8});
+  test_pool_options({32, 8}, {32, 8});
+  test_pool_options({32, 16}, {32, 16});
+  test_pool_options({32, 32}, {32, 32});
+  test_pool_options({32, 1024}, {32, 1024});
+  test_pool_options({32, 1048576}, {32, 1048576});
+  test_pool_options({32, 2097152}, {32, 2097152});
+  test_pool_options({32, 1073741824}, {32, 1073741824});
+  test_pool_options({32, 2147483648}, {32, 1073741824});
+  test_pool_options({1024, 0}, {1024, 1048576});
+  test_pool_options({1024, 1}, {1024, 8});
+  test_pool_options({1024, 2}, {1024, 8});
+  test_pool_options({1024, 4}, {1024, 8});
+  test_pool_options({1024, 8}, {1024, 8});
+  test_pool_options({1024, 16}, {1024, 16});
+  test_pool_options({1024, 32}, {1024, 32});
+  test_pool_options({1024, 1024}, {1024, 1024});
+  test_pool_options({1024, 1048576}, {1024, 1048576});
+  test_pool_options({1024, 2097152}, {1024, 2097152});
+  test_pool_options({1024, 1073741824}, {1024, 1073741824});
+  test_pool_options({1024, 2147483648}, {1024, 1073741824});
+  test_pool_options({1048576, 0}, {1048576, 1048576});
+  test_pool_options({1048576, 1}, {1048576, 8});
+  test_pool_options({1048576, 2}, {1048576, 8});
+  test_pool_options({1048576, 4}, {1048576, 8});
+  test_pool_options({1048576, 8}, {1048576, 8});
+  test_pool_options({1048576, 16}, {1048576, 16});
+  test_pool_options({1048576, 32}, {1048576, 32});
+  test_pool_options({1048576, 1024}, {1048576, 1024});
+  test_pool_options({1048576, 1048576}, {1048576, 1048576});
+  test_pool_options({1048576, 2097152}, {1048576, 2097152});
+  test_pool_options({1048576, 1073741824}, {1048576, 1073741824});
+  test_pool_options({1048576, 2147483648}, {1048576, 1073741824});
+  test_pool_options({2097152, 0}, {1048576, 1048576});
+  test_pool_options({2097152, 1}, {1048576, 8});
+  test_pool_options({2097152, 2}, {1048576, 8});
+  test_pool_options({2097152, 4}, {1048576, 8});
+  test_pool_options({2097152, 8}, {1048576, 8});
+  test_pool_options({2097152, 16}, {1048576, 16});
+  test_pool_options({2097152, 32}, {1048576, 32});
+  test_pool_options({2097152, 1024}, {1048576, 1024});
+  test_pool_options({2097152, 1048576}, {1048576, 1048576});
+  test_pool_options({2097152, 2097152}, {1048576, 2097152});
+  test_pool_options({2097152, 1073741824}, {1048576, 1073741824});
+  test_pool_options({2097152, 2147483648}, {1048576, 1073741824});
+  test_pool_options({1073741824, 0}, {1048576, 1048576});
+  test_pool_options({1073741824, 1}, {1048576, 8});
+  test_pool_options({1073741824, 2}, {1048576, 8});
+  test_pool_options({1073741824, 4}, {1048576, 8});
+  test_pool_options({1073741824, 8}, {1048576, 8});
+  test_pool_options({1073741824, 16}, {1048576, 16});
+  test_pool_options({1073741824, 32}, {1048576, 32});
+  test_pool_options({1073741824, 1024}, {1048576, 1024});
+  test_pool_options({1073741824, 1048576}, {1048576, 1048576});
+  test_pool_options({1073741824, 2097152}, {1048576, 2097152});
+  test_pool_options({1073741824, 1073741824}, {1048576, 1073741824});
+  test_pool_options({1073741824, 2147483648}, {1048576, 1073741824});
+  test_pool_options({2147483648, 0}, {1048576, 1048576});
+  test_pool_options({2147483648, 1}, {1048576, 8});
+  test_pool_options({2147483648, 2}, {1048576, 8});
+  test_pool_options({2147483648, 4}, {1048576, 8});
+  test_pool_options({2147483648, 8}, {1048576, 8});
+  test_pool_options({2147483648, 16}, {1048576, 16});
+  test_pool_options({2147483648, 32}, {1048576, 32});
+  test_pool_options({2147483648, 1024}, {1048576, 1024});
+  test_pool_options({2147483648, 1048576}, {1048576, 1048576});
+  test_pool_options({2147483648, 2097152}, {1048576, 2097152});
+  test_pool_options({2147483648, 1073741824}, {1048576, 1073741824});
+  test_pool_options({2147483648, 2147483648}, {1048576, 1073741824});
+
+#if SIZE_MAX > UINT32_MAX
+  test_pool_options({0, 8589934592}, {1048576, 1073741824});
+  test_pool_options({1, 8589934592}, {16, 1073741824});
+  test_pool_options({2, 8589934592}, {16, 1073741824});
+  test_pool_options({4, 8589934592}, {16, 1073741824});
+  test_pool_options({8, 8589934592}, {16, 1073741824});
+  test_pool_options({16, 8589934592}, {16, 1073741824});
+  test_pool_options({32, 8589934592}, {32, 1073741824});
+  test_pool_options({1024, 8589934592}, {1024, 1073741824});
+  test_pool_options({1048576, 8589934592}, {1048576, 1073741824});
+  test_pool_options({2097152, 8589934592}, {1048576, 1073741824});
+  test_pool_options({1073741824, 8589934592}, {1048576, 1073741824});
+  test_pool_options({2147483648, 8589934592}, {1048576, 1073741824});
+  test_pool_options({8589934592, 0}, {1048576, 1048576});
+  test_pool_options({8589934592, 1}, {1048576, 8});
+  test_pool_options({8589934592, 2}, {1048576, 8});
+  test_pool_options({8589934592, 4}, {1048576, 8});
+  test_pool_options({8589934592, 8}, {1048576, 8});
+  test_pool_options({8589934592, 16}, {1048576, 16});
+  test_pool_options({8589934592, 32}, {1048576, 32});
+  test_pool_options({8589934592, 1024}, {1048576, 1024});
+  test_pool_options({8589934592, 1048576}, {1048576, 1048576});
+  test_pool_options({8589934592, 2097152}, {1048576, 2097152});
+  test_pool_options({8589934592, 1073741824}, {1048576, 1073741824});
+  test_pool_options({8589934592, 2147483648}, {1048576, 1073741824});
+  test_pool_options({8589934592, 8589934592}, {1048576, 1073741824});
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.compile.pass.cpp
new file mode 100644
index 0000000000000..53f5e5c38210a
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.compile.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <memory_resource>
+
+// Test the feature test macros defined by <memory_resource>
+
+/*  Constant                           Value
+    __cpp_lib_memory_resource          201603L [C++17]
+    __cpp_lib_polymorphic_allocator    201902L [C++20]
+*/
+
+#include <memory_resource>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_polymorphic_allocator
+#   error "__cpp_lib_polymorphic_allocator should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_polymorphic_allocator
+#   error "__cpp_lib_polymorphic_allocator should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++17"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_polymorphic_allocator
+#   error "__cpp_lib_polymorphic_allocator should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++20"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++20"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+#   ifndef __cpp_lib_polymorphic_allocator
+#     error "__cpp_lib_polymorphic_allocator should be defined in c++20"
+#   endif
+#   if __cpp_lib_polymorphic_allocator != 201902L
+#     error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++20"
+#   endif
+# else // _LIBCPP_VERSION
+#   ifdef __cpp_lib_polymorphic_allocator
+#     error "__cpp_lib_polymorphic_allocator should not be defined because it is unimplemented in libc++!"
+#   endif
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++2b"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++2b"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+#   ifndef __cpp_lib_polymorphic_allocator
+#     error "__cpp_lib_polymorphic_allocator should be defined in c++2b"
+#   endif
+#   if __cpp_lib_polymorphic_allocator != 201902L
+#     error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++2b"
+#   endif
+# else // _LIBCPP_VERSION
+#   ifdef __cpp_lib_polymorphic_allocator
+#     error "__cpp_lib_polymorphic_allocator should not be defined because it is unimplemented in libc++!"
+#   endif
+# endif
+
+#endif // TEST_STD_VER > 20
+

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp
new file mode 100644
index 0000000000000..68c47df608af5
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <memory_resource>
+
+// Test the feature test macros defined by <memory_resource>
+
+/*  Constant                     Value
+    __cpp_lib_memory_resource    201603L [C++17]
+*/
+
+#include <memory_resource>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++17"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++17"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++20"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++20"
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++2b"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++2b"
+# endif
+
+#endif // TEST_STD_VER > 20
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d3e84d04183a8..b766f3df131b0 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -2030,17 +2030,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should be defined in c++17"
-#   endif
-#   if __cpp_lib_memory_resource != 201603L
-#     error "__cpp_lib_memory_resource should have the value 201603L in c++17"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++17"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++17"
 # endif
 
 # ifdef __cpp_lib_move_only_function
@@ -3140,17 +3134,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should be defined in c++20"
-#   endif
-#   if __cpp_lib_memory_resource != 201603L
-#     error "__cpp_lib_memory_resource should have the value 201603L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++20"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++20"
 # endif
 
 # ifdef __cpp_lib_move_only_function
@@ -4397,17 +4385,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should be defined in c++2b"
-#   endif
-#   if __cpp_lib_memory_resource != 201603L
-#     error "__cpp_lib_memory_resource should have the value 201603L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_memory_resource
-#     error "__cpp_lib_memory_resource should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_memory_resource
+#   error "__cpp_lib_memory_resource should be defined in c++2b"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+#   error "__cpp_lib_memory_resource should have the value 201603L in c++2b"
 # endif
 
 # if !defined(_LIBCPP_VERSION)

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/assign.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/assign.pass.cpp
new file mode 100644
index 0000000000000..79777940038e5
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/assign.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator operator=(polymorphic_allocator const &) = delete
+
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> T;
+  static_assert(!std::is_copy_assignable<T>::value, "");
+  static_assert(!std::is_move_assignable<T>::value, "");
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/copy.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/copy.pass.cpp
new file mode 100644
index 0000000000000..2d1b4296cb607
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/copy.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator const &);
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A1;
+  {
+    static_assert(std::is_copy_constructible<A1>::value, "");
+    static_assert(std::is_move_constructible<A1>::value, "");
+  }
+  // copy
+  {
+    A1 const a((std::pmr::memory_resource*)42);
+    A1 const a2(a);
+    assert(a.resource() == a2.resource());
+  }
+  // move
+  {
+    A1 a((std::pmr::memory_resource*)42);
+    A1 a2(std::move(a));
+    assert(a.resource() == a2.resource());
+    assert(a2.resource() == (std::pmr::memory_resource*)42);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/default.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/default.pass.cpp
new file mode 100644
index 0000000000000..c12a15255bafd
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/default.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator() noexcept
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  {
+    static_assert(std::is_nothrow_default_constructible<std::pmr::polymorphic_allocator<void>>::value,
+                  "Must me nothrow default constructible");
+  }
+  {
+    // test that the allocator gets its resource from get_default_resource
+    TestResource R1(42);
+    std::pmr::set_default_resource(&R1);
+
+    typedef std::pmr::polymorphic_allocator<void> A;
+    A const a;
+    assert(a.resource() == &R1);
+
+    std::pmr::set_default_resource(nullptr);
+    A const a2;
+    assert(a.resource() == &R1);
+    assert(a2.resource() == std::pmr::new_delete_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/memory_resource_convert.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/memory_resource_convert.pass.cpp
new file mode 100644
index 0000000000000..f34b62e58ffa6
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/memory_resource_convert.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator<T>::polymorphic_allocator(memory_resource *)
+
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  {
+    typedef std::pmr::polymorphic_allocator<void> A;
+    static_assert(std::is_convertible_v<decltype(nullptr), A>);
+    static_assert(std::is_convertible_v<std::pmr::memory_resource*, A>);
+  }
+  {
+    typedef std::pmr::polymorphic_allocator<void> A;
+    TestResource R;
+    A const a(&R);
+    assert(a.resource() == &R);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/other_alloc.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/other_alloc.pass.cpp
new file mode 100644
index 0000000000000..93df604df9d0d
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.ctor/other_alloc.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U>
+// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator<U> const &);
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A1;
+  typedef std::pmr::polymorphic_allocator<char> A2;
+  { // Test that the conversion is implicit and noexcept.
+    static_assert(std::is_convertible<A1 const&, A2>::value, "");
+    static_assert(std::is_convertible<A2 const&, A1>::value, "");
+    static_assert(std::is_nothrow_constructible<A1, A2 const&>::value, "");
+    static_assert(std::is_nothrow_constructible<A2, A1 const&>::value, "");
+  }
+  // copy other type
+  {
+    A1 const a((std::pmr::memory_resource*)42);
+    A2 const a2(a);
+    assert(a.resource() == a2.resource());
+    assert(a2.resource() == (std::pmr::memory_resource*)42);
+  }
+  {
+    A1 a((std::pmr::memory_resource*)42);
+    A2 const a2(std::move(a));
+    assert(a.resource() == a2.resource());
+    assert(a2.resource() == (std::pmr::memory_resource*)42);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/equal.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/equal.pass.cpp
new file mode 100644
index 0000000000000..acb0fdea0acbe
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/equal.pass.cpp
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator;
+
+// template <class T, class U>
+// bool operator==(
+//      polymorphic_allocator<T> const &
+//    , polymorphic_allocator<U> const &) noexcept
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A1;
+  typedef std::pmr::polymorphic_allocator<int> A2;
+  // check return types
+  {
+    A1 const a1;
+    A2 const a2;
+    static_assert(std::is_same_v<decltype(a1 == a2), bool>);
+    static_assert(noexcept(a1 == a2));
+  }
+  // equal same type (
diff erent resource)
+  {
+    TestResource d1(1);
+    TestResource d2(1);
+    A1 const a1(&d1);
+    A1 const a2(&d2);
+
+    assert(a1 == a2);
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(a2 == a1);
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+  // equal same type (same resource)
+  {
+    TestResource d1;
+    A1 const a1(&d1);
+    A1 const a2(&d1);
+
+    assert(a1 == a2);
+    assert(d1.checkIsEqualCalledEq(0));
+
+    assert(a2 == a1);
+    assert(d1.checkIsEqualCalledEq(0));
+  }
+  // equal 
diff erent type (
diff erent resource)
+  {
+    TestResource d1(42);
+    TestResource d2(42);
+    A1 const a1(&d1);
+    A2 const a2(&d2);
+
+    assert(a1 == a2);
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    assert(a2 == a1);
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+  // equal 
diff erent type (same resource)
+  {
+    TestResource d1(42);
+    A1 const a1(&d1);
+    A2 const a2(&d1);
+
+    assert(a1 == a2);
+    assert(d1.checkIsEqualCalledEq(0));
+
+    assert(a2 == a1);
+    assert(d1.checkIsEqualCalledEq(0));
+  }
+  // not equal same type
+  {
+    TestResource d1(1);
+    TestResource d2(2);
+    A1 const a1(&d1);
+    A1 const a2(&d2);
+
+    assert(!(a1 == a2));
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(!(a2 == a1));
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+  // not equal 
diff erent types
+  {
+    TestResource d1;
+    TestResource1 d2;
+    A1 const a1(&d1);
+    A2 const a2(&d2);
+
+    assert(!(a1 == a2));
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(!(a2 == a1));
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/not_equal.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/not_equal.pass.cpp
new file mode 100644
index 0000000000000..983a28c1b6471
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.eq/not_equal.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator;
+
+// template <class T>
+// bool operator!=(
+//      polymorphic_allocator<T> const &
+//    , polymorphic_allocator<T> const &) noexcept
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A1;
+  typedef std::pmr::polymorphic_allocator<int> A2;
+  // check return types
+  {
+    A1 const a1;
+    A2 const a2;
+    ASSERT_SAME_TYPE(decltype(a1 != a2), bool);
+    ASSERT_NOEXCEPT(a1 != a2);
+  }
+  // not equal same type (
diff erent resource)
+  {
+    TestResource d1(1);
+    TestResource d2(2);
+    A1 const a1(&d1);
+    A1 const a2(&d2);
+
+    assert(a1 != a2);
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(a2 != a1);
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+  // equal same type (same resource)
+  {
+    TestResource d1;
+    A1 const a1(&d1);
+    A1 const a2(&d1);
+
+    assert(!(a1 != a2));
+    assert(d1.checkIsEqualCalledEq(0));
+
+    assert(!(a2 != a1));
+    assert(d1.checkIsEqualCalledEq(0));
+  }
+  // equal same type
+  {
+    TestResource d1(1);
+    TestResource d2(1);
+    A1 const a1(&d1);
+    A1 const a2(&d2);
+
+    assert(!(a1 != a2));
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(!(a2 != a1));
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+  // not equal 
diff erent types
+  {
+    TestResource d1;
+    TestResource1 d2;
+    A1 const a1(&d1);
+    A2 const a2(&d2);
+
+    assert(a1 != a2);
+    assert(d1.checkIsEqualCalledEq(1));
+    assert(d2.checkIsEqualCalledEq(0));
+
+    d1.reset();
+
+    assert(a2 != a1);
+    assert(d1.checkIsEqualCalledEq(0));
+    assert(d2.checkIsEqualCalledEq(1));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
new file mode 100644
index 0000000000000..f555b67f550a4
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::allocate(size_t n)
+
+#include <memory_resource>
+#include <cassert>
+#include <exception>
+#include <limits>
+#include <memory>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+template <size_t S, size_t Align>
+void testForSizeAndAlign() {
+  using T = typename std::aligned_storage<S, Align>::type;
+  TestResource R;
+  std::pmr::polymorphic_allocator<T> a(&R);
+
+  for (int N = 1; N <= 5; ++N) {
+    auto ret = a.allocate(N);
+    assert(R.checkAlloc(ret, N * sizeof(T), alignof(T)));
+
+    a.deallocate(ret, N);
+    R.reset();
+  }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <size_t S>
+void testAllocForSizeThrows() {
+  using T      = typename std::aligned_storage<S>::type;
+  using Alloc  = std::pmr::polymorphic_allocator<T>;
+  using Traits = std::allocator_traits<Alloc>;
+  NullResource R;
+  Alloc a(&R);
+
+  // Test that allocating exactly the max size does not throw.
+  size_t maxSize = Traits::max_size(a);
+  try {
+    a.allocate(maxSize);
+  } catch (...) {
+    assert(false);
+  }
+
+  size_t sizeTypeMax = std::numeric_limits<std::size_t>::max();
+  if (maxSize != sizeTypeMax) {
+    // Test that allocating size_t(~0) throws bad alloc.
+    try {
+      a.allocate(sizeTypeMax);
+      assert(false);
+    } catch (const std::exception&) {
+    }
+
+    // Test that allocating even one more than the max size does throw.
+    size_t overSize = maxSize + 1;
+    try {
+      a.allocate(overSize);
+      assert(false);
+    } catch (const std::exception&) {
+    }
+  }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+int main(int, char**) {
+  {
+    std::pmr::polymorphic_allocator<int> a;
+    ASSERT_SAME_TYPE(decltype(a.allocate(0)), int*);
+    static_assert(!noexcept(a.allocate(0)), "");
+  }
+  {
+    constexpr std::size_t MA = alignof(std::max_align_t);
+    testForSizeAndAlign<1, 1>();
+    testForSizeAndAlign<1, 2>();
+    testForSizeAndAlign<1, MA>();
+    testForSizeAndAlign<2, 2>();
+    testForSizeAndAlign<73, alignof(void*)>();
+    testForSizeAndAlign<73, MA>();
+    testForSizeAndAlign<13, MA>();
+  }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  {
+    testAllocForSizeThrows<1>();
+    testAllocForSizeThrows<2>();
+    testAllocForSizeThrows<4>();
+    testAllocForSizeThrows<8>();
+    testAllocForSizeThrows<16>();
+    testAllocForSizeThrows<73>();
+    testAllocForSizeThrows<13>();
+  }
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair.pass.cpp
new file mode 100644
index 0000000000000..205fd7028d43b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<U1, U2>*)
+
+#include <memory_resource>
+#include <cassert>
+#include <cstdlib>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include "uses_alloc_types.h"
+
+int constructed = 0;
+
+struct default_constructible {
+  default_constructible() : x(42) { ++constructed; }
+  int x = 0;
+};
+
+int main(int, char**) {
+  // pair<default_constructible, default_constructible> as T()
+  {
+    typedef default_constructible T;
+    typedef std::pair<T, T> P;
+    typedef std::pmr::polymorphic_allocator<void> A;
+    P* ptr = (P*)std::malloc(sizeof(P));
+    A a;
+    a.construct(ptr);
+    assert(constructed == 2);
+    assert(ptr->first.x == 42);
+    assert(ptr->second.x == 42);
+    std::free(ptr);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
new file mode 100644
index 0000000000000..b61155ba38766
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> const&)
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+#include "uses_alloc_types.h"
+#include "controlled_allocators.h"
+#include "test_allocator.h"
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, std::pair<TT, UU> const& p) {
+  using P = std::pair<UA1, UA2>;
+  TestResource R;
+  std::pmr::memory_resource* M = &R;
+  std::pmr::polymorphic_allocator<P> A(M);
+  P* ptr  = (P*)std::malloc(sizeof(P));
+  P* ptr2 = (P*)std::malloc(sizeof(P));
+
+  // UNDER TEST //
+  A.construct(ptr, p);
+
+  A.construct(ptr2, std::piecewise_construct, std::forward_as_tuple(p.first), std::forward_as_tuple(p.second));
+  // ------- //
+
+  bool tres =
+      checkConstruct<decltype((p.first))>(ptr->first, TExpect, M) && checkConstructionEquiv(ptr->first, ptr2->first);
+
+  bool ures = checkConstruct<decltype((p.second))>(ptr->second, UExpect, M) &&
+              checkConstructionEquiv(ptr->second, ptr2->second);
+
+  A.destroy(ptr);
+  std::free(ptr);
+  A.destroy(ptr2);
+  std::free(ptr2);
+  return tres && ures;
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(std::pair<TT, UU> const& p) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, p)));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, p)));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, p)));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_None, p)));
+  }
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_not_uses_allocator(std::pair<TT, UU> const& p) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, p)));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, p)));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, p)));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, p)));
+  }
+}
+
+template <class Tp>
+struct Print;
+
+int main(int, char**) {
+  using PMR = std::pmr::memory_resource*;
+  using PMA = std::pmr::polymorphic_allocator<char>;
+  {
+    int x = 42;
+    int y = 42;
+    const std::pair<int, int&> p(x, y);
+    test_pmr_not_uses_allocator<PMR>(p);
+    test_pmr_uses_allocator<PMA>(p);
+  }
+  {
+    int x = 42;
+    int y = 42;
+    const std::pair<int&, int&&> p(x, std::move(y));
+    test_pmr_not_uses_allocator<PMR>(p);
+    test_pmr_uses_allocator<PMA>(p);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_rvalue.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_rvalue.pass.cpp
new file mode 100644
index 0000000000000..e000449dae463
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_rvalue.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&)
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+#include "uses_alloc_types.h"
+#include "controlled_allocators.h"
+#include "test_allocator.h"
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, std::pair<TT, UU>&& p) {
+  using P = std::pair<UA1, UA2>;
+  TestResource R;
+  std::pmr::memory_resource* M = &R;
+  std::pmr::polymorphic_allocator<P> A(M);
+  P* ptr  = A.allocate(2);
+  P* ptr2 = ptr + 1;
+
+  // UNDER TEST //
+  A.construct(ptr, std::move(p));
+
+  A.construct(ptr2,
+              std::piecewise_construct,
+              std::forward_as_tuple(std::forward<TT>(p.first)),
+              std::forward_as_tuple(std::forward<UU>(p.second)));
+  // ------- //
+
+  bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && checkConstructionEquiv(ptr->first, ptr2->first);
+
+  bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && checkConstructionEquiv(ptr->second, ptr2->second);
+
+  A.destroy(ptr);
+  A.destroy(ptr2);
+  A.deallocate(ptr, 2);
+  return tres && ures;
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(std::pair<TT, UU>&& p) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p))));
+  }
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_not_uses_allocator(std::pair<TT, UU>&& p) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
+  }
+}
+
+int main(int, char**) {
+  using PMR = std::pmr::memory_resource*;
+  using PMA = std::pmr::polymorphic_allocator<char>;
+  {
+    int x = 42;
+    int y = 42;
+    std::pair<int&, int&&> p(x, std::move(y));
+    test_pmr_not_uses_allocator<PMR>(std::move(p));
+    test_pmr_uses_allocator<PMA>(std::move(p));
+  }
+  {
+    int x = 42;
+    int y = 42;
+    std::pair<int&&, int&> p(std::move(x), y);
+    test_pmr_not_uses_allocator<PMR>(std::move(p));
+    test_pmr_uses_allocator<PMA>(std::move(p));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_values.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_values.pass.cpp
new file mode 100644
index 0000000000000..ee7db48146aab
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_values.pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class P1, class P2, class U1, class U2>
+// void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&)
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+#include "uses_alloc_types.h"
+#include "controlled_allocators.h"
+#include "test_allocator.h"
+
+template <class UA1, class UA2, class TT, class UU>
+bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, TT&& t, UU&& u) {
+  using P = std::pair<UA1, UA2>;
+  TestResource R;
+  std::pmr::memory_resource* M = &R;
+  std::pmr::polymorphic_allocator<P> A(M);
+  P* ptr  = (P*)std::malloc(sizeof(P));
+  P* ptr2 = (P*)std::malloc(sizeof(P));
+
+  // UNDER TEST //
+  A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u));
+  A.construct(ptr2,
+              std::piecewise_construct,
+              std::forward_as_tuple(std::forward<TT>(t)),
+              std::forward_as_tuple(std::forward<UU>(u)));
+  // ------- //
+
+  bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && checkConstructionEquiv(ptr->first, ptr2->first);
+
+  bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && checkConstructionEquiv(ptr->second, ptr2->second);
+
+  A.destroy(ptr);
+  A.destroy(ptr2);
+  std::free(ptr);
+  std::free(ptr2);
+  return tres && ures;
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_uses_allocator(TT&& t, UU&& u) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_AllocArg, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+}
+
+template <class Alloc, class TT, class UU>
+void test_pmr_not_uses_allocator(TT&& t, UU&& u) {
+  {
+    using T = NotUsesAllocator<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, 1>;
+    using U = UsesAllocatorV2<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, 1>;
+    using U = UsesAllocatorV3<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, 1>;
+    using U = NotUsesAllocator<Alloc, 1>;
+    assert((doTest<T, U>(UA_None, UA_None, std::forward<TT>(t), std::forward<UU>(u))));
+  }
+}
+
+int main(int, char**) {
+  using PMR = std::pmr::memory_resource*;
+  using PMA = std::pmr::polymorphic_allocator<char>;
+  {
+    int x = 42;
+    int y = 42;
+    test_pmr_not_uses_allocator<PMR>(x, std::move(y));
+    test_pmr_uses_allocator<PMA>(x, std::move(y));
+  }
+  {
+    int x       = 42;
+    const int y = 42;
+    test_pmr_not_uses_allocator<PMR>(std::move(x), y);
+    test_pmr_uses_allocator<PMA>(std::move(x), y);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
new file mode 100644
index 0000000000000..15806cd30a641
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t
+//                                          tuple<Args1...>, tuple<Args2...>)
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+#include "uses_alloc_types.h"
+#include "controlled_allocators.h"
+#include "test_allocator.h"
+
+template <class T, class U, class... TTuple, class... UTuple>
+bool doTest(
+    UsesAllocatorType TExpect, UsesAllocatorType UExpect, std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple) {
+  using P = std::pair<T, U>;
+  TestResource R;
+  std::pmr::memory_resource* M = &R;
+  std::pmr::polymorphic_allocator<P> A(M);
+  P* ptr = A.allocate(1);
+
+  // UNDER TEST //
+  A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple));
+  // ------- //
+  bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M);
+  bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M);
+
+  A.destroy(ptr);
+  A.deallocate(ptr, 1);
+  return tres && ures;
+}
+
+template <class Alloc, class... TTypes, class... UTypes>
+void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) {
+  {
+    using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>;
+    using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>;
+    using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>;
+    using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>;
+    using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+}
+
+template <class Alloc, class... TTypes, class... UTypes>
+void test_pmr_not_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) {
+  {
+    using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>;
+    using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>;
+    using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>;
+    using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>;
+    using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>;
+    assert((doTest<T, U>(UA_None, UA_None, std::move(ttuple), std::move(utuple))));
+  }
+}
+
+int main(int, char**) {
+  using PMR = std::pmr::memory_resource*;
+  using PMA = std::pmr::polymorphic_allocator<char>;
+  {
+    std::tuple<> t1;
+    test_pmr_not_uses_allocator<PMR>(t1, t1);
+    test_pmr_uses_allocator<PMA>(t1, t1);
+  }
+  {
+    std::tuple<int> t1(42);
+    std::tuple<> t2;
+    test_pmr_not_uses_allocator<PMR>(t1, t2);
+    test_pmr_not_uses_allocator<PMR>(t2, t1);
+    test_pmr_uses_allocator<PMA>(t1, t2);
+    test_pmr_uses_allocator<PMA>(t2, t1);
+  }
+  {
+    std::tuple<int> t1(42);
+    int x     = 55;
+    double dx = 42.42;
+    std::tuple<int&, double&&> t2(x, std::move(dx));
+    test_pmr_not_uses_allocator<PMR>(t1, std::move(t2));
+    test_pmr_not_uses_allocator<PMR>(std::move(t2), t1);
+    test_pmr_uses_allocator<PMA>(t1, std::move(t2));
+    test_pmr_uses_allocator<PMA>(std::move(t2), t1);
+  }
+  {
+    void* xptr = nullptr;
+    long y     = 4242;
+    std::tuple<int, long const&, void*&> t1(42, y, xptr);
+    int x         = 55;
+    double dx     = 42.42;
+    const char* s = "hello World";
+    std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s);
+    test_pmr_not_uses_allocator<PMR>(t1, std::move(t2));
+    test_pmr_not_uses_allocator<PMR>(std::move(t2), t1);
+    test_pmr_uses_allocator<PMA>(t1, std::move(t2));
+    test_pmr_uses_allocator<PMA>(std::move(t2), t1);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair_evil.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair_evil.pass.cpp
new file mode 100644
index 0000000000000..097b174aca094
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair_evil.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t
+//                                          tuple<Args1...>, tuple<Args2...>)
+
+#include <memory_resource>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+
+template <class T>
+struct EvilAlloc {
+  explicit EvilAlloc() : inner_(std::pmr::null_memory_resource()) {}
+
+  EvilAlloc(std::pmr::polymorphic_allocator<T>& a) : inner_(a) {}
+  EvilAlloc(std::pmr::polymorphic_allocator<T>&& a) : inner_(a) {}
+  EvilAlloc(std::pmr::polymorphic_allocator<T> const& a)  = delete;
+  EvilAlloc(std::pmr::polymorphic_allocator<T> const&& a) = delete;
+
+  using value_type = T;
+  template <class U>
+  EvilAlloc(EvilAlloc<U> const& rhs) : inner_(rhs.inner_) {}
+
+  std::pmr::polymorphic_allocator<T> inner_;
+};
+
+struct WidgetV0 {
+  WidgetV0(int v) : value_(v) {}
+
+  bool holds(int v, const std::pmr::polymorphic_allocator<char>&) const { return value_ == v; }
+
+private:
+  int value_;
+};
+
+struct WidgetV1 {
+  using allocator_type = EvilAlloc<char>;
+
+  WidgetV1(int v) : value_(v), alloc_() {}
+  WidgetV1(std::allocator_arg_t, EvilAlloc<char> a, int v) : value_(v), alloc_(a) {}
+
+  bool holds(int v, const std::pmr::polymorphic_allocator<char>& a) const { return value_ == v && alloc_.inner_ == a; }
+
+private:
+  int value_;
+  EvilAlloc<char> alloc_;
+};
+
+struct WidgetV2 {
+  using allocator_type = EvilAlloc<char>;
+
+  WidgetV2(int v) : value_(v), alloc_() {}
+  WidgetV2(int v, EvilAlloc<char> a) : value_(v), alloc_(a) {}
+
+  bool holds(int v, std::pmr::polymorphic_allocator<char> a) const { return value_ == v && alloc_.inner_ == a; }
+
+private:
+  int value_;
+  EvilAlloc<char> alloc_;
+};
+
+struct WidgetV3 {
+  using allocator_type = EvilAlloc<char>;
+
+  WidgetV3(int v) : value_(v), alloc_() {}
+  WidgetV3(std::allocator_arg_t, EvilAlloc<char> a, int v) : value_(v), alloc_(a) {}
+  WidgetV3(int v, EvilAlloc<char> a) : value_(v), alloc_(a) {}
+
+  bool holds(int v, std::pmr::polymorphic_allocator<char> a) const { return value_ == v && alloc_.inner_ == a; }
+
+private:
+  int value_;
+  EvilAlloc<char> alloc_;
+};
+
+static_assert(std::uses_allocator<WidgetV1, EvilAlloc<char>>::value, "");
+static_assert(std::uses_allocator<WidgetV2, EvilAlloc<char>>::value, "");
+static_assert(std::uses_allocator<WidgetV3, EvilAlloc<char>>::value, "");
+static_assert(std::uses_allocator<WidgetV1, std::pmr::polymorphic_allocator<char>>::value, "");
+static_assert(std::uses_allocator<WidgetV2, std::pmr::polymorphic_allocator<char>>::value, "");
+static_assert(std::uses_allocator<WidgetV3, std::pmr::polymorphic_allocator<char>>::value, "");
+
+template <class W1, class W2>
+void test_evil() {
+  using PMA = std::pmr::polymorphic_allocator<char>;
+  PMA pma(std::pmr::new_delete_resource());
+  {
+    using Pair  = std::pair<W1, W2>;
+    void* where = std::malloc(sizeof(Pair));
+    Pair* p     = (Pair*)where;
+    pma.construct(p, std::piecewise_construct, std::make_tuple(42), std::make_tuple(42));
+    assert(p->first.holds(42, pma));
+    assert(p->second.holds(42, pma));
+    pma.destroy(p);
+    std::free(where);
+  }
+}
+
+int main(int, char**) {
+  test_evil<WidgetV0, WidgetV0>();
+  test_evil<WidgetV0, WidgetV1>();
+  test_evil<WidgetV0, WidgetV2>();
+  test_evil<WidgetV0, WidgetV3>();
+  test_evil<WidgetV1, WidgetV0>();
+  test_evil<WidgetV1, WidgetV1>();
+  test_evil<WidgetV1, WidgetV2>();
+  test_evil<WidgetV1, WidgetV3>();
+  test_evil<WidgetV2, WidgetV0>();
+  test_evil<WidgetV2, WidgetV1>();
+  test_evil<WidgetV2, WidgetV2>();
+  test_evil<WidgetV2, WidgetV3>();
+  test_evil<WidgetV3, WidgetV0>();
+  test_evil<WidgetV3, WidgetV1>();
+  test_evil<WidgetV3, WidgetV2>();
+  test_evil<WidgetV3, WidgetV3>();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_types.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_types.pass.cpp
new file mode 100644
index 0000000000000..fbf2a90056e04
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_types.pass.cpp
@@ -0,0 +1,183 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U, class ...Args>
+// void polymorphic_allocator<T>::construct(U *, Args &&...)
+
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+#include "uses_alloc_types.h"
+#include "controlled_allocators.h"
+#include "test_allocator.h"
+
+template <class T>
+struct PMATest {
+  TestResource R;
+  std::pmr::polymorphic_allocator<T> A;
+  T* ptr;
+  bool constructed;
+
+  PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {}
+
+  template <class... Args>
+  void construct(Args&&... args) {
+    A.construct(ptr, std::forward<Args>(args)...);
+    constructed = true;
+  }
+
+  ~PMATest() {
+    if (constructed)
+      A.destroy(ptr);
+    A.deallocate(ptr, 1);
+  }
+};
+
+template <class T, class... Args>
+bool doTest(UsesAllocatorType UAExpect, Args&&... args) {
+  PMATest<T> TH;
+  // UNDER TEST //
+  TH.construct(std::forward<Args>(args)...);
+  return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R);
+  // ------- //
+}
+
+template <class T, class... Args>
+bool doTestUsesAllocV0(Args&&... args) {
+  PMATest<T> TH;
+  // UNDER TEST //
+  TH.construct(std::forward<Args>(args)...);
+  return checkConstruct<Args&&...>(*TH.ptr, UA_None);
+  // -------- //
+}
+
+template <class T, class EAlloc, class... Args>
+bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args) {
+  PMATest<T> TH;
+  // UNDER TEST //
+  TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...);
+  return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc);
+  // -------- //
+}
+
+template <class T, class EAlloc, class... Args>
+bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args) {
+  PMATest<T> TH;
+  // UNDER TEST //
+  TH.construct(std::forward<Args>(args)..., ealloc);
+  return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc);
+  // -------- //
+}
+
+template <class Alloc, class... Args>
+void test_pmr_uses_alloc(Args&&... args) {
+  TestResource R(12435);
+  std::pmr::memory_resource* M = &R;
+  {
+    // NotUsesAllocator provides valid signatures for each uses-allocator
+    // construction but does not supply the required allocator_type typedef.
+    // Test that we can call these constructors manually without
+    // polymorphic_allocator interfering.
+    using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
+    assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+    assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...)));
+    assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...)));
+  }
+  {
+    // Test T(std::allocator_arg_t, Alloc const&, Args...) construction
+    using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
+    assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
+  }
+  {
+    // Test T(Args..., Alloc const&) construction
+    using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
+    assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...)));
+  }
+  {
+    // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction
+    // is preferred when T(Args..., Alloc const&) is also available.
+    using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
+    assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...)));
+  }
+}
+
+// Test that polymorphic_allocator does not prevent us from manually
+// doing non-pmr uses-allocator construction.
+template <class Alloc, class AllocObj, class... Args>
+void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args) {
+  {
+    using T = NotUsesAllocator<Alloc, sizeof...(Args)>;
+    assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+    assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+    assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+  }
+  {
+    using T = UsesAllocatorV1<Alloc, sizeof...(Args)>;
+    assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+    assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+  }
+  {
+    using T = UsesAllocatorV2<Alloc, sizeof...(Args)>;
+    assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+    assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+  }
+  {
+    using T = UsesAllocatorV3<Alloc, sizeof...(Args)>;
+    assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...));
+    assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...)));
+    assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...)));
+  }
+}
+
+int main(int, char**) {
+  using PMR   = std::pmr::memory_resource*;
+  using PMA   = std::pmr::polymorphic_allocator<char>;
+  using STDA  = std::allocator<char>;
+  using TESTA = test_allocator<char>;
+
+  int value        = 42;
+  const int cvalue = 43;
+  {
+    test_pmr_uses_alloc<PMA>();
+    test_pmr_uses_alloc<PMA>(value);
+    test_pmr_uses_alloc<PMA>(cvalue);
+    test_pmr_uses_alloc<PMA>(cvalue, std::move(value));
+  }
+  {
+    STDA std_alloc;
+    TESTA test_alloc(42);
+    PMR mem_res = std::pmr::new_delete_resource();
+
+    test_non_pmr_uses_alloc<PMR>(mem_res);
+    test_non_pmr_uses_alloc<STDA>(std_alloc);
+    test_non_pmr_uses_alloc<TESTA>(test_alloc);
+    test_non_pmr_uses_alloc<PMR>(mem_res, value);
+    test_non_pmr_uses_alloc<STDA>(std_alloc, value);
+    test_non_pmr_uses_alloc<TESTA>(test_alloc, value);
+    test_non_pmr_uses_alloc<PMR>(mem_res, cvalue);
+    test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue);
+    test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue);
+    test_non_pmr_uses_alloc<PMR>(mem_res, cvalue, std::move(cvalue));
+    test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value));
+    test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
new file mode 100644
index 0000000000000..c69bd942b0b75
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+template <size_t S, size_t Align>
+void testForSizeAndAlign() {
+  using T = typename std::aligned_storage<S, Align>::type;
+
+  TestResource R;
+  std::pmr::polymorphic_allocator<T> a(&R);
+
+  for (int N = 1; N <= 5; ++N) {
+    auto ret = a.allocate(N);
+    assert(R.checkAlloc(ret, N * sizeof(T), alignof(T)));
+
+    a.deallocate(ret, N);
+    assert(R.checkDealloc(ret, N * sizeof(T), alignof(T)));
+
+    R.reset();
+  }
+}
+
+int main(int, char**) {
+  {
+    std::pmr::polymorphic_allocator<int> a;
+    ASSERT_SAME_TYPE(decltype(a.deallocate(nullptr, 0)), void);
+  }
+  {
+    constexpr std::size_t MA = alignof(std::max_align_t);
+    testForSizeAndAlign<1, 1>();
+    testForSizeAndAlign<1, 2>();
+    testForSizeAndAlign<1, MA>();
+    testForSizeAndAlign<2, 2>();
+    testForSizeAndAlign<73, alignof(void*)>();
+    testForSizeAndAlign<73, MA>();
+    testForSizeAndAlign<13, MA>();
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/destroy.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/destroy.pass.cpp
new file mode 100644
index 0000000000000..2594f5226c258
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/destroy.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U>
+// void polymorphic_allocator<T>::destroy(U * ptr);
+
+#include <memory_resource>
+#include <cassert>
+#include <cstdlib>
+#include <new>
+#include <type_traits>
+
+#include "test_macros.h"
+
+int count = 0;
+
+struct destroyable {
+  destroyable() { ++count; }
+  ~destroyable() { --count; }
+};
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<double> A;
+  {
+    A a;
+    ASSERT_SAME_TYPE(decltype(a.destroy((destroyable*)nullptr)), void);
+  }
+  {
+    destroyable* ptr = ::new (std::malloc(sizeof(destroyable))) destroyable();
+    assert(count == 1);
+    A{}.destroy(ptr);
+    assert(count == 0);
+    std::free(ptr);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/resource.pass.cpp
new file mode 100644
index 0000000000000..a6ed1f522194b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/resource.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// memory_resource *
+// polymorphic_allocator<T>::resource() const
+
+#include <memory_resource>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A;
+  {
+    A const a;
+    ASSERT_SAME_TYPE(decltype(a.resource()), std::pmr::memory_resource*);
+  }
+  {
+    std::pmr::memory_resource* mptr = (std::pmr::memory_resource*)42;
+    A const a(mptr);
+    assert(a.resource() == mptr);
+  }
+  {
+    A const a(nullptr);
+    assert(a.resource() == nullptr);
+    assert(a.resource() == nullptr);
+  }
+  {
+    A const a;
+    assert(a.resource() == std::pmr::get_default_resource());
+  }
+  {
+    std::pmr::memory_resource* mptr = (std::pmr::memory_resource*)42;
+    std::pmr::set_default_resource(mptr);
+    A const a;
+    assert(a.resource() == mptr);
+    assert(a.resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/select_on_container_copy_construction.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/select_on_container_copy_construction.pass.cpp
new file mode 100644
index 0000000000000..5b2551ec910cd
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/select_on_container_copy_construction.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// polymorphic_allocator
+// polymorphic_allocator<T>::select_on_container_copy_construction() const
+
+#include <memory_resource>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  typedef std::pmr::polymorphic_allocator<void> A;
+  {
+    A const a;
+    ASSERT_SAME_TYPE(decltype(a.select_on_container_copy_construction()), A);
+  }
+  {
+    std::pmr::memory_resource* mptr = (std::pmr::memory_resource*)42;
+    A const a(mptr);
+    assert(a.resource() == mptr);
+    A const other = a.select_on_container_copy_construction();
+    assert(other.resource() == std::pmr::get_default_resource());
+    assert(a.resource() == mptr);
+  }
+  {
+    std::pmr::memory_resource* mptr = (std::pmr::memory_resource*)42;
+    std::pmr::set_default_resource(mptr);
+    A const a(nullptr);
+    assert(a.resource() == nullptr);
+    A const other = a.select_on_container_copy_construction();
+    assert(other.resource() == std::pmr::get_default_resource());
+    assert(other.resource() == mptr);
+    assert(a.resource() == nullptr);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop.pass.cpp
new file mode 100644
index 0000000000000..3fe8a45864406
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <deque>
+
+// namespace std::pmr {
+// template <class T>
+// using deque =
+//     ::std::deque<T, polymorphic_allocator<T>>
+//
+// } // namespace std::pmr
+
+#include <deque>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using StdDeque = std::deque<int, std::pmr::polymorphic_allocator<int>>;
+  using PmrDeque = std::pmr::deque<int>;
+  static_assert(std::is_same<StdDeque, PmrDeque>::value, "");
+  PmrDeque d;
+  assert(d.get_allocator().resource() == std::pmr::get_default_resource());
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop2.pass.cpp
new file mode 100644
index 0000000000000..e96b21e136a59
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_deque_synop2.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <deque>
+
+// namespace std::pmr {
+//
+// typedef ... deque
+//
+// } // namespace std::pmr
+
+#include <deque>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::deque is usable without <memory_resource>.
+    std::pmr::deque<int> d;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_forward_list_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_forward_list_synop.pass.cpp
new file mode 100644
index 0000000000000..2a0935487dfb8
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_forward_list_synop.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <forward_list>
+
+// namespace std::pmr {
+// template <class T>
+// using forward_list =
+//     ::std::forward_list<T, polymorphic_allocator<T>>
+//
+// } // namespace std::pmr
+
+#include <forward_list>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using StdForwardList = std::forward_list<int, std::pmr::polymorphic_allocator<int>>;
+  using PmrForwardList = std::pmr::forward_list<int>;
+  static_assert(std::is_same<StdForwardList, PmrForwardList>::value, "");
+  PmrForwardList d;
+  assert(d.get_allocator().resource() == std::pmr::get_default_resource());
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop.pass.cpp
new file mode 100644
index 0000000000000..9adabd4fced90
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <list>
+
+// namespace std::pmr {
+// template <class T>
+// using list =
+//     ::std::list<T, polymorphic_allocator<T>>
+//
+// } // namespace std::pmr
+
+#include <list>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using StdList = std::list<int, std::pmr::polymorphic_allocator<int>>;
+  using PmrList = std::pmr::list<int>;
+  static_assert(std::is_same<StdList, PmrList>::value, "");
+  PmrList d;
+  assert(d.get_allocator().resource() == std::pmr::get_default_resource());
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop2.pass.cpp
new file mode 100644
index 0000000000000..fef4cb2a33764
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_list_synop2.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <list>
+
+// namespace std::pmr {
+//
+// typedef ... list
+//
+// } // namespace std::pmr
+
+#include <list>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::list is usable without <memory_resource>.
+    std::pmr::list<int> l;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop.pass.cpp
new file mode 100644
index 0000000000000..0ba22fc8e3b0b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <map>
+
+// namespace std::pmr {
+// template <class K, class V, class Compare = less<Key> >
+// using map =
+//     ::std::map<K, V, Compare, polymorphic_allocator<pair<const K, V>>>
+//
+// template <class K, class V, class Compare = less<Key> >
+// using multimap =
+//     ::std::multimap<K, V, Compare, polymorphic_allocator<pair<const K, V>>>
+//
+// } // namespace std::pmr
+
+#include <map>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using K  = int;
+  using V  = char;
+  using DC = std::less<int>;
+  using OC = std::greater<int>;
+  using P  = std::pair<const K, V>;
+  {
+    using StdMap = std::map<K, V, DC, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::map<K, V>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::map<K, V, OC, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::map<K, V, OC>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    std::pmr::map<int, int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+  {
+    using StdMap = std::multimap<K, V, DC, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::multimap<K, V>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::multimap<K, V, OC, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::multimap<K, V, OC>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    std::pmr::multimap<int, int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop2.pass.cpp
new file mode 100644
index 0000000000000..452f922fd5bf0
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_map_synop2.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <map>
+
+// namespace std::pmr {
+//
+// typedef ... map
+//
+// } // namespace std::pmr
+
+#include <map>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::map is usable without <memory_resource>.
+    std::pmr::map<int, int> m;
+    std::pmr::multimap<int, int> mm;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
new file mode 100644
index 0000000000000..14c605e95b75c
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: no-localization
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <regex>
+
+// namespace std::pmr {
+//
+//  template <class BidirectionalIterator>
+//  using match_results =
+//    std::match_results<BidirectionalIterator,
+//                       polymorphic_allocator<sub_match<BidirectionalIterator>>>;
+//
+//  typedef match_results<const char*> cmatch;
+//  typedef match_results<const wchar_t*> wcmatch;
+//  typedef match_results<string::const_iterator> smatch;
+//  typedef match_results<wstring::const_iterator> wsmatch;
+//
+// } // namespace std::pmr
+
+#include <regex>
+#include <cassert>
+#include <memory_resource>
+#include <type_traits>
+
+template <class Iter, class PmrTypedef>
+void test_match_result_typedef() {
+  using StdMR = std::match_results<Iter, std::pmr::polymorphic_allocator<std::sub_match<Iter>>>;
+  using PmrMR = std::pmr::match_results<Iter>;
+  static_assert(std::is_same<StdMR, PmrMR>::value, "");
+  static_assert(std::is_same<PmrMR, PmrTypedef>::value, "");
+}
+
+int main(int, char**) {
+  {
+    test_match_result_typedef<const char*, std::pmr::cmatch>();
+    test_match_result_typedef<const wchar_t*, std::pmr::wcmatch>();
+    test_match_result_typedef<std::pmr::string::const_iterator, std::pmr::smatch>();
+    test_match_result_typedef<std::pmr::wstring::const_iterator, std::pmr::wsmatch>();
+  }
+  {
+    // Check that std::match_results has been included and is complete.
+    std::pmr::smatch s;
+    assert(s.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop.pass.cpp
new file mode 100644
index 0000000000000..7b0a6aa799cdb
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <set>
+
+// namespace std::pmr {
+// template <class V, class Compare = less<V> >
+// using set =
+//     ::std::set<V, Compare, polymorphic_allocator<V>>
+//
+// template <class V, class Compare = less<V> >
+// using multiset =
+//     ::std::multiset<V, Compare, polymorphic_allocator<V>>
+//
+// } // namespace std::pmr
+
+#include <set>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using V  = char;
+  using DC = std::less<V>;
+  using OC = std::greater<V>;
+  {
+    using StdSet = std::set<V, DC, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::set<V>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::set<V, OC, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::set<V, OC>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    std::pmr::set<int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+  {
+    using StdSet = std::multiset<V, DC, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::multiset<V>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::multiset<V, OC, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::multiset<V, OC>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    std::pmr::multiset<int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop2.pass.cpp
new file mode 100644
index 0000000000000..b63677e79e43f
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_set_synop2.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <set>
+
+// namespace std::pmr {
+//
+// typedef ... set
+//
+// } // namespace std::pmr
+
+#include <set>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::set is usable without <memory_resource>.
+    std::pmr::set<int> s;
+    std::pmr::multiset<int> ms;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
new file mode 100644
index 0000000000000..d694a3900a964
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <string>
+
+// namespace std::pmr {
+// template <class Char, class Traits = ...>
+// using basic_string =
+//     ::std::basic_string<Char, Traits, polymorphic_allocator<Char>>
+//
+// typedef ... string
+// typedef ... u16string
+// typedef ... u32string
+// typedef ... wstring
+//
+// } // namespace std::pmr
+
+#include <string>
+#include <cassert>
+#include <memory_resource>
+#include <type_traits>
+
+#include "constexpr_char_traits.h"
+
+template <class Char, class PmrTypedef>
+void test_string_typedef() {
+  using StdStr = std::basic_string<Char, std::char_traits<Char>, std::pmr::polymorphic_allocator<Char>>;
+  using PmrStr = std::pmr::basic_string<Char>;
+  static_assert(std::is_same<StdStr, PmrStr>::value, "");
+  static_assert(std::is_same<PmrStr, PmrTypedef>::value, "");
+}
+
+template <class Char, class Traits>
+void test_basic_string_alias() {
+  using StdStr = std::basic_string<Char, Traits, std::pmr::polymorphic_allocator<Char>>;
+  using PmrStr = std::pmr::basic_string<Char, Traits>;
+  static_assert(std::is_same<StdStr, PmrStr>::value, "");
+}
+
+int main(int, char**) {
+  {
+    test_string_typedef<char, std::pmr::string>();
+    test_string_typedef<wchar_t, std::pmr::wstring>();
+    test_string_typedef<char16_t, std::pmr::u16string>();
+    test_string_typedef<char32_t, std::pmr::u32string>();
+  }
+  {
+    test_basic_string_alias<char, constexpr_char_traits<char>>();
+    test_basic_string_alias<wchar_t, constexpr_char_traits<wchar_t>>();
+    test_basic_string_alias<char16_t, constexpr_char_traits<char16_t>>();
+    test_basic_string_alias<char32_t, constexpr_char_traits<char32_t>>();
+  }
+  {
+    // Check that std::basic_string has been included and is complete.
+    std::pmr::string s;
+    assert(s.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
new file mode 100644
index 0000000000000..b25300acf3088
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <string>
+
+// namespace std::pmr {
+//
+// typedef ... string
+// typedef ... u16string
+// typedef ... u32string
+// typedef ... wstring
+//
+// } // namespace std::pmr
+
+#include <string>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::string is usable without <memory_resource>.
+    std::pmr::string s;
+    std::pmr::wstring ws;
+    std::pmr::u16string u16s;
+    std::pmr::u32string u32s;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop.pass.cpp
new file mode 100644
index 0000000000000..0f660b5c5b8e0
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <unordered_map>
+
+// namespace std::pmr {
+// template <class K, class V, class H = hash<K>, class P = equal_to<K> >
+// using unordered_map =
+//     ::std::unordered_map<K, V, H, P, polymorphic_allocator<pair<const K, V>>>
+//
+// template <class K, class V,  class H = hash<K>, class P = equal_to<K> >
+// using unordered_multimap =
+//     ::std::unordered_multimap<K, V, H, P, polymorphic_allocator<pair<const K, V>>>
+//
+// } // namespace std::pmr
+
+#include <unordered_map>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+template <class T>
+struct MyHash : std::hash<T> {};
+
+template <class T>
+struct MyPred : std::equal_to<T> {};
+
+int main(int, char**) {
+  using K  = int;
+  using V  = char;
+  using DH = std::hash<K>;
+  using MH = MyHash<K>;
+  using DP = std::equal_to<K>;
+  using MP = MyPred<K>;
+  using P  = std::pair<const K, V>;
+  {
+    using StdMap = std::unordered_map<K, V, DH, DP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_map<K, V>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::unordered_map<K, V, MH, DP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_map<K, V, MH>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::unordered_map<K, V, MH, MP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_map<K, V, MH, MP>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    std::pmr::unordered_map<int, int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+  {
+    using StdMap = std::unordered_multimap<K, V, DH, DP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_multimap<K, V>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::unordered_multimap<K, V, MH, DP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_multimap<K, V, MH>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    using StdMap = std::unordered_multimap<K, V, MH, MP, std::pmr::polymorphic_allocator<P>>;
+    using PmrMap = std::pmr::unordered_multimap<K, V, MH, MP>;
+    static_assert(std::is_same<StdMap, PmrMap>::value, "");
+  }
+  {
+    std::pmr::unordered_multimap<int, int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop2.pass.cpp
new file mode 100644
index 0000000000000..811753951beb4
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_map_synop2.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <unordered_map>
+
+// namespace std::pmr {
+//
+// typedef ... unordered_map
+//
+// } // namespace std::pmr
+
+#include <unordered_map>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::unordered_map is usable without <memory_resource>.
+    std::pmr::unordered_map<int, int> m;
+    std::pmr::unordered_multimap<int, int> mm;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop.pass.cpp
new file mode 100644
index 0000000000000..7f34fb2501759
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <unordered_set>
+
+// namespace std::pmr {
+// template <class V, class H = hash<V>, class P = equal_to<V> >
+// using unordered_set =
+//     ::std::unordered_set<V, H, P, polymorphic_allocator<V>>
+//
+// template <class V,  class H = hash<V>, class P = equal_to<V> >
+// using unordered_multiset =
+//     ::std::unordered_multiset<V, H, P, polymorphic_allocator<V>>
+//
+// } // namespace std::pmr
+
+#include <unordered_set>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+template <class T>
+struct MyHash : std::hash<T> {};
+
+template <class T>
+struct MyPred : std::equal_to<T> {};
+
+int main(int, char**) {
+  using V  = char;
+  using DH = std::hash<V>;
+  using MH = MyHash<V>;
+  using DP = std::equal_to<V>;
+  using MP = MyPred<V>;
+  {
+    using StdSet = std::unordered_set<V, DH, DP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_set<V>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::unordered_set<V, MH, DP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_set<V, MH>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::unordered_set<V, MH, MP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_set<V, MH, MP>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    std::pmr::unordered_set<int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+  {
+    using StdSet = std::unordered_multiset<V, DH, DP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_multiset<V>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::unordered_multiset<V, MH, DP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_multiset<V, MH>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    using StdSet = std::unordered_multiset<V, MH, MP, std::pmr::polymorphic_allocator<V>>;
+    using PmrSet = std::pmr::unordered_multiset<V, MH, MP>;
+    static_assert(std::is_same<StdSet, PmrSet>::value, "");
+  }
+  {
+    std::pmr::unordered_multiset<int> m;
+    assert(m.get_allocator().resource() == std::pmr::get_default_resource());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop2.pass.cpp
new file mode 100644
index 0000000000000..36cd6bf1acf7f
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_unordered_set_synop2.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <unordered_set>
+
+// namespace std::pmr {
+//
+// typedef ... unordered_set
+//
+// } // namespace std::pmr
+
+#include <unordered_set>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::unordered_set is usable without <memory_resource>.
+    std::pmr::unordered_set<int> s;
+    std::pmr::unordered_multiset<int> ms;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop.pass.cpp
new file mode 100644
index 0000000000000..0caca07096c30
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <vector>
+
+// namespace std::pmr {
+// template <class T>
+// using vector =
+//     ::std::vector<T, polymorphic_allocator<T>>
+//
+// } // namespace std::pmr
+
+#include <vector>
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+int main(int, char**) {
+  using StdVector = std::vector<int, std::pmr::polymorphic_allocator<int>>;
+  using PmrVector = std::pmr::vector<int>;
+  static_assert(std::is_same<StdVector, PmrVector>::value, "");
+  PmrVector d;
+  assert(d.get_allocator().resource() == std::pmr::get_default_resource());
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop2.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop2.pass.cpp
new file mode 100644
index 0000000000000..330f4bee3e7a8
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.aliases/header_vector_synop2.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <vector>
+
+// namespace std::pmr {
+//
+// typedef ... vector
+//
+// } // namespace std::pmr
+
+#include <vector>
+
+int main(int, char**) {
+  {
+    // Check that std::pmr::vector is usable without <memory_resource>.
+    std::pmr::vector<int> l;
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.global/default_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/default_resource.pass.cpp
new file mode 100644
index 0000000000000..7969643b1da3d
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/default_resource.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+//-----------------------------------------------------------------------------
+// TESTING memory_resource * get_default_resource() noexcept;
+//         memory_resource * set_default_resource(memory_resource*) noexcept;
+//
+// Concerns:
+//  A) 'get_default_resource()' returns a non-null memory_resource pointer.
+//  B) 'get_default_resource()' returns the value set by the last call to
+//     'set_default_resource(...)' and 'new_delete_resource()' if no call
+//     to 'set_default_resource(...)' has occurred.
+//  C) 'set_default_resource(...)' returns the previous value of the default
+//     resource.
+//  D) 'set_default_resource(T* p)' for a non-null 'p' sets the default resource
+//     to be 'p'.
+//  E) 'set_default_resource(null)' sets the default resource to
+//     'new_delete_resource()'.
+//  F) 'get_default_resource' and 'set_default_resource' are noexcept.
+
+#include <memory_resource>
+#include <cassert>
+
+#include "test_std_memory_resource.h"
+
+using namespace std::pmr;
+
+int main(int, char**) {
+  TestResource R;
+  { // Test (A) and (B)
+    memory_resource* p = get_default_resource();
+    assert(p != nullptr);
+    assert(p == new_delete_resource());
+    assert(p == get_default_resource());
+  }
+  { // Test (C) and (D)
+    memory_resource* expect = &R;
+    memory_resource* old    = set_default_resource(expect);
+    assert(old != nullptr);
+    assert(old == new_delete_resource());
+
+    memory_resource* p = get_default_resource();
+    assert(p != nullptr);
+    assert(p == expect);
+    assert(p == get_default_resource());
+  }
+  { // Test (E)
+    memory_resource* old = set_default_resource(nullptr);
+    assert(old == &R);
+    memory_resource* p = get_default_resource();
+    assert(p != nullptr);
+    assert(p == new_delete_resource());
+    assert(p == get_default_resource());
+  }
+  { // Test (F)
+    static_assert(noexcept(get_default_resource()), "get_default_resource() must be noexcept");
+
+    static_assert(noexcept(set_default_resource(nullptr)), "set_default_resource() must be noexcept");
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.global/new_delete_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/new_delete_resource.pass.cpp
new file mode 100644
index 0000000000000..bd8b8e9175c8c
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/new_delete_resource.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// memory_resource *new_delete_resource()
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+class assert_on_compare : public std::pmr::memory_resource {
+  void* do_allocate(size_t, size_t) override {
+    assert(false);
+    return nullptr;
+  }
+
+  void do_deallocate(void*, size_t, size_t) override { assert(false); }
+
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override {
+    assert(false);
+    return true;
+  }
+};
+
+void test_return() {
+  { ASSERT_SAME_TYPE(decltype(std::pmr::new_delete_resource()), std::pmr::memory_resource*); }
+  // assert not null
+  { assert(std::pmr::new_delete_resource()); }
+  // assert same return value
+  { assert(std::pmr::new_delete_resource() == std::pmr::new_delete_resource()); }
+}
+
+void test_equality() {
+  // Same object
+  {
+    std::pmr::memory_resource& r1 = *std::pmr::new_delete_resource();
+    std::pmr::memory_resource& r2 = *std::pmr::new_delete_resource();
+    // check both calls returned the same object
+    assert(&r1 == &r2);
+    // check for proper equality semantics
+    assert(r1 == r2);
+    assert(r2 == r1);
+    assert(!(r1 != r2));
+    assert(!(r2 != r1));
+  }
+  // Different types
+  {
+    std::pmr::memory_resource& r1 = *std::pmr::new_delete_resource();
+    assert_on_compare c;
+    std::pmr::memory_resource& r2 = c;
+    assert(r1 != r2);
+    assert(!(r1 == r2));
+  }
+}
+
+void test_allocate_deallocate() {
+  std::pmr::memory_resource& r1 = *std::pmr::new_delete_resource();
+
+  globalMemCounter.reset();
+
+  void* ret = r1.allocate(50);
+  assert(ret);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkOutstandingNewEq(1));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewSizeEq(50));
+
+  r1.deallocate(ret, 1);
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+}
+
+int main(int, char**) {
+  ASSERT_NOEXCEPT(std::pmr::new_delete_resource());
+  test_return();
+  test_equality();
+  test_allocate_deallocate();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.global/null_memory_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/null_memory_resource.pass.cpp
new file mode 100644
index 0000000000000..f0e0bbeb5a1c2
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.global/null_memory_resource.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// memory_resource *null_memory_resource()
+
+#include <memory_resource>
+#include <cassert>
+#include <cstddef> // size_t
+#include <new>
+#include <type_traits>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+struct assert_on_compare : public std::pmr::memory_resource {
+  void* do_allocate(size_t, size_t) override {
+    assert(false);
+    return nullptr;
+  }
+
+  void do_deallocate(void*, size_t, size_t) override { assert(false); }
+
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override {
+    assert(false);
+    return true;
+  }
+};
+
+void test_return() {
+  { ASSERT_SAME_TYPE(decltype(std::pmr::null_memory_resource()), std::pmr::memory_resource*); }
+  // Test that the returned value is not null
+  { assert(std::pmr::null_memory_resource()); }
+  // Test the same value is returned by repeated calls.
+  { assert(std::pmr::null_memory_resource() == std::pmr::null_memory_resource()); }
+}
+
+void test_equality() {
+  // Same object
+  {
+    std::pmr::memory_resource& r1 = *std::pmr::null_memory_resource();
+    std::pmr::memory_resource& r2 = *std::pmr::null_memory_resource();
+    // check both calls returned the same object
+    assert(&r1 == &r2);
+    // check for proper equality semantics
+    assert(r1 == r2);
+    assert(r2 == r1);
+    assert(!(r1 != r2));
+    assert(!(r2 != r1));
+    // check the is_equal method
+    assert(r1.is_equal(r2));
+    assert(r2.is_equal(r1));
+  }
+  // Different types
+  {
+    std::pmr::memory_resource& r1 = *std::pmr::null_memory_resource();
+    assert_on_compare c;
+    std::pmr::memory_resource& r2 = c;
+    assert(r1 != r2);
+    assert(!(r1 == r2));
+    assert(!r1.is_equal(r2));
+  }
+}
+
+void test_allocate() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  DisableAllocationGuard g; // null_memory_resource shouldn't allocate.
+  try {
+    std::pmr::null_memory_resource()->allocate(1);
+    assert(false);
+  } catch (std::bad_alloc const&) {
+    // do nothing
+  } catch (...) {
+    assert(false);
+  }
+#endif
+}
+
+void test_deallocate() {
+  globalMemCounter.reset();
+
+  int x = 42;
+  std::pmr::null_memory_resource()->deallocate(nullptr, 0);
+  std::pmr::null_memory_resource()->deallocate(&x, 0);
+
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+  assert(globalMemCounter.checkDeleteArrayCalledEq(0));
+}
+
+int main(int, char**) {
+  test_return();
+  test_equality();
+  test_allocate();
+  test_deallocate();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/copy_move.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/copy_move.pass.cpp
new file mode 100644
index 0000000000000..053bd692efcfd
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/copy_move.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// monotonic_buffer_resource(monotonic_buffer_resource const&) = delete;
+// monotonic_buffer_resource& operator=(monotonic_buffer_resource const&) = delete;
+
+#include <memory_resource>
+#include <type_traits>
+
+int main(int, char**) {
+  using MBR = std::pmr::monotonic_buffer_resource;
+  static_assert(!std::is_copy_constructible_v<MBR>);
+  static_assert(!std::is_move_constructible_v<MBR>);
+  static_assert(!std::is_copy_assignable_v<MBR>);
+  static_assert(!std::is_move_assignable_v<MBR>);
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/with_default_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/with_default_resource.pass.cpp
new file mode 100644
index 0000000000000..ff93f8210c99b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/with_default_resource.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+int main(int, char**) {
+  std::pmr::memory_resource* expected = std::pmr::null_memory_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    char buffer[16];
+    std::pmr::monotonic_buffer_resource r1;
+    std::pmr::monotonic_buffer_resource r2(16);
+    std::pmr::monotonic_buffer_resource r3(buffer, sizeof buffer);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+    assert(r3.upstream_resource() == expected);
+  }
+
+  expected = std::pmr::new_delete_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    char buffer[16];
+    std::pmr::monotonic_buffer_resource r1;
+    std::pmr::monotonic_buffer_resource r2(16);
+    std::pmr::monotonic_buffer_resource r3(buffer, sizeof buffer);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+    assert(r3.upstream_resource() == expected);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/without_buffer.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/without_buffer.pass.cpp
new file mode 100644
index 0000000000000..8adebb7758781
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/without_buffer.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+
+int main(int, char**) {
+  // Constructing a monotonic_buffer_resource should not cause allocations
+  // by itself; the resource should wait to allocate until an allocation is
+  // requested.
+
+  globalMemCounter.reset();
+  std::pmr::set_default_resource(std::pmr::new_delete_resource());
+
+  std::pmr::monotonic_buffer_resource r1;
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  std::pmr::monotonic_buffer_resource r2(1024);
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  std::pmr::monotonic_buffer_resource r3(1024, std::pmr::new_delete_resource());
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_deallocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_deallocate.pass.cpp
new file mode 100644
index 0000000000000..f75198a0d98d8
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_deallocate.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  {
+    globalMemCounter.reset();
+
+    auto mono1                    = std::pmr::monotonic_buffer_resource(std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = mono1;
+
+    void* ret = r1.allocate(50);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    // mem.res.monotonic.buffer 1.2
+    // A call to deallocate has no effect, thus the amount of memory
+    // consumed increases monotonically until the resource is destroyed.
+    // Check that deallocate is a no-op
+    r1.deallocate(ret, 50);
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    mono1.release();
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+
+    globalMemCounter.reset();
+
+    ret = r1.allocate(500);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    // Check that the destructor calls release()
+  }
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_exception_safety.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_exception_safety.pass.cpp
new file mode 100644
index 0000000000000..d8f8dac433c79
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_exception_safety.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: no-exceptions
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+struct repointable_resource : public std::pmr::memory_resource {
+  std::pmr::memory_resource* which;
+
+  explicit repointable_resource(std::pmr::memory_resource* res) : which(res) {}
+
+private:
+  void* do_allocate(size_t size, size_t align) override { return which->allocate(size, align); }
+
+  void do_deallocate(void* p, size_t size, size_t align) override { return which->deallocate(p, size, align); }
+
+  bool do_is_equal(std::pmr::memory_resource const& rhs) const noexcept override { return which->is_equal(rhs); }
+};
+
+void test_exception_safety() {
+  globalMemCounter.reset();
+  auto upstream = repointable_resource(std::pmr::new_delete_resource());
+  alignas(16) char buffer[64];
+  auto mono1                    = std::pmr::monotonic_buffer_resource(buffer, sizeof buffer, &upstream);
+  std::pmr::memory_resource& r1 = mono1;
+
+  void* res = r1.allocate(64, 16);
+  assert(res == buffer);
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  res = r1.allocate(64, 16);
+  assert(res != buffer);
+  assert(globalMemCounter.checkNewCalledEq(1));
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+  const size_t last_new_size = globalMemCounter.last_new_size;
+
+  upstream.which = std::pmr::null_memory_resource();
+  try {
+    res = r1.allocate(last_new_size, 16);
+    assert(false);
+  } catch (const std::bad_alloc&) {
+    // we expect this
+  }
+  assert(globalMemCounter.checkNewCalledEq(1));
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  upstream.which = std::pmr::new_delete_resource();
+  res            = r1.allocate(last_new_size, 16);
+  assert(res != buffer);
+  assert(globalMemCounter.checkNewCalledEq(2));
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  mono1.release();
+  assert(globalMemCounter.checkNewCalledEq(2));
+  assert(globalMemCounter.checkDeleteCalledEq(2));
+}
+
+int main(int, char**) {
+#if TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS && !defined(DISABLE_NEW_COUNT)
+  test_exception_safety();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_initial_buffer.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_initial_buffer.pass.cpp
new file mode 100644
index 0000000000000..446030eb6afba
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_initial_buffer.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  char buffer[100];
+  auto mono1 = std::pmr::monotonic_buffer_resource(buffer, sizeof buffer, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = mono1;
+
+  // Check that construction with a buffer does not allocate anything from the upstream
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  // Check that an allocation that fits in the buffer does not allocate anything from the upstream
+  void* ret = r1.allocate(50);
+  assert(ret);
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  // Check a second allocation
+  ret = r1.allocate(20);
+  assert(ret);
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  r1.deallocate(ret, 50);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  // Check an allocation that doesn't fit in the original buffer
+  ret = r1.allocate(50);
+  assert(ret);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+
+  r1.deallocate(ret, 50);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  mono1.release();
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
new file mode 100644
index 0000000000000..e35d9bd6fd5a4
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  {
+    alignas(4) char buffer[17];
+    auto mono1 = std::pmr::monotonic_buffer_resource(buffer + 1, 16, std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = mono1;
+
+    void* ret = r1.allocate(1, 1);
+    assert(ret == buffer + 1);
+    mono1.release();
+
+    ret = r1.allocate(1, 2);
+    assert(ret == buffer + 2);
+    mono1.release();
+
+    ret = r1.allocate(1, 4);
+    assert(ret == buffer + 4);
+    mono1.release();
+
+    // Test a size that is just big enough to fit in the buffer,
+    // but can't fit if it's aligned.
+    ret = r1.allocate(16, 1);
+    assert(ret == buffer + 1);
+    mono1.release();
+
+    assert(globalMemCounter.checkNewCalledEq(0));
+    ret = r1.allocate(16, 2);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewSizeGe(16));
+    mono1.release();
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_zero_sized_buffer.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_zero_sized_buffer.pass.cpp
new file mode 100644
index 0000000000000..acd4ca5b1f809
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_zero_sized_buffer.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  {
+    char buffer[100];
+    auto mono1                    = std::pmr::monotonic_buffer_resource(buffer, 0, std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = mono1;
+
+    void* ret = r1.allocate(1, 1);
+    assert(ret != nullptr);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+  }
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  globalMemCounter.reset();
+  {
+    auto mono1                    = std::pmr::monotonic_buffer_resource(nullptr, 0, std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = mono1;
+
+    void* ret = r1.allocate(1, 1);
+    assert(ret != nullptr);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+  }
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
new file mode 100644
index 0000000000000..ffe17d13a8233
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+void test_geometric_progression() {
+  // mem.res.monotonic.buffer 1.3
+  // Each additional buffer is larger than the previous one, following a
+  // geometric progression.
+
+  globalMemCounter.reset();
+  std::pmr::monotonic_buffer_resource mono1(100, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = mono1;
+
+  assert(globalMemCounter.checkNewCalledEq(0));
+  size_t next_buffer_size = 100;
+  void* ret               = r1.allocate(10, 1);
+  assert(ret != nullptr);
+  assert(globalMemCounter.checkNewCalledEq(1));
+  assert(globalMemCounter.last_new_size >= next_buffer_size);
+  next_buffer_size = globalMemCounter.last_new_size + 1;
+
+  int new_called = 1;
+  while (new_called < 5) {
+    ret = r1.allocate(10, 1);
+    if (globalMemCounter.new_called > new_called) {
+      assert(globalMemCounter.new_called == new_called + 1);
+      assert(globalMemCounter.last_new_size >= next_buffer_size);
+      next_buffer_size = globalMemCounter.last_new_size + 1;
+      new_called += 1;
+    }
+  }
+}
+
+int main(int, char**) {
+#if TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS && !defined(DISABLE_NEW_COUNT)
+  test_geometric_progression();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_overaligned_request.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_overaligned_request.pass.cpp
new file mode 100644
index 0000000000000..d2b8454ae30c2
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_overaligned_request.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  auto mono1                    = std::pmr::monotonic_buffer_resource(1024, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = mono1;
+
+  constexpr size_t big_alignment = 8 * alignof(std::max_align_t);
+  static_assert(big_alignment > 4);
+
+  void* ret = r1.allocate(2048, big_alignment);
+  assert(ret != nullptr);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkAlignedNewCalledEq(1));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewSizeGe(2048));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewAlignEq(big_alignment));
+
+  // Check that a single highly aligned allocation request doesn't
+  // permanently "poison" the resource to allocate only super-aligned
+  // blocks of memory.
+  ret = r1.allocate(globalMemCounter.last_new_size, 4);
+  assert(ret != nullptr);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(2));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkAlignedNewCalledEq(1));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_with_initial_size.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_with_initial_size.pass.cpp
new file mode 100644
index 0000000000000..e21015f96c50c
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_with_initial_size.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+void test(size_t initial_buffer_size) {
+  globalMemCounter.reset();
+
+  auto mono1 = std::pmr::monotonic_buffer_resource(initial_buffer_size, std::pmr::new_delete_resource());
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  mono1.allocate(1, 1);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewSizeGe(initial_buffer_size));
+
+  mono1.allocate(initial_buffer_size - 1, 1);
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+}
+
+int main(int, char**) {
+  test(1);
+  test(8);
+  test(10);
+  test(100);
+  test(256);
+  test(1000);
+  test(1024);
+  test(1000000);
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/equality.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/equality.pass.cpp
new file mode 100644
index 0000000000000..426331056af68
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/equality.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <cstddef> // size_t
+
+struct assert_on_compare : public std::pmr::memory_resource {
+  void* do_allocate(size_t, size_t) override {
+    assert(false);
+    return nullptr;
+  }
+
+  void do_deallocate(void*, size_t, size_t) override { assert(false); }
+
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override {
+    assert(false);
+    return true;
+  }
+};
+
+int main(int, char**) {
+  // Same object
+  {
+    std::pmr::monotonic_buffer_resource r1;
+    std::pmr::monotonic_buffer_resource r2;
+    assert(r1 == r1);
+    assert(r1 != r2);
+
+    std::pmr::memory_resource& p1 = r1;
+    std::pmr::memory_resource& p2 = r2;
+    assert(p1 == p1);
+    assert(p1 != p2);
+    assert(p1 == r1);
+    assert(r1 == p1);
+    assert(p1 != r2);
+    assert(r2 != p1);
+  }
+  // Different types
+  {
+    std::pmr::monotonic_buffer_resource mono1;
+    std::pmr::memory_resource& r1 = mono1;
+    assert_on_compare c;
+    std::pmr::memory_resource& r2 = c;
+    assert(r1 != r2);
+    assert(!(r1 == r2));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/ctor_does_not_allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/ctor_does_not_allocate.pass.cpp
new file mode 100644
index 0000000000000..323bc4362acc2
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/ctor_does_not_allocate.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+
+template <class PoolResource>
+void test() {
+  // Constructing a pool resource should not cause allocations
+  // by itself; the resource should wait to allocate until an
+  // allocation is requested.
+
+  globalMemCounter.reset();
+  std::pmr::set_default_resource(std::pmr::new_delete_resource());
+
+  PoolResource r1;
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  PoolResource r2(std::pmr::pool_options{1024, 2048});
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  PoolResource r3(std::pmr::pool_options{1024, 2048}, std::pmr::new_delete_resource());
+  assert(globalMemCounter.checkNewCalledEq(0));
+}
+
+int main(int, char**) {
+  test<std::pmr::unsynchronized_pool_resource>();
+  test<std::pmr::synchronized_pool_resource>();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/sync_with_default_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/sync_with_default_resource.pass.cpp
new file mode 100644
index 0000000000000..6597768feda8f
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/sync_with_default_resource.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+
+int main(int, char**) {
+  std::pmr::memory_resource* expected = std::pmr::null_memory_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    std::pmr::pool_options opts{0, 0};
+    std::pmr::synchronized_pool_resource r1;
+    std::pmr::synchronized_pool_resource r2(opts);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+  }
+
+  expected = std::pmr::new_delete_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    std::pmr::pool_options opts{1024, 2048};
+    std::pmr::synchronized_pool_resource r1;
+    std::pmr::synchronized_pool_resource r2(opts);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/unsync_with_default_resource.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/unsync_with_default_resource.pass.cpp
new file mode 100644
index 0000000000000..72a4bd91d31eb
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.ctor/unsync_with_default_resource.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+
+int main(int, char**) {
+  std::pmr::memory_resource* expected = std::pmr::null_memory_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    std::pmr::pool_options opts{0, 0};
+    std::pmr::unsynchronized_pool_resource r1;
+    std::pmr::unsynchronized_pool_resource r2(opts);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+  }
+
+  expected = std::pmr::new_delete_resource();
+  std::pmr::set_default_resource(expected);
+  {
+    std::pmr::pool_options opts{1024, 2048};
+    std::pmr::unsynchronized_pool_resource r1;
+    std::pmr::unsynchronized_pool_resource r2(opts);
+    assert(r1.upstream_resource() == expected);
+    assert(r2.upstream_resource() == expected);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/equality.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/equality.pass.cpp
new file mode 100644
index 0000000000000..39f0a11d6ac5e
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/equality.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <new>
+#include <type_traits>
+
+#include "count_new.h"
+
+class assert_on_compare : public std::pmr::memory_resource {
+  void* do_allocate(size_t, size_t) override {
+    assert(false);
+    return nullptr;
+  }
+
+  void do_deallocate(void*, size_t, size_t) override { assert(false); }
+
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override {
+    assert(false);
+    return true;
+  }
+};
+
+template <class PoolResource>
+void test() {
+  // Same type
+  {
+    PoolResource pr1;
+    PoolResource pr2;
+    assert(pr1 == pr1);
+    assert(pr1 != pr2);
+
+    std::pmr::memory_resource& mr1 = pr1;
+    std::pmr::memory_resource& mr2 = pr2;
+    assert(mr1 == mr1);
+    assert(mr1 != mr2);
+    assert(mr1 == pr1);
+    assert(pr1 == mr1);
+    assert(mr1 != pr2);
+    assert(pr2 != mr1);
+  }
+  // Different types
+  {
+    PoolResource pr1;
+    std::pmr::memory_resource& mr1 = pr1;
+    assert_on_compare c;
+    std::pmr::memory_resource& mr2 = c;
+    assert(mr1 != mr2);
+    assert(!(mr1 == mr2));
+  }
+}
+
+int main(int, char**) {
+  test<std::pmr::synchronized_pool_resource>();
+  test<std::pmr::unsynchronized_pool_resource>();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate.pass.cpp
new file mode 100644
index 0000000000000..fb905533faabe
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  {
+    auto sync1                    = std::pmr::synchronized_pool_resource(std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = sync1;
+
+    void* ret = r1.allocate(50);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(0));
+
+    r1.deallocate(ret, 50);
+    sync1.release();
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledGreaterThan(0));
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+
+    globalMemCounter.reset();
+
+    ret = r1.allocate(500);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    // Check that the destructor calls release()
+  }
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledGreaterThan(0));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_overaligned_request.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_overaligned_request.pass.cpp
new file mode 100644
index 0000000000000..d962d7f3d978b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_overaligned_request.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <memory> // std::align
+
+#include "count_new.h"
+#include "test_macros.h"
+
+bool is_aligned_to(void* p, size_t alignment) {
+  void* p2     = p;
+  size_t space = 1;
+  void* result = std::align(alignment, 1, p2, space);
+  return (result == p);
+}
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  std::pmr::pool_options opts{1, 1024};
+  std::pmr::synchronized_pool_resource sync1(opts, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = sync1;
+
+  constexpr size_t big_alignment = 8 * alignof(std::max_align_t);
+  static_assert(big_alignment > 4);
+
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  void* ret = r1.allocate(2048, big_alignment);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, big_alignment));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+
+  ret = r1.allocate(16, 4);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 4));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(1));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_reuse_blocks.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_reuse_blocks.pass.cpp
new file mode 100644
index 0000000000000..1fbc2b0e3fc87
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_allocate_reuse_blocks.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <memory> // std::align
+
+#include "count_new.h"
+#include "test_macros.h"
+
+static bool is_aligned_to(void* p, size_t alignment) {
+  void* p2     = p;
+  size_t space = 1;
+  void* result = std::align(alignment, 1, p2, space);
+  return (result == p);
+}
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  std::pmr::pool_options opts{1, 256};
+  auto sync1                    = std::pmr::synchronized_pool_resource(opts, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = sync1;
+
+  void* ret = r1.allocate(8);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 8));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+  int new_called = globalMemCounter.new_called;
+
+  // After deallocation, the pool for 8-byte blocks should have at least one vacancy.
+  r1.deallocate(ret, 8);
+  assert(globalMemCounter.new_called == new_called);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  // This should return an existing block from the pool: no new allocations.
+  ret = r1.allocate(8);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 8));
+  assert(globalMemCounter.new_called == new_called);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_deallocate_matches_allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_deallocate_matches_allocate.pass.cpp
new file mode 100644
index 0000000000000..26101d8e71c28
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/sync_deallocate_matches_allocate.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <algorithm>
+#include <cassert>
+#include <new>
+#include <vector>
+
+struct allocation_record {
+  size_t bytes;
+  size_t align;
+  explicit allocation_record(size_t b, size_t a) : bytes(b), align(a) {}
+  bool operator==(const allocation_record& rhs) const { return (bytes == rhs.bytes) && (align == rhs.align); }
+  bool operator<(const allocation_record& rhs) const {
+    if (bytes != rhs.bytes)
+      return (bytes < rhs.bytes);
+    return (align < rhs.align);
+  }
+};
+
+class test_resource : public std::pmr::memory_resource {
+  void* do_allocate(size_t bytes, size_t align) override {
+    void* result = std::pmr::new_delete_resource()->allocate(bytes, align);
+    successful_allocations.emplace_back(bytes, align);
+    return result;
+  }
+  void do_deallocate(void* p, size_t bytes, size_t align) override {
+    deallocations.emplace_back(bytes, align);
+    return std::pmr::new_delete_resource()->deallocate(p, bytes, align);
+  }
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override { return false; }
+
+public:
+  std::vector<allocation_record> successful_allocations;
+  std::vector<allocation_record> deallocations;
+};
+
+template <class F>
+void test_allocation_pattern(F do_pattern) {
+  test_resource tr;
+  std::pmr::pool_options opts{0, 256};
+  std::pmr::synchronized_pool_resource spr(opts, &tr);
+
+  try {
+    do_pattern(spr);
+  } catch (const std::bad_alloc&) {
+  }
+  spr.release();
+
+  assert(tr.successful_allocations.size() == tr.deallocations.size());
+  assert(std::is_permutation(
+      tr.successful_allocations.begin(),
+      tr.successful_allocations.end(),
+      tr.deallocations.begin(),
+      tr.deallocations.end()));
+}
+
+template <size_t Bytes, size_t Align>
+auto foo() {
+  return [=](auto& mr) {
+    void* p = mr.allocate(Bytes, Align);
+    mr.deallocate(p, Bytes, Align);
+  };
+}
+
+int main(int, char**) {
+  test_allocation_pattern(foo<2, 1>());
+  test_allocation_pattern(foo<2, 8>());
+  test_allocation_pattern(foo<2, 64>());
+  test_allocation_pattern(foo<128, 1>());
+  test_allocation_pattern(foo<128, 8>());
+  test_allocation_pattern(foo<128, 64>());
+  test_allocation_pattern(foo<1024, 1>());
+  test_allocation_pattern(foo<1024, 8>());
+  test_allocation_pattern(foo<1024, 64>());
+
+  test_allocation_pattern([](auto& mr) {
+    void* p1 = mr.allocate(2, 1);
+    void* p2 = mr.allocate(2, 8);
+    void* p3 = mr.allocate(2, 64);
+    void* p4 = mr.allocate(128, 1);
+    void* p5 = mr.allocate(128, 8);
+    void* p6 = mr.allocate(128, 64);
+    void* p7 = mr.allocate(1024, 1);
+    void* p8 = mr.allocate(1024, 8);
+    void* p9 = mr.allocate(1024, 64);
+    mr.deallocate(p1, 2, 1);
+    mr.deallocate(p2, 2, 8);
+    mr.deallocate(p3, 2, 64);
+    mr.deallocate(p4, 128, 1);
+    mr.deallocate(p5, 128, 8);
+    mr.deallocate(p6, 128, 64);
+    mr.deallocate(p7, 1024, 1);
+    mr.deallocate(p8, 1024, 8);
+    mr.deallocate(p9, 1024, 64);
+  });
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate.pass.cpp
new file mode 100644
index 0000000000000..69d4f2e00afd4
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  {
+    auto unsync1                  = std::pmr::unsynchronized_pool_resource(std::pmr::new_delete_resource());
+    std::pmr::memory_resource& r1 = unsync1;
+
+    void* ret = r1.allocate(50);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    r1.deallocate(ret, 50);
+    unsync1.release();
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledGreaterThan(0));
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+
+    globalMemCounter.reset();
+
+    ret = r1.allocate(500);
+    assert(ret);
+    ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+    assert(globalMemCounter.checkDeleteCalledEq(0));
+
+    // Check that the destructor calls release()
+  }
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledGreaterThan(0));
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_overaligned_request.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_overaligned_request.pass.cpp
new file mode 100644
index 0000000000000..a316750231724
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_overaligned_request.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <memory> // std::align
+
+#include "count_new.h"
+#include "test_macros.h"
+
+bool is_aligned_to(void* p, size_t alignment) {
+  void* p2     = p;
+  size_t space = 1;
+  void* result = std::align(alignment, 1, p2, space);
+  return (result == p);
+}
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  std::pmr::pool_options opts{1, 1024};
+  auto unsync1                  = std::pmr::unsynchronized_pool_resource(opts, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = unsync1;
+
+  constexpr size_t big_alignment = 8 * alignof(std::max_align_t);
+  static_assert(big_alignment > 4);
+
+  assert(globalMemCounter.checkNewCalledEq(0));
+
+  void* ret = r1.allocate(2048, big_alignment);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, big_alignment));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+
+  ret = r1.allocate(16, 4);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 4));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(1));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_reuse_blocks.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_reuse_blocks.pass.cpp
new file mode 100644
index 0000000000000..72087e88d78e6
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_allocate_reuse_blocks.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <memory> // std::align
+
+#include "count_new.h"
+#include "test_macros.h"
+
+static bool is_aligned_to(void* p, size_t alignment) {
+  void* p2     = p;
+  size_t space = 1;
+  void* result = std::align(alignment, 1, p2, space);
+  return (result == p);
+}
+
+int main(int, char**) {
+  globalMemCounter.reset();
+  std::pmr::pool_options opts{1, 256};
+  auto unsync1                  = std::pmr::unsynchronized_pool_resource(opts, std::pmr::new_delete_resource());
+  std::pmr::memory_resource& r1 = unsync1;
+
+  void* ret = r1.allocate(8);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 8));
+  ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledGreaterThan(0));
+  int new_called = globalMemCounter.new_called;
+
+  // After deallocation, the pool for 8-byte blocks should have at least one vacancy.
+  r1.deallocate(ret, 8);
+  assert(globalMemCounter.new_called == new_called);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  // This should return an existing block from the pool: no new allocations.
+  ret = r1.allocate(8);
+  assert(ret != nullptr);
+  assert(is_aligned_to(ret, 8));
+  assert(globalMemCounter.new_called == new_called);
+  assert(globalMemCounter.checkDeleteCalledEq(0));
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_deallocate_matches_allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_deallocate_matches_allocate.pass.cpp
new file mode 100644
index 0000000000000..2863cba6dd94b
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res.pool/mem.res.pool.mem/unsync_deallocate_matches_allocate.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: c++03, c++11, c++14
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}}
+
+// <memory_resource>
+
+// class unsynchronized_pool_resource
+
+#include <memory_resource>
+#include <algorithm>
+#include <cassert>
+#include <new>
+#include <vector>
+
+struct allocation_record {
+  size_t bytes;
+  size_t align;
+  explicit allocation_record(size_t b, size_t a) : bytes(b), align(a) {}
+  bool operator==(const allocation_record& rhs) const { return (bytes == rhs.bytes) && (align == rhs.align); }
+  bool operator<(const allocation_record& rhs) const {
+    if (bytes != rhs.bytes)
+      return (bytes < rhs.bytes);
+    return (align < rhs.align);
+  }
+};
+
+class test_resource : public std::pmr::memory_resource {
+  void* do_allocate(size_t bytes, size_t align) override {
+    void* result = std::pmr::new_delete_resource()->allocate(bytes, align);
+    successful_allocations.emplace_back(bytes, align);
+    return result;
+  }
+  void do_deallocate(void* p, size_t bytes, size_t align) override {
+    deallocations.emplace_back(bytes, align);
+    return std::pmr::new_delete_resource()->deallocate(p, bytes, align);
+  }
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override { return false; }
+
+public:
+  std::vector<allocation_record> successful_allocations;
+  std::vector<allocation_record> deallocations;
+};
+
+template <class F>
+void test_allocation_pattern(F do_pattern) {
+  test_resource tr;
+  std::pmr::pool_options opts{0, 256};
+  std::pmr::unsynchronized_pool_resource uspr(opts, &tr);
+
+  try {
+    do_pattern(uspr);
+  } catch (const std::bad_alloc&) {
+  }
+  uspr.release();
+
+  assert(tr.successful_allocations.size() == tr.deallocations.size());
+  assert(std::is_permutation(
+      tr.successful_allocations.begin(),
+      tr.successful_allocations.end(),
+      tr.deallocations.begin(),
+      tr.deallocations.end()));
+}
+
+template <size_t Bytes, size_t Align>
+auto foo() {
+  return [=](auto& mr) {
+    void* p = mr.allocate(Bytes, Align);
+    mr.deallocate(p, Bytes, Align);
+  };
+}
+
+int main(int, char**) {
+  test_allocation_pattern(foo<2, 1>());
+  test_allocation_pattern(foo<2, 8>());
+  test_allocation_pattern(foo<2, 64>());
+  test_allocation_pattern(foo<128, 1>());
+  test_allocation_pattern(foo<128, 8>());
+  test_allocation_pattern(foo<128, 64>());
+  test_allocation_pattern(foo<1024, 1>());
+  test_allocation_pattern(foo<1024, 8>());
+  test_allocation_pattern(foo<1024, 64>());
+
+  test_allocation_pattern([](auto& mr) {
+    void* p1 = mr.allocate(2, 1);
+    void* p2 = mr.allocate(2, 8);
+    void* p3 = mr.allocate(2, 64);
+    void* p4 = mr.allocate(128, 1);
+    void* p5 = mr.allocate(128, 8);
+    void* p6 = mr.allocate(128, 64);
+    void* p7 = mr.allocate(1024, 1);
+    void* p8 = mr.allocate(1024, 8);
+    void* p9 = mr.allocate(1024, 64);
+    mr.deallocate(p1, 2, 1);
+    mr.deallocate(p2, 2, 8);
+    mr.deallocate(p3, 2, 64);
+    mr.deallocate(p4, 128, 1);
+    mr.deallocate(p5, 128, 8);
+    mr.deallocate(p6, 128, 64);
+    mr.deallocate(p7, 1024, 1);
+    mr.deallocate(p8, 1024, 8);
+    mr.deallocate(p9, 1024, 64);
+  });
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/construct.fail.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/construct.fail.cpp
new file mode 100644
index 0000000000000..acea9615275c3
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/construct.fail.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// Check that memory_resource is not constructible
+
+#include <memory_resource>
+
+void test() {
+  std::pmr::memory_resource m; // expected-error {{variable type 'std::pmr::memory_resource' is an abstract class}}
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/equal.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/equal.pass.cpp
new file mode 100644
index 0000000000000..eb8c4a2f33d35
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/equal.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// bool operator==(memory_resource const &, memory_resource const &) noexcept;
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  // check return types
+  {
+    const std::pmr::memory_resource* mr1 = nullptr;
+    const std::pmr::memory_resource* mr2 = nullptr;
+    ASSERT_SAME_TYPE(decltype(*mr1 == *mr2), bool);
+    ASSERT_NOEXCEPT(*mr1 == *mr2);
+  }
+  // equal
+  {
+    TestResource r1(1);
+    TestResource r2(1);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r2;
+
+    assert(mr1 == mr2);
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(0));
+
+    assert(mr2 == mr1);
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(1));
+  }
+  // equal same object
+  {
+    TestResource r1(1);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r1;
+
+    assert(mr1 == mr2);
+    assert(r1.checkIsEqualCalledEq(0));
+
+    assert(mr2 == mr1);
+    assert(r1.checkIsEqualCalledEq(0));
+  }
+  // not equal
+  {
+    TestResource r1(1);
+    TestResource r2(2);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r2;
+
+    assert(!(mr1 == mr2));
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(0));
+
+    assert(!(mr2 == mr1));
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(1));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/not_equal.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/not_equal.pass.cpp
new file mode 100644
index 0000000000000..d34295257c160
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.eq/not_equal.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// bool operator!=(memory_resource const &, memory_resource const &) noexcept;
+
+#include <memory_resource>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  // check return types
+  {
+    const std::pmr::memory_resource* mr1 = nullptr;
+    const std::pmr::memory_resource* mr2 = nullptr;
+    ASSERT_SAME_TYPE(decltype(*mr1 != *mr2), bool);
+    ASSERT_NOEXCEPT(*mr1 != *mr2);
+  }
+  // not equal
+  {
+    TestResource r1(1);
+    TestResource r2(2);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r2;
+
+    assert(mr1 != mr2);
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(0));
+
+    assert(mr2 != mr1);
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(1));
+  }
+  // equal
+  {
+    TestResource r1(1);
+    TestResource r2(1);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r2;
+
+    assert(!(mr1 != mr2));
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(0));
+
+    assert(!(mr2 != mr1));
+    assert(r1.checkIsEqualCalledEq(1));
+    assert(r2.checkIsEqualCalledEq(1));
+  }
+  // equal same object
+  {
+    TestResource r1(1);
+    const std::pmr::memory_resource& mr1 = r1;
+    const std::pmr::memory_resource& mr2 = r1;
+
+    assert(!(mr1 != mr2));
+    assert(r1.checkIsEqualCalledEq(0));
+
+    assert(!(mr2 != mr1));
+    assert(r1.checkIsEqualCalledEq(0));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/private_members.fail.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/private_members.fail.cpp
new file mode 100644
index 0000000000000..f17c8132059b8
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/private_members.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// memory_resource::do_allocate(size_t, size_t);          /* private */
+// memory_resource::do_deallocate(void*, size_t, size_t); /* private */
+// memory_resource::do_is_equal(memory_resource const&);  /* private */
+
+#include <memory_resource>
+
+void test() {
+  std::pmr::memory_resource* m = std::pmr::new_delete_resource();
+  m->do_allocate(0, 0);            // expected-error{{'do_allocate' is a private member}}
+  m->do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a private member}}
+  m->do_is_equal(*m);              // expected-error{{'do_is_equal' is a private member}}
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/protected_members.fail.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/protected_members.fail.cpp
new file mode 100644
index 0000000000000..bfd60239c9591
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.private/protected_members.fail.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+// monotonic_buffer_resource::do_allocate(size_t, size_t);          /* protected */
+// monotonic_buffer_resource::do_deallocate(void*, size_t, size_t); /* protected */
+// monotonic_buffer_resource::do_is_equal(memory_resource const&);  /* protected */
+
+// synchronized_pool_resource::do_allocate(size_t, size_t);          /* protected */
+// synchronized_pool_resource::do_deallocate(void*, size_t, size_t); /* protected */
+// synchronized_pool_resource::do_is_equal(memory_resource const&);  /* protected */
+
+// unsynchronized_pool_resource::do_allocate(size_t, size_t);          /* protected */
+// unsynchronized_pool_resource::do_deallocate(void*, size_t, size_t); /* protected */
+// unsynchronized_pool_resource::do_is_equal(memory_resource const&);  /* protected */
+
+#include <memory_resource>
+
+void test() {
+  {
+    std::pmr::monotonic_buffer_resource m;
+    m.do_allocate(0, 0);            // expected-error{{'do_allocate' is a protected member}}
+    m.do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}}
+    m.do_is_equal(m);               // expected-error{{'do_is_equal' is a protected member}}
+  }
+  {
+    std::pmr::synchronized_pool_resource m;
+    m.do_allocate(0, 0);            // expected-error{{'do_allocate' is a protected member}}
+    m.do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}}
+    m.do_is_equal(m);               // expected-error{{'do_is_equal' is a protected member}}
+  }
+  {
+    std::pmr::unsynchronized_pool_resource m;
+    m.do_allocate(0, 0);            // expected-error{{'do_allocate' is a protected member}}
+    m.do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}}
+    m.do_is_equal(m);               // expected-error{{'do_is_equal' is a protected member}}
+  }
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/allocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/allocate.pass.cpp
new file mode 100644
index 0000000000000..e011227f23dc1
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/allocate.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory_resource>
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+//------------------------------------------------------------------------------
+// TESTING void *memory_resource::allocate(size_t, size_t = max_align)
+//
+// Concerns:
+//  A) 'memory_resource' contains a member 'allocate' with the required
+//     signature, including the default alignment parameter.
+//  B) The return type of 'allocate' is 'void*'.
+//  C) 'allocate' is not marked as 'noexcept'.
+//  D) Invoking 'allocate' invokes 'do_allocate' with the same arguments.
+//  E) If 'do_allocate' throws then 'allocate' propagates that exception.
+
+#include <memory_resource>
+#include <cassert>
+#include <cstddef>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  TestResource R(42);
+  auto& P                      = R.getController();
+  std::pmr::memory_resource& M = R;
+  {
+    static_assert(std::is_same<decltype(M.allocate(0, 0)), void*>::value, "Must be void*");
+    static_assert(std::is_same<decltype(M.allocate(0)), void*>::value, "Must be void*");
+  }
+  {
+    static_assert(!noexcept(M.allocate(0, 0)), "Must not be noexcept.");
+    static_assert(!noexcept(M.allocate(0)), "Must not be noexcept.");
+  }
+  {
+    int s   = 42;
+    int a   = 64;
+    void* p = M.allocate(s, a);
+    assert(P.alloc_count == 1);
+    assert(P.checkAlloc(p, s, a));
+
+    s = 128;
+    a = MaxAlignV;
+    p = M.allocate(s);
+    assert(P.alloc_count == 2);
+    assert(P.checkAlloc(p, s, a));
+  }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+  {
+    TestResource R2;
+    auto& P2                      = R2.getController();
+    P2.throw_on_alloc             = true;
+    std::pmr::memory_resource& M2 = R2;
+    try {
+      M2.allocate(42);
+      assert(false);
+    } catch (TestException const&) {
+      // do nothing.
+    } catch (...) {
+      assert(false);
+    }
+  }
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/deallocate.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/deallocate.pass.cpp
new file mode 100644
index 0000000000000..ad2614bf95f97
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/deallocate.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory_resource>
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+//------------------------------------------------------------------------------
+// TESTING void * memory_resource::deallocate(void *, size_t, size_t = max_align)
+//
+// Concerns:
+//  A) 'memory_resource' contains a member 'deallocate' with the required
+//     signature, including the default alignment parameter.
+//  B) The return type of 'deallocate' is 'void'.
+//  C) 'deallocate' is not marked as 'noexcept'.
+//  D) Invoking 'deallocate' invokes 'do_deallocate' with the same arguments.
+
+#include <memory_resource>
+#include <cassert>
+#include <cstddef>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  NullResource R(42);
+  auto& P                      = R.getController();
+  std::pmr::memory_resource& M = R;
+  {
+    ASSERT_SAME_TYPE(decltype(M.deallocate(nullptr, 0, 0)), void);
+    ASSERT_SAME_TYPE(decltype(M.deallocate(nullptr, 0)), void);
+  }
+  {
+    static_assert(!noexcept(M.deallocate(nullptr, 0, 0)));
+    static_assert(!noexcept(M.deallocate(nullptr, 0)));
+  }
+  {
+    int s   = 100;
+    int a   = 64;
+    void* p = reinterpret_cast<void*>(640);
+    M.deallocate(p, s, a);
+    assert(P.dealloc_count == 1);
+    assert(P.checkDealloc(p, s, a));
+
+    s = 128;
+    a = alignof(std::max_align_t);
+    p = reinterpret_cast<void*>(12800);
+    M.deallocate(p, s);
+    assert(P.dealloc_count == 2);
+    assert(P.checkDealloc(p, s, a));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/dtor.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/dtor.pass.cpp
new file mode 100644
index 0000000000000..e8756b50e8dc4
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/dtor.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+//------------------------------------------------------------------------------
+// TESTING virtual ~memory_resource()
+//
+// Concerns:
+//  A) 'memory_resource' is destructible.
+//  B) The destructor is implicitly marked noexcept.
+//  C) The destructor is marked virtual.
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  static_assert(std::has_virtual_destructor_v<std::pmr::memory_resource>);
+  static_assert(std::is_nothrow_destructible_v<std::pmr::memory_resource>);
+  static_assert(std::is_abstract_v<std::pmr::memory_resource>);
+
+  // Check that the destructor of `TestResource` is called when
+  // it is deleted as a pointer to `memory_resource`.
+  {
+    using TR                     = TestResource;
+    std::pmr::memory_resource* M = new TR(42);
+    assert(TR::resource_alive == 1);
+    assert(TR::resource_constructed == 1);
+    assert(TR::resource_destructed == 0);
+
+    delete M;
+
+    assert(TR::resource_alive == 0);
+    assert(TR::resource_constructed == 1);
+    assert(TR::resource_destructed == 1);
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/is_equal.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/is_equal.pass.cpp
new file mode 100644
index 0000000000000..5943b91ae8103
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.res/mem.res.public/is_equal.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <memory_resource>
+
+//------------------------------------------------------------------------------
+// TESTING virtual bool is_equal(memory_resource const &) const noexcept
+//
+// Concerns:
+//   A) 'memory_resource' provides a function 'is_equal' with the required
+//      signature.
+//   B) 'is_equal' is noexcept.
+//   C) 'do_is_equal' is called using the same arguments passed to 'is_equal'
+//      and the resulting value is returned.
+//   D) 'do_is_equal' is called on the LHS object and not the RHS object.
+
+#include <memory_resource>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+  {
+    const std::pmr::memory_resource* r1 = nullptr;
+    const std::pmr::memory_resource* r2 = nullptr;
+    ASSERT_NOEXCEPT(r1->is_equal(*r2));
+  }
+  {
+    TestResource1 R1(1);
+    auto& P1                            = R1.getController();
+    const std::pmr::memory_resource& M1 = R1;
+
+    TestResource2 R2(1);
+    auto& P2                            = R2.getController();
+    const std::pmr::memory_resource& M2 = R2;
+
+    assert(M1.is_equal(M2) == false);
+    assert(P1.checkIsEqualCalledEq(1));
+    assert(P2.checkIsEqualCalledEq(0));
+
+    assert(M2.is_equal(M1) == false);
+    assert(P2.checkIsEqualCalledEq(1));
+    assert(P1.checkIsEqualCalledEq(1));
+  }
+  {
+    TestResource1 R1(1);
+    auto& P1                            = R1.getController();
+    const std::pmr::memory_resource& M1 = R1;
+
+    TestResource1 R2(2);
+    auto& P2                            = R2.getController();
+    const std::pmr::memory_resource& M2 = R2;
+
+    assert(M1.is_equal(M2) == false);
+    assert(P1.checkIsEqualCalledEq(1));
+    assert(P2.checkIsEqualCalledEq(0));
+
+    assert(M2.is_equal(M1) == false);
+    assert(P2.checkIsEqualCalledEq(1));
+    assert(P1.checkIsEqualCalledEq(1));
+  }
+  {
+    TestResource1 R1(1);
+    auto& P1                            = R1.getController();
+    const std::pmr::memory_resource& M1 = R1;
+
+    TestResource1 R2(1);
+    auto& P2                            = R2.getController();
+    const std::pmr::memory_resource& M2 = R2;
+
+    assert(M1.is_equal(M2) == true);
+    assert(P1.checkIsEqualCalledEq(1));
+    assert(P2.checkIsEqualCalledEq(0));
+
+    assert(M2.is_equal(M1) == true);
+    assert(P2.checkIsEqualCalledEq(1));
+    assert(P1.checkIsEqualCalledEq(1));
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h
index 18b0c5609d7c8..aadebe444708f 100644
--- a/libcxx/test/support/count_new.h
+++ b/libcxx/test/support/count_new.h
@@ -210,6 +210,11 @@ class MemCounter
         return disable_checking || n != delete_called;
     }
 
+    bool checkDeleteCalledGreaterThan(int n) const
+    {
+        return disable_checking || delete_called > n;
+    }
+
     bool checkAlignedNewCalledEq(int n) const
     {
         return disable_checking || n == aligned_new_called;
@@ -245,6 +250,11 @@ class MemCounter
         return disable_checking || n != last_new_size;
     }
 
+    bool checkLastNewSizeGe(std::size_t n) const
+    {
+        return disable_checking || last_new_size >= n;
+    }
+
     bool checkLastNewAlignEq(std::size_t n) const
     {
         return disable_checking || n == last_new_align;
@@ -255,6 +265,11 @@ class MemCounter
         return disable_checking || n != last_new_align;
     }
 
+    bool checkLastNewAlignGe(std::size_t n) const
+    {
+        return disable_checking || last_new_align >= n;
+    }
+
     bool checkLastDeleteAlignEq(std::size_t n) const
     {
         return disable_checking || n == last_delete_align;

diff  --git a/libcxx/test/support/test_std_memory_resource.h b/libcxx/test/support/test_std_memory_resource.h
new file mode 100644
index 0000000000000..a392b9cabea59
--- /dev/null
+++ b/libcxx/test/support/test_std_memory_resource.h
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_TEST_STD_MEMORY_RESOURCE_H
+#define SUPPORT_TEST_STD_MEMORY_RESOURCE_H
+
+#include <memory>
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <cstdint>
+#include <cassert>
+#include "test_macros.h"
+#include "controlled_allocators.h"
+#include "uses_alloc_types.h"
+
+template <class ProviderT, int = 0>
+class TestResourceImp : public std::pmr::memory_resource {
+public:
+  static int resource_alive;
+  static int resource_constructed;
+  static int resource_destructed;
+
+  static void resetStatics() {
+    assert(resource_alive == 0);
+    resource_alive       = 0;
+    resource_constructed = 0;
+    resource_destructed  = 0;
+  }
+
+  using memory_resource = std::pmr::memory_resource;
+  using Provider        = ProviderT;
+
+  int value;
+
+  explicit TestResourceImp(int val = 0) : value(val) {
+    ++resource_alive;
+    ++resource_constructed;
+  }
+
+  ~TestResourceImp() noexcept {
+    --resource_alive;
+    ++resource_destructed;
+  }
+
+  void reset() {
+    C.reset();
+    P.reset();
+  }
+  AllocController& getController() { return C; }
+
+  bool checkAlloc(void* p, std::size_t s, std::size_t a) const { return C.checkAlloc(p, s, a); }
+
+  bool checkDealloc(void* p, std::size_t s, std::size_t a) const { return C.checkDealloc(p, s, a); }
+
+  bool checkIsEqualCalledEq(int n) const { return C.checkIsEqualCalledEq(n); }
+
+protected:
+  virtual void* do_allocate(std::size_t s, std::size_t a) {
+    if (C.throw_on_alloc) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+      throw TestException{};
+#else
+      assert(false);
+#endif
+    }
+    void* ret = P.allocate(s, a);
+    C.countAlloc(ret, s, a);
+    return ret;
+  }
+
+  virtual void do_deallocate(void* p, std::size_t s, std::size_t a) {
+    C.countDealloc(p, s, a);
+    P.deallocate(p, s, a);
+  }
+
+  virtual bool do_is_equal(memory_resource const& other) const noexcept {
+    C.countIsEqual();
+    TestResourceImp const* o = dynamic_cast<TestResourceImp const*>(&other);
+    return o && o->value == value;
+  }
+
+private:
+  mutable AllocController C;
+  mutable Provider P;
+  DISALLOW_COPY(TestResourceImp);
+};
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_alive = 0;
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_constructed = 0;
+
+template <class Provider, int N>
+int TestResourceImp<Provider, N>::resource_destructed = 0;
+
+struct NullProvider {
+  NullProvider() {}
+  void* allocate(size_t, size_t) { return nullptr; }
+  void deallocate(void*, size_t, size_t) {}
+  void reset() {}
+
+private:
+  DISALLOW_COPY(NullProvider);
+};
+
+struct NewDeleteProvider {
+  NewDeleteProvider() {}
+  void* allocate(size_t s, size_t) { return ::operator new(s); }
+  void deallocate(void* p, size_t, size_t) { ::operator delete(p); }
+  void reset() {}
+
+private:
+  DISALLOW_COPY(NewDeleteProvider);
+};
+
+template <size_t Size = 4096 * 10> // 10 pages worth of memory.
+struct BufferProvider {
+  char buffer[Size];
+  void* next   = &buffer;
+  size_t space = Size;
+
+  BufferProvider() {}
+
+  void* allocate(size_t s, size_t a) {
+    void* ret = std::align(s, a, next, space);
+    if (ret == nullptr) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+      throw std::bad_alloc();
+#else
+      assert(false);
+#endif
+    }
+
+    return ret;
+  }
+
+  void deallocate(void*, size_t, size_t) {}
+
+  void reset() {
+    next  = &buffer;
+    space = Size;
+  }
+
+private:
+  DISALLOW_COPY(BufferProvider);
+};
+
+using NullResource      = TestResourceImp<NullProvider, 0>;
+using NewDeleteResource = TestResourceImp<NewDeleteProvider, 0>;
+using TestResource      = TestResourceImp<BufferProvider<>, 0>;
+using TestResource1     = TestResourceImp<BufferProvider<>, 1>;
+using TestResource2     = TestResourceImp<BufferProvider<>, 2>;
+
+#endif /* SUPPORT_TEST_STD_MEMORY_RESOURCE_H */

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 37860a731d299..62f703b60c2f1 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -483,7 +483,6 @@ def add_version_header(tc):
     "name": "__cpp_lib_memory_resource",
     "values": { "c++17": 201603 },
     "headers": ["memory_resource"],
-    "unimplemented": True,
   }, {
     "name": "__cpp_lib_move_only_function",
     "values": { "c++2b": 202110 },


        


More information about the libcxx-commits mailing list