[libc++] Move the definition of aligned allocation helpers outside of <new>

They are not needed in <new> -- in fact they are only needed in .cpp files.
Getting those out of the way makes the headers smaller and also makes it
easier to use the library on platforms where aligned allocation is not
available.

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

NOKEYCHECK=True
GitOrigin-RevId: 36080434a8858c33f2af2382be748caed131385f
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index a12aa1d..7b6ef9b 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -414,6 +414,7 @@
   __mbstate_t.h
   __memory/addressof.h
   __memory/align.h
+  __memory/aligned_alloc.h
   __memory/allocate_at_least.h
   __memory/allocation_guard.h
   __memory/allocator.h
diff --git a/include/__memory/aligned_alloc.h b/include/__memory/aligned_alloc.h
new file mode 100644
index 0000000..41520cf
--- /dev/null
+++ b/include/__memory/aligned_alloc.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H
+#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H
+
+#include <__config>
+#include <cstddef>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+
+// Low-level helpers to call the aligned allocation and deallocation functions
+// on the target platform. This is used to implement libc++'s own memory
+// allocation routines -- if you need to allocate memory inside the library,
+// chances are that you want to use `__libcpp_allocate` instead.
+//
+// Returns the allocated memory, or `nullptr` on failure.
+inline _LIBCPP_HIDE_FROM_ABI
+void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+#  if defined(_LIBCPP_MSVCRT_LIKE)
+    return ::_aligned_malloc(__size, __alignment);
+#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
+    // aligned_alloc() requires that __size is a multiple of __alignment,
+    // but for C++ [new.delete.general], only states "if the value of an
+    // alignment argument passed to any of these functions is not a valid
+    // alignment value, the behavior is undefined".
+    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
+    // round __size up to the next multiple of __alignment.
+    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
+    // Rounding up could have wrapped around to zero, so we have to add another
+    // max() ternary to the actual call site to avoid succeeded in that case.
+    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
+#  else
+    void* __result = nullptr;
+    (void)::posix_memalign(&__result, __alignment, __size);
+    // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
+    return __result;
+#  endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+void __libcpp_aligned_free(void* __ptr) {
+#if defined(_LIBCPP_MSVCRT_LIKE)
+  ::_aligned_free(__ptr);
+#else
+  ::free(__ptr);
+#endif
+}
+
+#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H
diff --git a/include/module.modulemap.in b/include/module.modulemap.in
index 1f1d67d..6bc64be 100644
--- a/include/module.modulemap.in
+++ b/include/module.modulemap.in
@@ -1061,6 +1061,7 @@
     module __memory {
       module addressof                       { private header "__memory/addressof.h" }
       module align                           { private header "__memory/align.h" }
+      module aligned_alloc                   { private header "__memory/aligned_alloc.h" }
       module allocate_at_least               { private header "__memory/allocate_at_least.h" }
       module allocation_guard                { private header "__memory/allocation_guard.h" }
       module allocator                       { private header "__memory/allocator.h" }
diff --git a/include/new b/include/new
index 0c826f4..97c8fc4 100644
--- a/include/new
+++ b/include/new
@@ -332,46 +332,6 @@
 #endif
 }
 
-#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
-// Low-level helpers to call the aligned allocation and deallocation functions
-// on the target platform. This is used to implement libc++'s own memory
-// allocation routines -- if you need to allocate memory inside the library,
-// chances are that you want to use `__libcpp_allocate` instead.
-//
-// Returns the allocated memory, or `nullptr` on failure.
-inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
-#  if defined(_LIBCPP_MSVCRT_LIKE)
-    return ::_aligned_malloc(__size, __alignment);
-#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
-    // aligned_alloc() requires that __size is a multiple of __alignment,
-    // but for C++ [new.delete.general], only states "if the value of an
-    // alignment argument passed to any of these functions is not a valid
-    // alignment value, the behavior is undefined".
-    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
-    // round __size up to the next multiple of __alignment.
-    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
-    // Rounding up could have wrapped around to zero, so we have to add another
-    // max() ternary to the actual call site to avoid succeeded in that case.
-    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
-#  else
-    void* __result = nullptr;
-    (void)::posix_memalign(&__result, __alignment, __size);
-    // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
-    return __result;
-#  endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-void __libcpp_aligned_free(void* __ptr) {
-#if defined(_LIBCPP_MSVCRT_LIKE)
-  ::_aligned_free(__ptr);
-#else
-  ::free(__ptr);
-#endif
-}
-#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-
-
 template <class _Tp>
 _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
diff --git a/src/new.cpp b/src/new.cpp
index 48d6f99..f2ca698 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <__memory/aligned_alloc.h>
 #include <new>
 #include <stdlib.h>
 
diff --git a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
index 545032b..28c964d 100644
--- a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -42,6 +42,11 @@
 
 #include "test_macros.h"
 
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__memory/aligned_alloc.h>
+TEST_DIAGNOSTIC_POP
+
 struct alloc_stats {
   alloc_stats() { reset(); }
 
diff --git a/test/libcxx/private_headers.verify.cpp b/test/libcxx/private_headers.verify.cpp
index ebbd50b..f629ce0 100644
--- a/test/libcxx/private_headers.verify.cpp
+++ b/test/libcxx/private_headers.verify.cpp
@@ -445,6 +445,7 @@
 #include <__mbstate_t.h> // expected-error@*:* {{use of private header from outside its module: '__mbstate_t.h'}}
 #include <__memory/addressof.h> // expected-error@*:* {{use of private header from outside its module: '__memory/addressof.h'}}
 #include <__memory/align.h> // expected-error@*:* {{use of private header from outside its module: '__memory/align.h'}}
+#include <__memory/aligned_alloc.h> // expected-error@*:* {{use of private header from outside its module: '__memory/aligned_alloc.h'}}
 #include <__memory/allocate_at_least.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocate_at_least.h'}}
 #include <__memory/allocation_guard.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocation_guard.h'}}
 #include <__memory/allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocator.h'}}