Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -3222,6 +3222,22 @@
         {__alloc_traits::deallocate(__alloc_, __p, __s_);}
 };
 
+template <class _Alloc>
+class __allocator_destroyer
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    _Alloc __alloc_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __allocator_destroyer(_Alloc const& __a)
+             _NOEXCEPT
+        : __alloc_(__a) {}
+
+    template<class _Tp>
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(_Tp* __p) _NOEXCEPT
+        {__alloc_traits::destroy(__alloc_, __p);}
+};
+
 template <class _InputIterator, class _ForwardIterator>
 _ForwardIterator
 uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
@@ -3510,6 +3526,20 @@
 #endif
 }
 
+template<class _CntrlBlk, class _Tp>
+struct __shared_ptr_aligned_block
+{
+    typename std::aligned_storage<
+        sizeof(_CntrlBlk),
+        alignment_of<_CntrlBlk>::value
+    >::type __cntrl_buff[sizeof(_CntrlBlk)];
+
+    typename std::aligned_storage<
+        sizeof(_Tp),
+        alignment_of<_CntrlBlk>::value
+    >::type __value_buff[sizeof(_Tp)];
+};
+
 template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
 
 class _LIBCPP_TYPE_VIS __shared_count
@@ -3607,10 +3637,14 @@
     : public __shared_weak_count
 {
     __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
+    size_t __size;
+
 public:
     _LIBCPP_INLINE_VISIBILITY
-    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
-        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
+    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a,
+                         size_t __size = sizeof(__shared_ptr_pointer))
+        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)),
+           __size(__size) {}
 
 #ifndef _LIBCPP_NO_RTTI
     virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
@@ -3644,13 +3678,13 @@
 void
 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
 {
-    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
+    typedef typename __allocator_traits_rebind<_Alloc, char>::type _Al;
     typedef allocator_traits<_Al> _ATraits;
     typedef pointer_traits<typename _ATraits::pointer> _PTraits;
 
     _Al __a(__data_.second());
     __data_.second().~_Alloc();
-    __a.deallocate(_PTraits::pointer_to(*this), 1);
+    __a.deallocate(_PTraits::pointer_to(*reinterpret_cast<char*>(this)), __size);
 }
 
 template <class _Tp, class _Alloc>
@@ -4457,17 +4491,27 @@
 {
     static_assert(is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared");
 
-    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
+    typedef typename __allocator_traits_rebind<_Alloc, _Tp>::type _TAlloc;
+    typedef __allocator_destroyer<_TAlloc> _D1;
+    typedef __shared_ptr_pointer<_Tp*, _D1, _Alloc> _CntrlBlk;
+    typedef __shared_ptr_aligned_block<_CntrlBlk, _Tp> _AlignedBlk;
+    typedef typename __allocator_traits_rebind<_Alloc, _AlignedBlk>::type _A2;
     typedef __allocator_destructor<_A2> _D2;
+    typedef allocator_traits<_TAlloc> _ATraits;
 
     _A2 __a2(__a);
-    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
-    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
-        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
-
-    return shared_ptr<_Tp>::__create_with_cntrl_block(__hold2.get()->get(),
-                                                      _VSTD::addressof(*__hold2.release()));
+    _TAlloc __a3(__a);
+    unique_ptr<_AlignedBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+    _CntrlBlk*   __cntrl_buff = reinterpret_cast<_CntrlBlk*>(__hold2.get()->__cntrl_buff);
+    _Tp*         __value_buff = reinterpret_cast<_Tp*>      (__hold2.get()->__value_buff);
+
+    ::new(static_cast<void*>(__cntrl_buff))
+        _CntrlBlk(__value_buff, _D1(__a), __a2, sizeof(_AlignedBlk));
+    _ATraits::construct(__a3, __value_buff, _VSTD::forward<_Args>(__args)...);
+
+    __hold2.release();
+    return shared_ptr<_Tp>::__create_with_cntrl_block(__value_buff,
+                                                      __cntrl_buff);
 }
 
 #else  // _LIBCPP_HAS_NO_VARIADICS
Index: test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
===================================================================
--- test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
+++ test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
@@ -38,6 +38,8 @@
   }
   // expected-error-re@memory:* 2 {{static_assert failed{{.*}} "default_delete cannot be instantiated for function types"}}
   {
+    // expected-error@memory:* {{no member named 'value' in 'std::__1::is_empty<std::__1::__compressed_pair<void (*)(Tag<4>), std::__1::default_delete<void (Tag<4>)> > >'}}
+    // expected-error@memory:* {{cannot initialize return object of type 'std::__1::__shared_weak_count *' with an rvalue of type 'std::__1::__shared_ptr_pointer<void (*)(Tag<4>), std::__1::default_delete<void (Tag<4>)>, std::__1::allocator<std::__1::__shared_ptr_dummy_rebind_allocator_type> > *'}}
     SPtr<4> s4(getFn<4>()); // expected-note {{requested here}}
     SPtr<5> s5(getFn<5>(), std::default_delete<FnType<5>>{}); // expected-note {{requested here}}
   }
Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp
===================================================================
--- /dev/null
+++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// shared_ptr
+
+// template<class T, class A, class... Args>
+//    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+
+// This patch tests that allocator_traits::construct is used in allocate_shared.
+
+// XFAIL UNTIL THE PATCH IS FINISHED
+
+#include <memory>
+
+static bool construct_called = false;
+static bool destroy_called = false;
+static unsigned allocator_id = 0;
+
+template<class T>
+struct MyAllocator {
+public:
+    typedef T  value_type;
+    typedef T* pointer;
+
+    unsigned id = 0;
+
+    MyAllocator() = default;
+    MyAllocator(int id) : id(id) {}
+
+    template<class U>
+    MyAllocator(MyAllocator<U> const& other)
+        : id(other.id) {};
+
+    pointer allocate(std::ptrdiff_t n)
+    {
+        return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
+    }
+
+    void deallocate(pointer p, std::ptrdiff_t)
+    {
+        return ::operator delete(p);
+    }
+
+    void construct(T *p)
+    {
+        construct_called = true;
+        destroy_called = false;
+        allocator_id = id;
+        ::new(p) T;
+    }
+
+    void construct(T *p, T x)
+    {
+        construct_called = true;
+        destroy_called = false;
+        allocator_id = id;
+        ::new(p) T(x);
+    }
+
+    void construct(T *p, T x, T y)
+    {
+        construct_called = true;
+        destroy_called = false;
+        allocator_id = id;
+        ::new(p) T(x, y);
+    }
+
+    void destroy(T *p)
+    {
+        destroy_called = true;
+        construct_called = false;
+        allocator_id = id;
+        p->~T();
+    }
+};
+
+struct mchar { char c; };
+
+struct Foo
+{
+    int val;
+
+    Foo(int val) : val(val) {}
+
+    Foo(Foo a, Foo b)
+        : val(a.val + b.val) {}
+};
+
+struct Bar {
+    std::max_align_t y;
+};
+
+void test_aligned(void *p, size_t align) {
+    assert(reinterpret_cast<uintptr_t>(p) % align == 0);
+}
+
+int main(int, char**)
+{
+    {
+        std::shared_ptr<int> p = std::allocate_shared<int>(MyAllocator<int>());
+        assert(construct_called);
+    }
+    assert(destroy_called);
+
+    {
+        std::shared_ptr<int> p = std::allocate_shared<int>(MyAllocator<int>(), 42);
+        assert(construct_called);
+        assert(*p == 42);
+    }
+    assert(destroy_called);
+
+    {
+        std::shared_ptr<Foo> p = std::allocate_shared<Foo>(MyAllocator<Foo>(), Foo(42), Foo(100));
+        assert(construct_called);
+        assert(p->val == 142);
+    }
+    assert(destroy_called);
+
+    { // make sure allocator is properly re-bound
+        std::shared_ptr<int> p = std::allocate_shared<int>(MyAllocator<mchar>(), 42);
+        assert(construct_called);
+        assert(*p == 42);
+    }
+    assert(destroy_called);
+
+    { // make sure allocator is copied
+        std::shared_ptr<int> p = std::allocate_shared<int>(MyAllocator<int>(3));
+        assert(allocator_id == 3);
+
+        allocator_id = 0;
+    }
+    assert(allocator_id == 3);
+
+    {
+        std::shared_ptr<Bar> p;
+        test_aligned(p.get(), alignof(Bar));
+    }
+
+    return 0;
+}