[clang] [lldb] [clang][windows] Revert support for vector deleting destructors (PR #169063)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 21 09:37:36 PST 2025


https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/169063

>From 119a90271e43dbf53893240bc0ec172930ab938a Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Fri, 21 Nov 2025 08:44:15 -0800
Subject: [PATCH 1/3] Revert "[CIR][NFC] Add missing code markers for
 Dtor_VectorDeleting (#167969)"

This reverts commit e6b9805b574bb5c90263ec7fbcb94df76d2807a4.
---
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp  | 7 -------
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 5 +----
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 28a42121052e2..95c96d48bfac4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -746,13 +746,6 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *e) {
   deleteTy = getContext().getBaseElementType(deleteTy);
   ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy));
 
-  if (e->isArrayForm() &&
-      cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors(
-          cgm.getASTContext().getLangOpts())) {
-    cgm.errorNYI(e->getSourceRange(),
-                 "emitCXXDeleteExpr: emitVectorDeletingDtors");
-  }
-
   if (e->isArrayForm()) {
     assert(!cir::MissingFeatures::deleteArray());
     cgm.errorNYI(e->getSourceRange(), "emitCXXDeleteExpr: array delete");
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 7df650984bdd2..33bdfa315a9ea 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -754,9 +754,7 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
   // outside of the function-try-block, which means it's always
   // possible to delegate the destructor body to the complete
   // destructor.  Do so.
-  if (dtorType == Dtor_Deleting || dtorType == Dtor_VectorDeleting) {
-    if (cxxStructorImplicitParamValue && dtorType == Dtor_VectorDeleting)
-      cgm.errorNYI(dtor->getSourceRange(), "emitConditionalArrayDtorCall");
+  if (dtorType == Dtor_Deleting) {
     RunCleanupsScope dtorEpilogue(*this);
     enterDtorCleanups(dtor, Dtor_Deleting);
     if (haveInsertPoint()) {
@@ -789,7 +787,6 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
   case Dtor_Deleting:
-  case Dtor_VectorDeleting:
     llvm_unreachable("already handled deleting case");
 
   case Dtor_Complete:

>From 0645cfd9e5c9008cb98e7e9825f9ad24bbd4dc61 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Fri, 21 Nov 2025 08:45:04 -0800
Subject: [PATCH 2/3] Revert "Reland [MS][clang] Add support for vector
 deleting destructors (#165598)"

This reverts commit 4d10c1165442cbbbc0017b48fcdd7dae1ccf3678.
---
 clang/docs/ReleaseNotes.rst                   |   8 -
 clang/include/clang/AST/ASTContext.h          |  22 --
 clang/include/clang/AST/ASTMutationListener.h |   9 -
 clang/include/clang/AST/DeclCXX.h             |  16 +-
 clang/include/clang/AST/VTableBuilder.h       |   6 +-
 clang/include/clang/Basic/ABI.h               |  11 +-
 clang/include/clang/Basic/TargetInfo.h        |   5 -
 clang/include/clang/Sema/Sema.h               |   3 +-
 clang/include/clang/Serialization/ASTWriter.h |   4 -
 clang/lib/AST/ASTContext.cpp                  |  65 ----
 clang/lib/AST/DeclCXX.cpp                     |  73 +---
 clang/lib/AST/Expr.cpp                        |   3 -
 clang/lib/AST/ItaniumMangle.cpp               |   2 -
 clang/lib/AST/MicrosoftMangle.cpp             |  22 +-
 clang/lib/AST/VTableBuilder.cpp               |  18 +-
 clang/lib/Basic/TargetInfo.cpp                |   7 -
 clang/lib/CodeGen/CGCXX.cpp                   |  37 +-
 clang/lib/CodeGen/CGCXXABI.cpp                |  14 -
 clang/lib/CodeGen/CGCXXABI.h                  |   6 -
 clang/lib/CodeGen/CGClass.cpp                 |  95 +----
 clang/lib/CodeGen/CGDebugInfo.cpp             |   8 +-
 clang/lib/CodeGen/CGExprCXX.cpp               |  52 +--
 clang/lib/CodeGen/CGVTables.cpp               |   4 +-
 clang/lib/CodeGen/CodeGenModule.cpp           |  50 ---
 clang/lib/CodeGen/CodeGenModule.h             |   6 -
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |   5 +-
 clang/lib/CodeGen/MicrosoftCXXABI.cpp         |  70 +---
 clang/lib/Sema/SemaDeclCXX.cpp                |  30 +-
 clang/lib/Sema/SemaExprCXX.cpp                |  13 +-
 clang/lib/Serialization/ASTCommon.h           |   4 +-
 clang/lib/Serialization/ASTReaderDecl.cpp     |  66 +---
 clang/lib/Serialization/ASTWriter.cpp         |  36 --
 clang/lib/Serialization/ASTWriterDecl.cpp     |   2 -
 clang/test/CodeGenCXX/dllexport.cpp           |   5 +-
 .../microsoft-abi-extern-template.cpp         |   2 +-
 .../CodeGenCXX/microsoft-abi-structors.cpp    |   2 +-
 .../test/CodeGenCXX/microsoft-abi-thunks.cpp  |   3 +-
 .../CodeGenCXX/microsoft-abi-vftables.cpp     |  20 +-
 .../microsoft-abi-virtual-inheritance.cpp     |  17 +-
 ...multiple-nonvirtual-inheritance-vdtors.cpp |  18 +-
 .../microsoft-abi-vtables-return-thunks.cpp   |   2 +-
 ...crosoft-abi-vtables-single-inheritance.cpp |  20 +-
 ...-vtables-virtual-inheritance-vtordisps.cpp |  30 +-
 ...rosoft-abi-vtables-virtual-inheritance.cpp |  18 +-
 .../CodeGenCXX/microsoft-no-rtti-data.cpp     |   2 +-
 .../microsoft-vector-deleting-dtors.cpp       | 336 ------------------
 clang/test/CodeGenCXX/vtable-consteval.cpp    |   4 +-
 clang/test/DebugInfo/CXX/windows-dtor.cpp     |   2 +-
 .../module.modulemap                          |   1 -
 .../msvc-vector-deleting-dtors.h              |  16 -
 .../msvc-vector-deleting-destructors.cpp      |  30 --
 clang/test/Modules/vtable-windows.cppm        |   2 +-
 .../PCH/Inputs/msvc-vector-deleting-dtors.h   |  16 -
 .../PCH/msvc-vector-deleting-destructors.cpp  |  34 --
 clang/test/Profile/cxx-abc-deleting-dtor.cpp  |   9 +-
 clang/test/SemaCXX/gh134265.cpp               |  62 ----
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      |   1 -
 57 files changed, 164 insertions(+), 1260 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
 delete mode 100644 clang/test/Modules/Inputs/msvc-vector-deleting-dtors/module.modulemap
 delete mode 100644 clang/test/Modules/Inputs/msvc-vector-deleting-dtors/msvc-vector-deleting-dtors.h
 delete mode 100644 clang/test/Modules/msvc-vector-deleting-destructors.cpp
 delete mode 100644 clang/test/PCH/Inputs/msvc-vector-deleting-dtors.h
 delete mode 100644 clang/test/PCH/msvc-vector-deleting-destructors.cpp
 delete mode 100644 clang/test/SemaCXX/gh134265.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e440c35a5b98..e8bd591a44d18 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,12 +84,6 @@ Potentially Breaking Changes
 - Downstream projects that previously linked only against ``clangDriver`` may
   now (also) need to link against the new ``clangOptions`` library, since
   options-related code has been moved out of the Driver into a separate library.
-- Clang now supports MSVC vector deleting destructors when targeting Windows.
-  This means that vtables of classes with virtual destructors will contain a
-  pointer to vector deleting destructor (instead of scalar deleting destructor)
-  which in fact is a different symbol with different name and linkage. This
-  may cause runtime failures if two binaries using the same class defining a
-  virtual destructor are compiled with different versions of clang.
 
 C/C++ Language Potentially Breaking Changes
 -------------------------------------------
@@ -621,8 +615,6 @@ Windows Support
 - clang-cl now supports /arch:AVX10.1 and /arch:AVX10.2.
 - clang-cl now supports /vlen, /vlen=256 and /vlen=512.
 
-- Clang now supports MSVC vector deleting destructors (GH19772).
-
 LoongArch Support
 ^^^^^^^^^^^^^^^^^
 - Enable linker relaxation by default for loongarch64.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 6e9e737dcae4f..33aa2d343aa7a 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -370,18 +370,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
   mutable llvm::DenseSet<const FunctionDecl *> DestroyingOperatorDeletes;
   mutable llvm::DenseSet<const FunctionDecl *> TypeAwareOperatorNewAndDeletes;
 
-  /// Global and array operators delete are only required for MSVC deleting
-  /// destructors support. Store them here to avoid keeping 4 pointers that are
-  /// not always used in each redeclaration of the destructor.
-  mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
-      OperatorDeletesForVirtualDtor;
-  mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
-      GlobalOperatorDeletesForVirtualDtor;
-  mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
-      ArrayOperatorDeletesForVirtualDtor;
-  mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
-      GlobalArrayOperatorDeletesForVirtualDtor;
-
   /// The next string literal "version" to allocate during constant evaluation.
   /// This is used to distinguish between repeated evaluations of the same
   /// string literal.
@@ -3485,16 +3473,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
                                          bool IsTypeAware);
   bool isTypeAwareOperatorNewOrDelete(const FunctionDecl *FD) const;
 
-  enum OperatorDeleteKind { Regular, GlobalRegular, Array, ArrayGlobal };
-
-  void addOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
-                                 FunctionDecl *OperatorDelete,
-                                 OperatorDeleteKind K) const;
-  FunctionDecl *getOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
-                                          OperatorDeleteKind K) const;
-  bool dtorHasOperatorDelete(const CXXDestructorDecl *Dtor,
-                             OperatorDeleteKind K) const;
-
   /// Retrieve the context for computing mangling numbers in the given
   /// DeclContext.
   MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
diff --git a/clang/include/clang/AST/ASTMutationListener.h b/clang/include/clang/AST/ASTMutationListener.h
index c8448a25c23a4..352af42391782 100644
--- a/clang/include/clang/AST/ASTMutationListener.h
+++ b/clang/include/clang/AST/ASTMutationListener.h
@@ -90,15 +90,6 @@ class ASTMutationListener {
   virtual void ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
                                           const FunctionDecl *GlobDelete) {}
 
-  /// A virtual destructor's operator array delete has been resolved.
-  virtual void ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
-                                           const FunctionDecl *ArrayDelete) {}
-
-  /// A virtual destructor's operator global array delete has been resolved.
-  virtual void
-  ResolvedOperatorGlobArrayDelete(const CXXDestructorDecl *DD,
-                                  const FunctionDecl *GlobArrayDelete) {}
-
   /// An implicit member got a definition.
   virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
 
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 5c4ad3c45da19..dfa3befb27dd0 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2872,6 +2872,8 @@ class CXXDestructorDecl : public CXXMethodDecl {
 
   // FIXME: Don't allocate storage for these except in the first declaration
   // of a virtual destructor.
+  FunctionDecl *OperatorDelete = nullptr;
+  FunctionDecl *OperatorGlobalDelete = nullptr;
   Expr *OperatorDeleteThisArg = nullptr;
 
   CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
@@ -2898,12 +2900,14 @@ class CXXDestructorDecl : public CXXMethodDecl {
 
   void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
   void setOperatorGlobalDelete(FunctionDecl *OD);
-  void setOperatorArrayDelete(FunctionDecl *OD);
-  void setGlobalOperatorArrayDelete(FunctionDecl *OD);
-  const FunctionDecl *getOperatorDelete() const;
-  const FunctionDecl *getOperatorGlobalDelete() const;
-  const FunctionDecl *getArrayOperatorDelete() const;
-  const FunctionDecl *getGlobalArrayOperatorDelete() const;
+
+  const FunctionDecl *getOperatorDelete() const {
+    return getCanonicalDecl()->OperatorDelete;
+  }
+
+  const FunctionDecl *getOperatorGlobalDelete() const {
+    return getCanonicalDecl()->OperatorGlobalDelete;
+  }
 
   Expr *getOperatorDeleteThisArg() const {
     return getCanonicalDecl()->OperatorDeleteThisArg;
diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h
index e1efe8cddcc5e..a5de41dbc22f1 100644
--- a/clang/include/clang/AST/VTableBuilder.h
+++ b/clang/include/clang/AST/VTableBuilder.h
@@ -150,7 +150,7 @@ class VTableComponent {
 
   bool isRTTIKind() const { return isRTTIKind(getKind()); }
 
-  GlobalDecl getGlobalDecl(bool HasVectorDeletingDtors) const {
+  GlobalDecl getGlobalDecl() const {
     assert(isUsedFunctionPointerKind() &&
            "GlobalDecl can be created only from virtual function");
 
@@ -161,9 +161,7 @@ class VTableComponent {
     case CK_CompleteDtorPointer:
       return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
     case CK_DeletingDtorPointer:
-      return GlobalDecl(DtorDecl, (HasVectorDeletingDtors)
-                                      ? CXXDtorType::Dtor_VectorDeleting
-                                      : CXXDtorType::Dtor_Deleting);
+      return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting);
     case CK_VCallOffset:
     case CK_VBaseOffset:
     case CK_OffsetToTop:
diff --git a/clang/include/clang/Basic/ABI.h b/clang/include/clang/Basic/ABI.h
index be3edccbf50b2..8279529c316cf 100644
--- a/clang/include/clang/Basic/ABI.h
+++ b/clang/include/clang/Basic/ABI.h
@@ -32,12 +32,11 @@ enum CXXCtorType {
 
 /// C++ destructor types.
 enum CXXDtorType {
-  Dtor_Deleting,       ///< Deleting dtor
-  Dtor_Complete,       ///< Complete object dtor
-  Dtor_Base,           ///< Base object dtor
-  Dtor_Comdat,         ///< The COMDAT used for dtors
-  Dtor_Unified,        ///< GCC-style unified dtor
-  Dtor_VectorDeleting, ///< Vector deleting dtor
+  Dtor_Deleting, ///< Deleting dtor
+  Dtor_Complete, ///< Complete object dtor
+  Dtor_Base,     ///< Base object dtor
+  Dtor_Comdat,   ///< The COMDAT used for dtors
+  Dtor_Unified,  ///< GCC-style unified dtor
 };
 
 } // end namespace clang
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 1c16f9f79ae68..39af84c8d0872 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1796,11 +1796,6 @@ class TargetInfo : public TransferrableTargetInfo,
   /// destructor body.
   virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const;
 
-  /// Controls whether to emit MSVC vector deleting destructors. The support for
-  /// vector deleting affects vtable layout and therefore is an ABI breaking
-  /// change. The support was only implemented at Clang 22 timeframe.
-  virtual bool emitVectorDeletingDtors(const LangOptions &) const;
-
   /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
   /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
   virtual bool hasSjLjLowering() const {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index cbfcc9bc0ea99..ae500139ee6f7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8581,8 +8581,7 @@ class Sema final : public SemaBase {
   FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc,
                                                       CXXRecordDecl *RD,
                                                       bool Diagnose,
-                                                      bool LookForGlobal,
-                                                      DeclarationName Name);
+                                                      bool LookForGlobal);
 
   /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
   /// @code ::delete ptr; @endcode
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index dbbfc29058f43..c77c98dffc39f 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -955,10 +955,6 @@ class ASTWriter : public ASTDeserializationListener,
                               Expr *ThisArg) override;
   void ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
                                   const FunctionDecl *Delete) override;
-  void ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
-                                   const FunctionDecl *Delete) override;
-  void ResolvedOperatorGlobArrayDelete(const CXXDestructorDecl *DD,
-                                       const FunctionDecl *Delete) override;
   void CompletedImplicitDefinition(const FunctionDecl *D) override;
   void InstantiationRequested(const ValueDecl *D) override;
   void VariableDefinitionInstantiated(const VarDecl *D) override;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b929b0fc1aa8e..b359fc8350375 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13337,71 +13337,6 @@ bool ASTContext::isTypeAwareOperatorNewOrDelete(const FunctionDecl *FD) const {
   return TypeAwareOperatorNewAndDeletes.contains(FD->getCanonicalDecl());
 }
 
-void ASTContext::addOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
-                                           FunctionDecl *OperatorDelete,
-                                           OperatorDeleteKind K) const {
-  switch (K) {
-  case OperatorDeleteKind::Regular:
-    OperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = OperatorDelete;
-    break;
-  case OperatorDeleteKind::GlobalRegular:
-    GlobalOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
-        OperatorDelete;
-    break;
-  case OperatorDeleteKind::Array:
-    ArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
-        OperatorDelete;
-    break;
-  case OperatorDeleteKind::ArrayGlobal:
-    GlobalArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
-        OperatorDelete;
-    break;
-  }
-}
-
-bool ASTContext::dtorHasOperatorDelete(const CXXDestructorDecl *Dtor,
-                                       OperatorDeleteKind K) const {
-  switch (K) {
-  case OperatorDeleteKind::Regular:
-    return OperatorDeletesForVirtualDtor.contains(Dtor->getCanonicalDecl());
-  case OperatorDeleteKind::GlobalRegular:
-    return GlobalOperatorDeletesForVirtualDtor.contains(
-        Dtor->getCanonicalDecl());
-  case OperatorDeleteKind::Array:
-    return ArrayOperatorDeletesForVirtualDtor.contains(
-        Dtor->getCanonicalDecl());
-  case OperatorDeleteKind::ArrayGlobal:
-    return GlobalArrayOperatorDeletesForVirtualDtor.contains(
-        Dtor->getCanonicalDecl());
-  }
-  return false;
-}
-
-FunctionDecl *
-ASTContext::getOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
-                                      OperatorDeleteKind K) const {
-  const CXXDestructorDecl *Canon = Dtor->getCanonicalDecl();
-  switch (K) {
-  case OperatorDeleteKind::Regular:
-    if (OperatorDeletesForVirtualDtor.contains(Canon))
-      return OperatorDeletesForVirtualDtor[Canon];
-    return nullptr;
-  case OperatorDeleteKind::GlobalRegular:
-    if (GlobalOperatorDeletesForVirtualDtor.contains(Canon))
-      return GlobalOperatorDeletesForVirtualDtor[Canon];
-    return nullptr;
-  case OperatorDeleteKind::Array:
-    if (ArrayOperatorDeletesForVirtualDtor.contains(Canon))
-      return ArrayOperatorDeletesForVirtualDtor[Canon];
-    return nullptr;
-  case OperatorDeleteKind::ArrayGlobal:
-    if (GlobalArrayOperatorDeletesForVirtualDtor.contains(Canon))
-      return GlobalArrayOperatorDeletesForVirtualDtor[Canon];
-    return nullptr;
-  }
-  return nullptr;
-}
-
 MangleNumberingContext &
 ASTContext::getManglingNumberContext(const DeclContext *DC) {
   assert(LangOpts.CPlusPlus);  // We don't need mangling numbers for plain C.
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index c16b1bb7a3453..24e4f189cbe4a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -3110,15 +3110,12 @@ CXXDestructorDecl *CXXDestructorDecl::Create(
 }
 
 void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
-  assert(!OD || (OD->getDeclName().getCXXOverloadedOperator() == OO_Delete));
-  if (OD && !getASTContext().dtorHasOperatorDelete(
-                this, ASTContext::OperatorDeleteKind::Regular)) {
-    getASTContext().addOperatorDeleteForVDtor(
-        this, OD, ASTContext::OperatorDeleteKind::Regular);
-    getCanonicalDecl()->OperatorDeleteThisArg = ThisArg;
+  auto *First = cast<CXXDestructorDecl>(getFirstDecl());
+  if (OD && !First->OperatorDelete) {
+    First->OperatorDelete = OD;
+    First->OperatorDeleteThisArg = ThisArg;
     if (auto *L = getASTMutationListener())
-      L->ResolvedOperatorDelete(cast<CXXDestructorDecl>(getCanonicalDecl()), OD,
-                                ThisArg);
+      L->ResolvedOperatorDelete(First, OD, ThisArg);
   }
 }
 
@@ -3130,63 +3127,14 @@ void CXXDestructorDecl::setOperatorGlobalDelete(FunctionDecl *OD) {
   assert(!OD ||
          (OD->getDeclName().getCXXOverloadedOperator() == OO_Delete &&
           OD->getDeclContext()->getRedeclContext()->isTranslationUnit()));
-  if (OD && !getASTContext().dtorHasOperatorDelete(
-                this, ASTContext::OperatorDeleteKind::GlobalRegular)) {
-    getASTContext().addOperatorDeleteForVDtor(
-        this, OD, ASTContext::OperatorDeleteKind::GlobalRegular);
+  auto *Canonical = cast<CXXDestructorDecl>(getCanonicalDecl());
+  if (!Canonical->OperatorGlobalDelete) {
+    Canonical->OperatorGlobalDelete = OD;
     if (auto *L = getASTMutationListener())
-      L->ResolvedOperatorGlobDelete(cast<CXXDestructorDecl>(getCanonicalDecl()),
-                                    OD);
+      L->ResolvedOperatorGlobDelete(Canonical, OD);
   }
 }
 
-void CXXDestructorDecl::setOperatorArrayDelete(FunctionDecl *OD) {
-  assert(!OD ||
-         (OD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete));
-  if (OD && !getASTContext().dtorHasOperatorDelete(
-                this, ASTContext::OperatorDeleteKind::Array)) {
-    getASTContext().addOperatorDeleteForVDtor(
-        this, OD, ASTContext::OperatorDeleteKind::Array);
-    if (auto *L = getASTMutationListener())
-      L->ResolvedOperatorArrayDelete(
-          cast<CXXDestructorDecl>(getCanonicalDecl()), OD);
-  }
-}
-
-void CXXDestructorDecl::setGlobalOperatorArrayDelete(FunctionDecl *OD) {
-  assert(!OD ||
-         (OD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete &&
-          OD->getDeclContext()->getRedeclContext()->isTranslationUnit()));
-  if (OD && !getASTContext().dtorHasOperatorDelete(
-                this, ASTContext::OperatorDeleteKind::ArrayGlobal)) {
-    getASTContext().addOperatorDeleteForVDtor(
-        this, OD, ASTContext::OperatorDeleteKind::ArrayGlobal);
-    if (auto *L = getASTMutationListener())
-      L->ResolvedOperatorGlobArrayDelete(
-          cast<CXXDestructorDecl>(getCanonicalDecl()), OD);
-  }
-}
-
-const FunctionDecl *CXXDestructorDecl::getOperatorDelete() const {
-  return getASTContext().getOperatorDeleteForVDtor(
-      this, ASTContext::OperatorDeleteKind::Regular);
-}
-
-const FunctionDecl *CXXDestructorDecl::getOperatorGlobalDelete() const {
-  return getASTContext().getOperatorDeleteForVDtor(
-      this, ASTContext::OperatorDeleteKind::GlobalRegular);
-}
-
-const FunctionDecl *CXXDestructorDecl::getArrayOperatorDelete() const {
-  return getASTContext().getOperatorDeleteForVDtor(
-      this, ASTContext::OperatorDeleteKind::Array);
-}
-
-const FunctionDecl *CXXDestructorDecl::getGlobalArrayOperatorDelete() const {
-  return getASTContext().getOperatorDeleteForVDtor(
-      this, ASTContext::OperatorDeleteKind::ArrayGlobal);
-}
-
 bool CXXDestructorDecl::isCalledByDelete(const FunctionDecl *OpDel) const {
   // C++20 [expr.delete]p6: If the value of the operand of the delete-
   // expression is not a null pointer value and the selected deallocation
@@ -3198,8 +3146,7 @@ bool CXXDestructorDecl::isCalledByDelete(const FunctionDecl *OpDel) const {
   // delete operator, as that destructor is never called, unless the
   // destructor is virtual (see [expr.delete]p8.1) because then the
   // selected operator depends on the dynamic type of the pointer.
-  const FunctionDecl *SelectedOperatorDelete =
-      OpDel ? OpDel : getOperatorDelete();
+  const FunctionDecl *SelectedOperatorDelete = OpDel ? OpDel : OperatorDelete;
   if (!SelectedOperatorDelete)
     return true;
 
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 1d914fa876759..340bb4b2ed6a3 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -71,9 +71,6 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const {
   if (const PointerType *PTy = DerivedType->getAs<PointerType>())
     DerivedType = PTy->getPointeeType();
 
-  while (const ArrayType *ATy = DerivedType->getAsArrayTypeUnsafe())
-    DerivedType = ATy->getElementType();
-
   if (DerivedType->isDependentType())
     return nullptr;
 
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index a5bcf5c97e837..5572e0a7ae59c 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -6040,8 +6040,6 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   case Dtor_Comdat:
     Out << "D5";
     break;
-  case Dtor_VectorDeleting:
-    llvm_unreachable("Itanium ABI does not use vector deleting dtors");
   }
 }
 
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 551aa7bf3321c..f1baf9f49384b 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1492,9 +1492,8 @@ void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   // <operator-name> ::= ?_G # scalar deleting destructor
   case Dtor_Deleting: Out << "?_G"; return;
   // <operator-name> ::= ?_E # vector deleting destructor
-  case Dtor_VectorDeleting:
-    Out << "?_E";
-    return;
+  // FIXME: Add a vector deleting dtor type.  It goes in the vtable, so we need
+  // it.
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
   case Dtor_Unified:
@@ -2914,12 +2913,9 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
   //               ::= @ # structors (they have no declared return type)
   if (IsStructor) {
     if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
-      // The deleting destructors take an extra argument of type int that
-      // indicates whether the storage for the object should be deleted and
-      // whether a single object or an array of objects is being destroyed. This
-      // extra argument is not reflected in the AST.
-      if (StructorType == Dtor_Deleting ||
-          StructorType == Dtor_VectorDeleting) {
+      // The scalar deleting destructor takes an extra int argument which is not
+      // reflected in the AST.
+      if (StructorType == Dtor_Deleting) {
         Out << (PointersAre64Bit ? "PEAXI at Z" : "PAXI at Z");
         return;
       }
@@ -3915,10 +3911,10 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
                                                     const ThunkInfo &Thunk,
                                                     bool /*ElideOverrideInfo*/,
                                                     raw_ostream &Out) {
-  // The dtor thunk should use vector deleting dtor mangling, however as an
-  // optimization we may end up emitting only scalar deleting dtor body, so just
-  // use the vector deleting dtor mangling manually.
-  assert(Type == Dtor_Deleting || Type == Dtor_VectorDeleting);
+  // FIXME: Actually, the dtor thunk should be emitted for vector deleting
+  // dtors rather than scalar deleting dtors. Just use the vector deleting dtor
+  // mangling manually until we support both deleting dtor types.
+  assert(Type == Dtor_Deleting);
   msvc_hashing_ostream MHO(Out);
   MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
   Mangler.getStream() << "??_E";
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 9951126c2c3a3..3ded3a51206da 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -2658,12 +2658,7 @@ class VFTableBuilder {
       MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
                                 WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-        // In Microsoft ABI vftable always references vector deleting dtor.
-        CXXDtorType DtorTy = Context.getTargetInfo().emitVectorDeletingDtors(
-                                 Context.getLangOpts())
-                                 ? Dtor_VectorDeleting
-                                 : Dtor_Deleting;
-        MethodVFTableLocations[GlobalDecl(DD, DtorTy)] = Loc;
+        MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
       } else {
         MethodVFTableLocations[MD] = Loc;
       }
@@ -3293,11 +3288,7 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
       const CXXDestructorDecl *DD = Component.getDestructorDecl();
 
       DD->printQualifiedName(Out);
-      if (Context.getTargetInfo().emitVectorDeletingDtors(
-              Context.getLangOpts()))
-        Out << "() [vector deleting]";
-      else
-        Out << "() [scalar deleting]";
+      Out << "() [scalar deleting]";
 
       if (DD->isPureVirtual())
         Out << " [pure]";
@@ -3767,7 +3758,7 @@ void MicrosoftVTableContext::dumpMethodLocations(
         PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
 
     if (isa<CXXDestructorDecl>(MD)) {
-      IndicesMap[I.second] = MethodName + " [vector deleting]";
+      IndicesMap[I.second] = MethodName + " [scalar deleting]";
     } else {
       IndicesMap[I.second] = MethodName;
     }
@@ -3883,8 +3874,7 @@ MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) {
   assert(hasVtableSlot(cast<CXXMethodDecl>(GD.getDecl())) &&
          "Only use this method for virtual methods or dtors");
   if (isa<CXXDestructorDecl>(GD.getDecl()))
-    assert(GD.getDtorType() == Dtor_VectorDeleting ||
-           GD.getDtorType() == Dtor_Deleting);
+    assert(GD.getDtorType() == Dtor_Deleting);
 
   GD = GD.getCanonicalDecl();
 
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index ffaf98bf9c366..9a5db6e164f66 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -636,13 +636,6 @@ bool TargetInfo::callGlobalDeleteInDeletingDtor(
   return false;
 }
 
-bool TargetInfo::emitVectorDeletingDtors(const LangOptions &LangOpts) const {
-  if (getCXXABI() == TargetCXXABI::Microsoft &&
-      LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21)
-    return true;
-  return false;
-}
-
 bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {
   return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;
 }
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 8ca53c1b58a9d..59aeff6804b61 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -174,6 +174,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
   // requires explicit comdat support in the IL.
   if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
     return true;
+
   // Create the alias with no name.
   auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
                                           Aliasee, &getModule());
@@ -199,42 +200,6 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
   return false;
 }
 
-/// Emit a definition as a global alias for another definition, unconditionally.
-void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl,
-                                          GlobalDecl TargetDecl) {
-
-  llvm::Type *AliasValueType = getTypes().GetFunctionType(AliasDecl);
-
-  StringRef MangledName = getMangledName(AliasDecl);
-  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
-  if (Entry && !Entry->isDeclaration())
-    return;
-  auto *Aliasee = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
-
-  // Determine the linkage type for the alias.
-  llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
-
-  // Create the alias with no name.
-  auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
-                                          Aliasee, &getModule());
-  // Destructors are always unnamed_addr.
-  Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-
-  if (Entry) {
-    assert(Entry->getValueType() == AliasValueType &&
-           Entry->getAddressSpace() == Alias->getAddressSpace() &&
-           "declaration exists with different type");
-    Alias->takeName(Entry);
-    Entry->replaceAllUsesWith(Alias);
-    Entry->eraseFromParent();
-  } else {
-    Alias->setName(MangledName);
-  }
-
-  // Set any additional necessary attributes for the alias.
-  SetCommonAttributes(AliasDecl, Alias);
-}
-
 llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
   const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
   auto *Fn = cast<llvm::Function>(
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 4051cacbbbc1d..30e5dc2b6cbd9 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -268,20 +268,6 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
   numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
 }
 
-void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
-                               QualType eltTy, llvm::Value *&numElements,
-                               llvm::Value *&allocPtr, CharUnits &cookieSize) {
-  assert(eltTy.isDestructedType());
-
-  // Derive a char* in the same address space as the pointer.
-  ptr = ptr.withElementType(CGF.Int8Ty);
-
-  cookieSize = getArrayCookieSizeImpl(eltTy);
-  Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
-  allocPtr = allocAddr.emitRawPointer(CGF);
-  numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
-}
-
 llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
                                            Address ptr,
                                            CharUnits cookieSize) {
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index 47090276c56b0..2dd320dbda976 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -583,12 +583,6 @@ class CGCXXABI {
                                QualType ElementType, llvm::Value *&NumElements,
                                llvm::Value *&AllocPtr, CharUnits &CookieSize);
 
-  /// Reads the array cookie associated with the given pointer,
-  /// that should have one.
-  void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, QualType ElementType,
-                       llvm::Value *&NumElements, llvm::Value *&AllocPtr,
-                       CharUnits &CookieSize);
-
   /// Return whether the given global decl needs a VTT parameter.
   virtual bool NeedsVTTParameter(GlobalDecl GD);
 
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index ced175a9a8f0e..f782b0cd17da4 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1442,95 +1442,6 @@ static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
   return true;
 }
 
-static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD,
-                                         CodeGenFunction &CGF,
-                                         llvm::Value *ShouldDeleteCondition) {
-  Address ThisPtr = CGF.LoadCXXThisAddress();
-  llvm::BasicBlock *ScalarBB = CGF.createBasicBlock("dtor.scalar");
-  llvm::BasicBlock *callDeleteBB =
-      CGF.createBasicBlock("dtor.call_delete_after_array_destroy");
-  llvm::BasicBlock *VectorBB = CGF.createBasicBlock("dtor.vector");
-  auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
-  llvm::Value *CheckTheBitForArrayDestroy = CGF.Builder.CreateAnd(
-      ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2));
-  llvm::Value *ShouldDestroyArray =
-      CGF.Builder.CreateIsNull(CheckTheBitForArrayDestroy);
-  CGF.Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
-
-  CGF.EmitBlock(VectorBB);
-
-  llvm::Value *numElements = nullptr;
-  llvm::Value *allocatedPtr = nullptr;
-  CharUnits cookieSize;
-  QualType EltTy = DD->getThisType()->getPointeeType();
-  CGF.CGM.getCXXABI().ReadArrayCookie(CGF, ThisPtr, EltTy, numElements,
-                                      allocatedPtr, cookieSize);
-
-  // Destroy the elements.
-  QualType::DestructionKind dtorKind = EltTy.isDestructedType();
-
-  assert(dtorKind);
-  assert(numElements && "no element count for a type with a destructor!");
-
-  CharUnits elementSize = CGF.getContext().getTypeSizeInChars(EltTy);
-  CharUnits elementAlign =
-      ThisPtr.getAlignment().alignmentOfArrayElement(elementSize);
-
-  llvm::Value *arrayBegin = ThisPtr.emitRawPointer(CGF);
-  llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP(
-      ThisPtr.getElementType(), arrayBegin, numElements, "delete.end");
-
-  // We already checked that the array is not 0-length before entering vector
-  // deleting dtor.
-  CGF.emitArrayDestroy(arrayBegin, arrayEnd, EltTy, elementAlign,
-                       CGF.getDestroyer(dtorKind),
-                       /*checkZeroLength*/ false, CGF.needsEHCleanup(dtorKind));
-
-  llvm::BasicBlock *VectorBBCont = CGF.createBasicBlock("dtor.vector.cont");
-  CGF.EmitBlock(VectorBBCont);
-
-  llvm::Value *CheckTheBitForDeleteCall = CGF.Builder.CreateAnd(
-      ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
-
-  llvm::Value *ShouldCallDelete =
-      CGF.Builder.CreateIsNull(CheckTheBitForDeleteCall);
-  CGF.Builder.CreateCondBr(ShouldCallDelete, CGF.ReturnBlock.getBlock(),
-                           callDeleteBB);
-  CGF.EmitBlock(callDeleteBB);
-  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
-  const CXXRecordDecl *ClassDecl = Dtor->getParent();
-  assert(Dtor->getArrayOperatorDelete());
-  if (!Dtor->getGlobalArrayOperatorDelete()) {
-    CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
-                       CGF.getContext().getCanonicalTagType(ClassDecl));
-  } else {
-    // If global operator[] is set, the class had its own operator delete[].
-    // In that case, check the 4th bit. If it is set, we need to call
-    // ::delete[].
-    llvm::Value *CheckTheBitForGlobDeleteCall = CGF.Builder.CreateAnd(
-        ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
-
-    llvm::Value *ShouldCallGlobDelete =
-        CGF.Builder.CreateIsNull(CheckTheBitForGlobDeleteCall);
-    llvm::BasicBlock *GlobDelete =
-        CGF.createBasicBlock("dtor.call_glob_delete_after_array_destroy");
-    llvm::BasicBlock *ClassDelete =
-        CGF.createBasicBlock("dtor.call_class_delete_after_array_destroy");
-    CGF.Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
-    CGF.EmitBlock(ClassDelete);
-    CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
-                       CGF.getContext().getCanonicalTagType(ClassDecl));
-    CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
-
-    CGF.EmitBlock(GlobDelete);
-    CGF.EmitDeleteCall(Dtor->getGlobalArrayOperatorDelete(), allocatedPtr,
-                       CGF.getContext().getCanonicalTagType(ClassDecl));
-  }
-
-  CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
-  CGF.EmitBlock(ScalarBB);
-}
-
 /// EmitDestructorBody - Emits the body of the current destructor.
 void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
@@ -1560,9 +1471,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
   // outside of the function-try-block, which means it's always
   // possible to delegate the destructor body to the complete
   // destructor.  Do so.
-  if (DtorType == Dtor_Deleting || DtorType == Dtor_VectorDeleting) {
-    if (CXXStructorImplicitParamValue && DtorType == Dtor_VectorDeleting)
-      EmitConditionalArrayDtorCall(Dtor, *this, CXXStructorImplicitParamValue);
+  if (DtorType == Dtor_Deleting) {
     RunCleanupsScope DtorEpilogue(*this);
     EnterDtorCleanups(Dtor, Dtor_Deleting);
     if (HaveInsertPoint()) {
@@ -1593,8 +1502,6 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
     llvm_unreachable("not expecting a unified dtor");
   case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
-  case Dtor_VectorDeleting:
-    llvm_unreachable("already handled vector deleting case");
 
   case Dtor_Complete:
     assert((Body || getTarget().getCXXABI().isMicrosoft()) &&
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 1489b5116e6ce..4eb99cc342275 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2363,13 +2363,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
       // Emit MS ABI vftable information.  There is only one entry for the
       // deleting dtor.
       const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
-      GlobalDecl GD =
-          DD ? GlobalDecl(
-                   DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-                           CGM.getContext().getLangOpts())
-                           ? Dtor_VectorDeleting
-                           : Dtor_Deleting)
-             : GlobalDecl(Method);
+      GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method);
       MethodVFTableLocation ML =
           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
       VIndex = ML.Index;
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index f64cf9f8a6c2d..14d8db32bafc6 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1206,16 +1206,6 @@ void CodeGenFunction::EmitNewArrayInitializer(
     EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
                                /*NewPointerIsChecked*/true,
                                CCE->requiresZeroInitialization());
-
-    // For MSVC vector deleting destructors support we record that for the class
-    // new[] was called. We try to optimize the code size and only emit vector
-    // deleting destructors when they are required. Vector deleting destructors
-    // are required for delete[] call but MSVC triggers emission of them
-    // whenever new[] is called for an object of the class and we do the same
-    // for compatibility.
-    if (CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-            CGM.getContext().getLangOpts()))
-      CGM.requireVectorDestructorDefinition(Ctor->getParent());
     return;
   }
 
@@ -1922,8 +1912,10 @@ static void EmitDestroyingObjectDelete(CodeGenFunction &CGF,
 /// Emit the code for deleting a single object.
 /// \return \c true if we started emitting UnconditionalDeleteBlock, \c false
 /// if not.
-static bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
-                             Address Ptr, QualType ElementType,
+static bool EmitObjectDelete(CodeGenFunction &CGF,
+                             const CXXDeleteExpr *DE,
+                             Address Ptr,
+                             QualType ElementType,
                              llvm::BasicBlock *UnconditionalDeleteBlock) {
   // C++11 [expr.delete]p3:
   //   If the static type of the object to be deleted is different from its
@@ -2117,42 +2109,6 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
   DeleteTy = getContext().getBaseElementType(DeleteTy);
   Ptr = Ptr.withElementType(ConvertTypeForMem(DeleteTy));
 
-  if (E->isArrayForm() &&
-      CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-          CGM.getContext().getLangOpts())) {
-    if (auto *RD = DeleteTy->getAsCXXRecordDecl()) {
-      auto *Dtor = RD->getDestructor();
-      if (Dtor && Dtor->isVirtual()) {
-        llvm::Value *NumElements = nullptr;
-        llvm::Value *AllocatedPtr = nullptr;
-        CharUnits CookieSize;
-        llvm::BasicBlock *BodyBB = createBasicBlock("vdtor.call");
-        llvm::BasicBlock *DoneBB = createBasicBlock("vdtor.nocall");
-        // Check array cookie to see if the array has length 0. Don't call
-        // the destructor in that case.
-        CGM.getCXXABI().ReadArrayCookie(*this, Ptr, E, DeleteTy, NumElements,
-                                        AllocatedPtr, CookieSize);
-
-        auto *CondTy = cast<llvm::IntegerType>(NumElements->getType());
-        llvm::Value *IsEmpty = Builder.CreateICmpEQ(
-            NumElements, llvm::ConstantInt::get(CondTy, 0));
-        Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
-
-        // Delete cookie for empty array.
-        const FunctionDecl *OperatorDelete = E->getOperatorDelete();
-        EmitBlock(DoneBB);
-        EmitDeleteCall(OperatorDelete, AllocatedPtr, DeleteTy, NumElements,
-                       CookieSize);
-        EmitBranch(DeleteEnd);
-
-        EmitBlock(BodyBB);
-        if (!EmitObjectDelete(*this, E, Ptr, DeleteTy, DeleteEnd))
-          EmitBlock(DeleteEnd);
-        return;
-      }
-    }
-  }
-
   if (E->isArrayForm()) {
     EmitArrayDelete(*this, E, Ptr, DeleteTy);
     EmitBlock(DeleteEnd);
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index c95bd9a3067a9..3fbac308a9178 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -775,9 +775,7 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
   case VTableComponent::CK_FunctionPointer:
   case VTableComponent::CK_CompleteDtorPointer:
   case VTableComponent::CK_DeletingDtorPointer: {
-    GlobalDecl GD = component.getGlobalDecl(
-        CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-            CGM.getContext().getLangOpts()));
+    GlobalDecl GD = component.getGlobalDecl();
 
     const bool IsThunk =
         nextVTableThunkIndex < layout.vtable_thunks().size() &&
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4bd3e4f8c02cf..645b78a599f89 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -8288,53 +8288,3 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) {
 
   NewBuilder->ABI->MangleCtx = std::move(ABI->MangleCtx);
 }
-
-bool CodeGenModule::classNeedsVectorDestructor(const CXXRecordDecl *RD) {
-  if (!Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts()))
-    return false;
-  CXXDestructorDecl *Dtor = RD->getDestructor();
-  // The compiler can't know if new[]/delete[] will be used outside of the DLL,
-  // so just force vector deleting destructor emission if dllexport is present.
-  // This matches MSVC behavior.
-  if (Dtor && Dtor->isVirtual() && Dtor->isDefined() &&
-      Dtor->hasAttr<DLLExportAttr>())
-    return true;
-
-  return RequireVectorDeletingDtor.count(RD);
-}
-
-void CodeGenModule::requireVectorDestructorDefinition(const CXXRecordDecl *RD) {
-  if (!Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts()))
-    return;
-  RequireVectorDeletingDtor.insert(RD);
-
-  // To reduce code size in general case we lazily emit scalar deleting
-  // destructor definition and an alias from vector deleting destructor to
-  // scalar deleting destructor. It may happen that we first emitted the scalar
-  // deleting destructor definition and the alias and then discovered that the
-  // definition of the vector deleting destructor is required. Then we need to
-  // remove the alias and the scalar deleting destructor and queue vector
-  // deleting destructor body for emission. Check if that is the case.
-  CXXDestructorDecl *DtorD = RD->getDestructor();
-  GlobalDecl ScalarDtorGD(DtorD, Dtor_Deleting);
-  StringRef MangledName = getMangledName(ScalarDtorGD);
-  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
-  if (Entry && !Entry->isDeclaration()) {
-    GlobalDecl VectorDtorGD(DtorD, Dtor_VectorDeleting);
-    StringRef VDName = getMangledName(VectorDtorGD);
-    llvm::GlobalValue *VDEntry = GetGlobalValue(VDName);
-    // It exists and it should be an alias.
-    assert(VDEntry && isa<llvm::GlobalAlias>(VDEntry));
-    auto *NewFn = llvm::Function::Create(
-        cast<llvm::FunctionType>(VDEntry->getValueType()),
-        llvm::Function::ExternalLinkage, VDName, &getModule());
-    SetFunctionAttributes(VectorDtorGD, NewFn, /*IsIncompleteFunction*/ false,
-                          /*IsThunk*/ false);
-    NewFn->takeName(VDEntry);
-    VDEntry->replaceAllUsesWith(NewFn);
-    VDEntry->eraseFromParent();
-    Entry->replaceAllUsesWith(NewFn);
-    Entry->eraseFromParent();
-    addDeferredDeclToEmit(VectorDtorGD);
-  }
-}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 2acfc83338a0c..a253bcda2d06c 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -529,9 +529,6 @@ class CodeGenModule : public CodeGenTypeCache {
   /// that we don't re-emit the initializer.
   llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
 
-  /// To remember which types did require a vector deleting dtor.
-  llvm::SmallPtrSet<const CXXRecordDecl *, 16> RequireVectorDeletingDtor;
-
   typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
       GlobalInitData;
 
@@ -1550,7 +1547,6 @@ class CodeGenModule : public CodeGenTypeCache {
   void EmitGlobal(GlobalDecl D);
 
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
-  void EmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);
 
   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
 
@@ -1828,8 +1824,6 @@ class CodeGenModule : public CodeGenTypeCache {
     // behavior. So projects like the Linux kernel can rely on it.
     return !getLangOpts().CPlusPlus;
   }
-  void requireVectorDestructorDefinition(const CXXRecordDecl *RD);
-  bool classNeedsVectorDestructor(const CXXRecordDecl *RD);
 
   // Helper to get the alignment for a variable.
   unsigned getVtableGlobalVarAlignment(const VarDecl *D = nullptr) {
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 82a0acb9cd51e..65c47633bc5c4 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -93,8 +93,6 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
         llvm_unreachable("emitting dtor comdat as function?");
       case Dtor_Unified:
         llvm_unreachable("emitting unified dtor as function?");
-      case Dtor_VectorDeleting:
-        llvm_unreachable("unexpected dtor kind for this ABI");
       }
       llvm_unreachable("bad dtor kind");
     }
@@ -460,8 +458,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
        if (!IsInlined)
          continue;
 
-       StringRef Name = CGM.getMangledName(
-           VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false));
+       StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
        auto *Entry = CGM.GetGlobalValue(Name);
        // This checks if virtual inline function has already been emitted.
        // Note that it is possible that this inline function would be emitted
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 11ca94f03cb98..71e24491f19a4 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -71,8 +71,8 @@ class MicrosoftCXXABI : public CGCXXABI {
       switch (GD.getDtorType()) {
       case Dtor_Complete:
       case Dtor_Deleting:
-      case Dtor_VectorDeleting:
         return true;
+
       case Dtor_Base:
         return false;
 
@@ -269,11 +269,7 @@ class MicrosoftCXXABI : public CGCXXABI {
 
         // There's only Dtor_Deleting in vftable but it shares the this
         // adjustment with the base one, so look up the deleting one instead.
-        LookupGD = GlobalDecl(
-            DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-                    CGM.getContext().getLangOpts())
-                    ? Dtor_VectorDeleting
-                    : Dtor_Deleting);
+        LookupGD = GlobalDecl(DD, Dtor_Deleting);
       }
       MethodVFTableLocation ML =
           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
@@ -355,9 +351,8 @@ class MicrosoftCXXABI : public CGCXXABI {
 
   void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
                                         CallArgList &CallArgs) override {
-    assert((GD.getDtorType() == Dtor_VectorDeleting ||
-            GD.getDtorType() == Dtor_Deleting) &&
-           "Only vector deleting destructor thunks are available in this ABI");
+    assert(GD.getDtorType() == Dtor_Deleting &&
+           "Only deleting destructor thunks are available in this ABI");
     CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
                  getContext().IntTy);
   }
@@ -1112,8 +1107,7 @@ bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
 
 static bool isDeletingDtor(GlobalDecl GD) {
   return isa<CXXDestructorDecl>(GD.getDecl()) &&
-         (GD.getDtorType() == Dtor_Deleting ||
-          GD.getDtorType() == Dtor_VectorDeleting);
+         GD.getDtorType() == Dtor_Deleting;
 }
 
 bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
@@ -1366,8 +1360,7 @@ MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
   AddedStructorArgCounts Added;
   // TODO: 'for base' flag
   if (isa<CXXDestructorDecl>(GD.getDecl()) &&
-      (GD.getDtorType() == Dtor_Deleting ||
-       GD.getDtorType() == Dtor_VectorDeleting)) {
+      GD.getDtorType() == Dtor_Deleting) {
     // The scalar deleting destructor takes an implicit int parameter.
     ArgTys.push_back(getContext().IntTy);
     ++Added.Suffix;
@@ -1399,7 +1392,7 @@ void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
                                                  CXXDtorType DT) const {
   // Deleting destructor variants are never imported or exported. Give them the
   // default storage class.
-  if (DT == Dtor_Deleting || DT == Dtor_VectorDeleting) {
+  if (DT == Dtor_Deleting) {
     GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
   } else {
     const NamedDecl *ND = Dtor;
@@ -1435,12 +1428,6 @@ llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
     return llvm::GlobalValue::LinkOnceODRLinkage;
   case Dtor_Unified:
     llvm_unreachable("MS C++ ABI does not support unified dtors");
-  case Dtor_VectorDeleting:
-    // Use the weak, non-ODR linkage for vector deleting destructors to block
-    // inlining. This enables an MS ABI code-size saving optimization that
-    // allows us to avoid emitting array deletion code when arrays of a given
-    // type are not allocated within the final linkage unit.
-    return llvm::GlobalValue::WeakAnyLinkage;
   case Dtor_Comdat:
     llvm_unreachable("MS C++ ABI does not support comdat dtors");
   }
@@ -1472,11 +1459,7 @@ MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
 
     // There's no Dtor_Base in vftable but it shares the this adjustment with
     // the deleting one, so look it up instead.
-    GD =
-        GlobalDecl(DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-                           CGM.getContext().getLangOpts())
-                           ? Dtor_VectorDeleting
-                           : Dtor_Deleting);
+    GD = GlobalDecl(DD, Dtor_Deleting);
   }
 
   MethodVFTableLocation ML =
@@ -1525,11 +1508,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
 
     // There's only Dtor_Deleting in vftable but it shares the this adjustment
     // with the base one, so look up the deleting one instead.
-    LookupGD =
-        GlobalDecl(DD, CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
-                           CGM.getContext().getLangOpts())
-                           ? Dtor_VectorDeleting
-                           : Dtor_Deleting);
+    LookupGD = GlobalDecl(DD, Dtor_Deleting);
   }
   MethodVFTableLocation ML =
       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
@@ -2039,30 +2018,24 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
   auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
   auto *D = dyn_cast<const CXXDeleteExpr *>(E);
   assert((CE != nullptr) ^ (D != nullptr));
-  assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
-  assert(DtorType == Dtor_VectorDeleting || DtorType == Dtor_Complete ||
-         DtorType == Dtor_Deleting);
+  assert(CE == nullptr || CE->arguments().empty());
+  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
 
   // We have only one destructor in the vftable but can get both behaviors
   // by passing an implicit int parameter.
-  ASTContext &Context = getContext();
-  bool VectorDeletingDtorsEnabled =
-      Context.getTargetInfo().emitVectorDeletingDtors(Context.getLangOpts());
-  GlobalDecl GD(Dtor, VectorDeletingDtorsEnabled ? Dtor_VectorDeleting
-                                                 : Dtor_Deleting);
+  GlobalDecl GD(Dtor, Dtor_Deleting);
   const CGFunctionInfo *FInfo =
       &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
   CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
 
+  ASTContext &Context = getContext();
   bool IsDeleting = DtorType == Dtor_Deleting;
-  bool IsArrayDelete = D && D->isArrayForm() && VectorDeletingDtorsEnabled;
   bool IsGlobalDelete = D && D->isGlobalDelete() &&
                         Context.getTargetInfo().callGlobalDeleteInDeletingDtor(
                             Context.getLangOpts());
   llvm::Value *ImplicitParam =
-      CGF.Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0) |
-                           (IsArrayDelete ? 2 : 0));
+      CGF.Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0));
 
   QualType ThisTy;
   if (CE) {
@@ -2071,9 +2044,6 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
     ThisTy = D->getDestroyedType();
   }
 
-  while (const ArrayType *ATy = Context.getAsArrayType(ThisTy))
-    ThisTy = ATy->getElementType();
-
   This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
   RValue RV =
       CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy,
@@ -4104,18 +4074,6 @@ void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
   if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
     return;
 
-  if (GD.getDtorType() == Dtor_VectorDeleting &&
-      !CGM.classNeedsVectorDestructor(dtor->getParent())) {
-    // Create GlobalDecl object with the correct type for the scalar
-    // deleting destructor.
-    GlobalDecl ScalarDtorGD(dtor, Dtor_Deleting);
-
-    // Emit an alias from the vector deleting destructor to the scalar deleting
-    // destructor.
-    CGM.EmitDefinitionAsAlias(GD, ScalarDtorGD);
-    return;
-  }
-
   llvm::Function *Fn = CGM.codegenCXXStructor(GD);
   if (Fn->isWeakForLinker())
     Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName()));
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index aa36a79142e52..8030aac3d8771 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11139,11 +11139,9 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
     else
       Loc = RD->getLocation();
 
-    DeclarationName Name =
-        Context.DeclarationNames.getCXXOperatorName(OO_Delete);
     // If we have a virtual destructor, look up the deallocation function
     if (FunctionDecl *OperatorDelete = FindDeallocationFunctionForDestructor(
-            Loc, RD, /*Diagnose=*/true, /*LookForGlobal=*/false, Name)) {
+            Loc, RD, /*Diagnose=*/true, /*LookForGlobal=*/false)) {
       Expr *ThisArg = nullptr;
 
       // If the notional 'delete this' expression requires a non-trivial
@@ -11191,33 +11189,9 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
         // delete calls that require it.
         FunctionDecl *GlobalOperatorDelete =
             FindDeallocationFunctionForDestructor(Loc, RD, /*Diagnose*/ false,
-                                                  /*LookForGlobal*/ true, Name);
+                                                  /*LookForGlobal*/ true);
         Destructor->setOperatorGlobalDelete(GlobalOperatorDelete);
       }
-
-      if (Context.getTargetInfo().emitVectorDeletingDtors(
-              Context.getLangOpts())) {
-        // Lookup delete[] too in case we have to emit a vector deleting dtor.
-        DeclarationName VDeleteName =
-            Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
-        FunctionDecl *ArrOperatorDelete = FindDeallocationFunctionForDestructor(
-            Loc, RD, /*Diagnose*/ false,
-            /*LookForGlobal*/ false, VDeleteName);
-        if (ArrOperatorDelete && isa<CXXMethodDecl>(ArrOperatorDelete)) {
-          FunctionDecl *GlobalArrOperatorDelete =
-              FindDeallocationFunctionForDestructor(Loc, RD, /*Diagnose*/ false,
-                                                    /*LookForGlobal*/ true,
-                                                    VDeleteName);
-          Destructor->setGlobalOperatorArrayDelete(GlobalArrOperatorDelete);
-        } else if (!ArrOperatorDelete) {
-          ArrOperatorDelete = FindDeallocationFunctionForDestructor(
-              Loc, RD, /*Diagnose*/ false,
-              /*LookForGlobal*/ true, VDeleteName);
-        }
-        assert(ArrOperatorDelete &&
-               "Should've found at least global array delete");
-        Destructor->setOperatorArrayDelete(ArrOperatorDelete);
-      }
     }
   }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index dc7ed4e9a48bc..fe1f89b7a5dfa 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3612,9 +3612,11 @@ Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
   return Result.FD;
 }
 
-FunctionDecl *Sema::FindDeallocationFunctionForDestructor(
-    SourceLocation Loc, CXXRecordDecl *RD, bool Diagnose, bool LookForGlobal,
-    DeclarationName Name) {
+FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
+                                                          CXXRecordDecl *RD,
+                                                          bool Diagnose,
+                                                          bool LookForGlobal) {
+  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
 
   FunctionDecl *OperatorDelete = nullptr;
   CanQualType DeallocType = Context.getCanonicalTagType(RD);
@@ -3647,11 +3649,8 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
   // Try to find operator delete/operator delete[] in class scope.
   LookupQualifiedName(Found, RD);
 
-  if (Found.isAmbiguous()) {
-    if (!Diagnose)
-      Found.suppressDiagnostics();
+  if (Found.isAmbiguous())
     return true;
-  }
 
   Found.suppressDiagnostics();
 
diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h
index 23d3954f257e7..c9b9b1bbf8743 100644
--- a/clang/lib/Serialization/ASTCommon.h
+++ b/clang/lib/Serialization/ASTCommon.h
@@ -42,9 +42,7 @@ enum class DeclUpdateKind {
   DeclMarkedOpenMPDeclareTarget,
   DeclExported,
   AddedAttrToRecord,
-  CXXResolvedDtorGlobDelete,
-  CXXResolvedDtorArrayDelete,
-  CXXResolvedDtorGlobArrayDelete
+  CXXResolvedDtorGlobDelete
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 0ee8c3511527c..5456e73956659 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2339,33 +2339,19 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
 void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
   VisitCXXMethodDecl(D);
 
-  ASTContext &C = Reader.getContext();
-  CXXDestructorDecl *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl());
+  CXXDestructorDecl *Canon = D->getCanonicalDecl();
   if (auto *OperatorDelete = readDeclAs<FunctionDecl>()) {
     auto *ThisArg = Record.readExpr();
     // FIXME: Check consistency if we have an old and new operator delete.
-    if (!C.dtorHasOperatorDelete(D, ASTContext::OperatorDeleteKind::Regular)) {
-      C.addOperatorDeleteForVDtor(D, OperatorDelete,
-                                  ASTContext::OperatorDeleteKind::Regular);
+    if (!Canon->OperatorDelete) {
+      Canon->OperatorDelete = OperatorDelete;
       Canon->OperatorDeleteThisArg = ThisArg;
     }
   }
   if (auto *OperatorGlobDelete = readDeclAs<FunctionDecl>()) {
-    if (!C.dtorHasOperatorDelete(D,
-                                 ASTContext::OperatorDeleteKind::GlobalRegular))
-      C.addOperatorDeleteForVDtor(
-          D, OperatorGlobDelete, ASTContext::OperatorDeleteKind::GlobalRegular);
-  }
-  if (auto *OperatorArrayDelete = readDeclAs<FunctionDecl>()) {
-    if (!C.dtorHasOperatorDelete(D, ASTContext::OperatorDeleteKind::Array))
-      C.addOperatorDeleteForVDtor(D, OperatorArrayDelete,
-                                  ASTContext::OperatorDeleteKind::Array);
-  }
-  if (auto *OperatorGlobArrayDelete = readDeclAs<FunctionDecl>()) {
-    if (!C.dtorHasOperatorDelete(D,
-                                 ASTContext::OperatorDeleteKind::ArrayGlobal))
-      C.addOperatorDeleteForVDtor(D, OperatorGlobArrayDelete,
-                                  ASTContext::OperatorDeleteKind::ArrayGlobal);
+    if (!Canon->OperatorGlobalDelete) {
+      Canon->OperatorGlobalDelete = OperatorGlobDelete;
+    }
   }
 }
 
@@ -4866,48 +4852,22 @@ void ASTDeclReader::UpdateDecl(Decl *D) {
     case DeclUpdateKind::CXXResolvedDtorDelete: {
       // Set the 'operator delete' directly to avoid emitting another update
       // record.
-      CXXDestructorDecl *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl());
-      ASTContext &C = Reader.getContext();
       auto *Del = readDeclAs<FunctionDecl>();
+      auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl());
       auto *ThisArg = Record.readExpr();
-      auto *Dtor = cast<CXXDestructorDecl>(D);
       // FIXME: Check consistency if we have an old and new operator delete.
-      if (!C.dtorHasOperatorDelete(Dtor,
-                                   ASTContext::OperatorDeleteKind::Regular)) {
-        C.addOperatorDeleteForVDtor(Dtor, Del,
-                                    ASTContext::OperatorDeleteKind::Regular);
-        Canon->OperatorDeleteThisArg = ThisArg;
+      if (!First->OperatorDelete) {
+        First->OperatorDelete = Del;
+        First->OperatorDeleteThisArg = ThisArg;
       }
       break;
     }
 
     case DeclUpdateKind::CXXResolvedDtorGlobDelete: {
       auto *Del = readDeclAs<FunctionDecl>();
-      auto *Dtor = cast<CXXDestructorDecl>(D);
-      ASTContext &C = Reader.getContext();
-      if (!C.dtorHasOperatorDelete(
-              Dtor, ASTContext::OperatorDeleteKind::GlobalRegular))
-        C.addOperatorDeleteForVDtor(
-            Dtor, Del, ASTContext::OperatorDeleteKind::GlobalRegular);
-      break;
-    }
-    case DeclUpdateKind::CXXResolvedDtorArrayDelete: {
-      auto *Del = readDeclAs<FunctionDecl>();
-      auto *Dtor = cast<CXXDestructorDecl>(D);
-      ASTContext &C = Reader.getContext();
-      if (!C.dtorHasOperatorDelete(Dtor, ASTContext::OperatorDeleteKind::Array))
-        C.addOperatorDeleteForVDtor(Dtor, Del,
-                                    ASTContext::OperatorDeleteKind::Array);
-      break;
-    }
-    case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete: {
-      auto *Del = readDeclAs<FunctionDecl>();
-      auto *Dtor = cast<CXXDestructorDecl>(D);
-      ASTContext &C = Reader.getContext();
-      if (!C.dtorHasOperatorDelete(Dtor,
-                                   ASTContext::OperatorDeleteKind::ArrayGlobal))
-        C.addOperatorDeleteForVDtor(
-            Dtor, Del, ASTContext::OperatorDeleteKind::ArrayGlobal);
+      auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl());
+      if (!Canon->OperatorGlobalDelete)
+        Canon->OperatorGlobalDelete = Del;
       break;
     }
 
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 547497cbd87d9..e8c0d3f2b4ee9 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6531,14 +6531,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context,
         Record.AddDeclRef(Update.getDecl());
         break;
 
-      case DeclUpdateKind::CXXResolvedDtorArrayDelete:
-        Record.AddDeclRef(Update.getDecl());
-        break;
-
-      case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete:
-        Record.AddDeclRef(Update.getDecl());
-        break;
-
       case DeclUpdateKind::CXXResolvedExceptionSpec: {
         auto prototype =
           cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>();
@@ -7612,34 +7604,6 @@ void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
   });
 }
 
-void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
-                                            const FunctionDecl *ArrayDelete) {
-  if (Chain && Chain->isProcessingUpdateRecords())
-    return;
-  assert(!WritingAST && "Already writing the AST!");
-  assert(ArrayDelete && "Not given an operator delete");
-  if (!Chain)
-    return;
-  Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
-    DeclUpdates[D].push_back(
-        DeclUpdate(DeclUpdateKind::CXXResolvedDtorArrayDelete, ArrayDelete));
-  });
-}
-
-void ASTWriter::ResolvedOperatorGlobArrayDelete(
-    const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) {
-  if (Chain && Chain->isProcessingUpdateRecords())
-    return;
-  assert(!WritingAST && "Already writing the AST!");
-  assert(GlobArrayDelete && "Not given an operator delete");
-  if (!Chain)
-    return;
-  Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
-    DeclUpdates[D].push_back(DeclUpdate(
-        DeclUpdateKind::CXXResolvedDtorGlobArrayDelete, GlobArrayDelete));
-  });
-}
-
 void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
   if (Chain && Chain->isProcessingUpdateRecords()) return;
   assert(!WritingAST && "Already writing the AST!");
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 89e6d8e2acfec..c9f8797ab973f 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1794,8 +1794,6 @@ void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
   if (D->getOperatorDelete())
     Record.AddStmt(D->getOperatorDeleteThisArg());
   Record.AddDeclRef(D->getOperatorGlobalDelete());
-  Record.AddDeclRef(D->getArrayOperatorDelete());
-  Record.AddDeclRef(D->getGlobalArrayOperatorDelete());
 
   Code = serialization::DECL_CXX_DESTRUCTOR;
 }
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index ef9d8131c511c..dfbb2762ac85c 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -633,9 +633,8 @@ struct __declspec(dllexport) Y {
 };
 
 struct __declspec(dllexport) Z { virtual ~Z() {} };
-// The deleting dtor does not get exported, but we emit body of vector deleting
-// destructor:
-// M32-DAG: define weak dso_local x86_thiscallcc ptr @"??_EZ@@UAEPAXI at Z"
+// The scalar deleting dtor does not get exported:
+// M32-DAG: define linkonce_odr dso_local x86_thiscallcc ptr @"??_GZ@@UAEPAXI at Z"
 
 
 // The user-defined dtor does get exported:
diff --git a/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp b/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp
index 67df330bc3263..ea12aa64ae305 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -4,7 +4,7 @@
 // own copy the vftable when emitting the available externally constructor.
 
 // CHECK: @"??_7?$Foo at H@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [
-// CHECK-SAME:   ptr @"??_E?$Foo at H@@UEAAPEAXI at Z"
+// CHECK-SAME:   ptr @"??_G?$Foo at H@@UEAAPEAXI at Z"
 // CHECK-SAME: ] }, comdat
 
 // CHECK-LABEL: define dso_local noundef ptr @"?f@@YAPEAU?$Foo at H@@XZ"()
diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
index 670988fc1ada2..497775840e049 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -169,7 +169,7 @@ void foo() {
 // DTORS2-LABEL: define linkonce_odr dso_local x86_thiscallcc ptr @"??_EC at dtor_in_second_nvbase@@W3AEPAXI at Z"(ptr %this, i32 %should_call_delete)
 //      Do an adjustment from B* to C*.
 // DTORS2:   getelementptr i8, ptr %{{.*}}, i32 -4
-// DTORS2:   %[[CALL:.*]] = tail call x86_thiscallcc ptr @"??_EC at dtor_in_second_nvbase@@UAEPAXI at Z"
+// DTORS2:   %[[CALL:.*]] = tail call x86_thiscallcc ptr @"??_GC at dtor_in_second_nvbase@@UAEPAXI at Z"
 // DTORS2:   ret ptr %[[CALL]]
 }
 
diff --git a/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
index 83ec158ff7f51..38aa81253ccad 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -63,7 +63,8 @@ C::C() {}  // Emits vftable and forces thunk generation.
 
 // CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_EC@@W3AEPAXI at Z"(ptr noundef %this, i32 noundef %should_call_delete) {{.*}} comdat
 // CODEGEN:   getelementptr i8, ptr {{.*}}, i32 -4
-// CODEGEN:   call x86_thiscallcc noundef ptr @"??_EC@@UAEPAXI at Z"
+// FIXME: should actually call _EC, not _GC.
+// CODEGEN:   call x86_thiscallcc noundef ptr @"??_GC@@UAEPAXI at Z"
 // CODEGEN: ret
 
 // CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?public_f at C@@W3AEXXZ"(ptr
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp b/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
index 7ceb15e40e582..bc278bdb847fc 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -8,38 +8,38 @@ struct S {
   virtual ~S();
 } s;
 
-// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4S@@6B@", ptr @"??_ES@@UAEPAXI at Z"] }, comdat($"??_7S@@6B@")
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4S@@6B@", ptr @"??_GS@@UAEPAXI at Z"] }, comdat($"??_7S@@6B@")
 // RTTI-DAG: @"??_7S@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_S]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_ES@@UAEPAXI at Z"] }
+// NO-RTTI-DAG: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_GS@@UAEPAXI at Z"] }
 
 struct __declspec(dllimport) U {
   virtual ~U();
 } u;
 
-// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4U@@6B@", ptr @"??_EU@@UAEPAXI at Z"] }
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4U@@6B@", ptr @"??_GU@@UAEPAXI at Z"] }
 // RTTI-DAG: @"??_SU@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_U]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_SU@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EU@@UAEPAXI at Z"] }
+// NO-RTTI-DAG: @"??_SU@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_GU@@UAEPAXI at Z"] }
 
 struct __declspec(dllexport) V {
   virtual ~V();
 } v;
 
-// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4V@@6B@", ptr @"??_EV@@UAEPAXI at Z"] }, comdat($"??_7V@@6B@")
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4V@@6B@", ptr @"??_GV@@UAEPAXI at Z"] }, comdat($"??_7V@@6B@")
 // RTTI-DAG: @"??_7V@@6B@" = dllexport unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_V]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EV@@UAEPAXI at Z"] }
+// NO-RTTI-DAG: @"??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_GV@@UAEPAXI at Z"] }
 
 namespace {
 struct W {
   virtual ~W() {}
 } w;
 }
-// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4W@?A0x{{[^@]*}}@@6B@", ptr @"??_EW@?A0x{{[^@]*}}@@UAEPAXI at Z"] }
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4W@?A0x{{[^@]*}}@@6B@", ptr @"??_GW@?A0x{{[^@]*}}@@UAEPAXI at Z"] }
 // RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_W]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EW@?A0x{{[^@]*}}@@UAEPAXI at Z"] }
+// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_GW@?A0x{{[^@]*}}@@UAEPAXI at Z"] }
 
 struct X {};
 template <class> struct Y : virtual X {
@@ -49,7 +49,7 @@ template <class> struct Y : virtual X {
 
 extern template class Y<int>;
 template Y<int>::Y();
-// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4?$Y at H@@6B@", ptr @"??_E?$Y at H@@UAEPAXI at Z"] }, comdat($"??_7?$Y at H@@6B@")
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4?$Y at H@@6B@", ptr @"??_G?$Y at H@@UAEPAXI at Z"] }, comdat($"??_7?$Y at H@@6B@")
 // RTTI-DAG: @"??_7?$Y at H@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_Y]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_7?$Y at H@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_E?$Y at H@@UAEPAXI at Z"] }, comdat
+// NO-RTTI-DAG: @"??_7?$Y at H@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_G?$Y at H@@UAEPAXI at Z"] }, comdat
diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 7e9dce18b2797..b54775f6c5dd0 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -80,15 +80,6 @@ B::~B() {
   // CHECK2: call x86_thiscallcc void @"??1VBase@@UAE at XZ"(ptr {{[^,]*}} %[[VBASE_i8]])
   // CHECK2: ret
 
-  // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??0B at test2@@QAE at XZ"
-  // CHECK2:           (ptr {{[^,]*}} returned align 4 dereferenceable(4) %this, i32 noundef %is_most_derived)
-  // CHECK2: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
-  // CHECK2: ret
-
-  // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_GD at pr36921@@UAEPAXI at Z"(
-  // CHECK2:   %[[THIS_RELOAD:.*]] = load ptr, ptr
-  // CHECK2:   %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -4
-
   // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_GB@@UAEPAXI at Z"
   // CHECK2:   store ptr %{{.*}}, ptr %[[THIS_ADDR:.*]], align 4
   // CHECK2:   %[[THIS_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_PARAM_i8:.*]], i32 -8
@@ -302,6 +293,11 @@ void callC() { C x; }
 // CHECK: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
 // CHECK: ret
 
+// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??0B at test2@@QAE at XZ"
+// CHECK2:           (ptr {{[^,]*}} returned align 4 dereferenceable(4) %this, i32 noundef %is_most_derived)
+// CHECK2: call x86_thiscallcc noundef ptr @"??0A at test2@@QAE at XZ"(ptr {{[^,]*}} %{{.*}})
+// CHECK2: ret
+
 }
 
 namespace test3 {
@@ -484,6 +480,9 @@ struct B {
 struct C : virtual B {};
 struct D : virtual A, C {};
 D d;
+// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_GD at pr36921@@UAEPAXI at Z"(
+// CHECK2:   %[[THIS_RELOAD:.*]] = load ptr, ptr
+// CHECK2:   %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, ptr %[[THIS_RELOAD]], i32 -4
 }
 
 namespace issue_60465 {
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
index 74150b0ecb535..a407766f8ed9f 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
@@ -12,18 +12,18 @@ struct B {
 
 struct C : A, B {
   // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries).
-  // CHECK-NEXT:   0 | C::~C() [vector deleting]
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
   // CHECK-NEXT:   1 | void A::z1()
 
   // CHECK-LABEL: VFTable for 'B' in 'C' (1 entry).
-  // CHECK-NEXT:   0 | C::~C() [vector deleting]
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
 
   // CHECK-LABEL: Thunks for 'C::~C()' (1 entry).
   // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
 
   // CHECK-LABEL: VFTable indices for 'C' (1 entry).
-  // CHECK-NEXT:   0 | C::~C() [vector deleting]
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
   virtual ~C();
 };
 
@@ -41,7 +41,7 @@ struct E : D, B {
   // CHECK-NEXT:   0 | void D::z4()
 
   // CHECK-LABEL: VFTable for 'B' in 'E' (1 entry).
-  // CHECK-NEXT:   0 | E::~E() [vector deleting]
+  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
 
   // CHECK-LABEL: Thunks for 'E::~E()' (1 entry).
@@ -49,7 +49,7 @@ struct E : D, B {
 
   // CHECK-LABEL: VFTable indices for 'E' (1 entry).
   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
-  // CHECK-NEXT:   0 | E::~E() [vector deleting]
+  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
 };
 
 void build_vftable(E *obj) { delete obj; }
@@ -61,7 +61,7 @@ struct F : D, B {
   // CHECK-NEXT:   0 | void D::z4()
 
   // CHECK-LABEL: VFTable for 'B' in 'F' (1 entry).
-  // CHECK-NEXT:   0 | F::~F() [vector deleting]
+  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
 
   // CHECK-LABEL: Thunks for 'F::~F()' (1 entry).
@@ -69,7 +69,7 @@ struct F : D, B {
 
   // CHECK-LABEL: VFTable indices for 'F' (1 entry).
   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
-  // CHECK-NEXT:   0 | F::~F() [vector deleting]
+  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
 };
 
 void build_vftable(F *obj) { delete obj; }
@@ -79,7 +79,7 @@ struct G : F {
   // CHECK-NEXT:   0 | void D::z4()
 
   // CHECK-LABEL: VFTable for 'B' in 'F' in 'G' (1 entry).
-  // CHECK-NEXT:   0 | G::~G() [vector deleting]
+  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
 
   // CHECK-LABEL: Thunks for 'G::~G()' (1 entry).
@@ -87,7 +87,7 @@ struct G : F {
 
   // CHECK-LABEL: VFTable indices for 'G' (1 entry).
   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
-  // CHECK-NEXT:   0 | G::~G() [vector deleting]
+  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
   virtual ~G();
 };
 
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index 1a589370d3a74..5030a5dcd2a50 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -213,6 +213,6 @@ struct C : virtual B { C *f(); };
 C c;
 // VFTABLES-LABEL: VFTable indices for 'pr34302::C' (2 entries).
 // VFTABLES-NEXT:  -- accessible via vbtable index 1, vfptr at offset 0 --
-// VFTABLES-NEXT:    0 | pr34302::C::~C() [vector deleting]
+// VFTABLES-NEXT:    0 | pr34302::C::~C() [scalar deleting]
 // VFTABLES-NEXT:    2 | C *pr34302::C::f()
 }
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
index c95202e8cc253..b0bf927d38f7c 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -44,10 +44,10 @@ void use(B *obj) { obj->f(); }
 
 struct C {
   // CHECK-LABEL: VFTable for 'C' (2 entries)
-  // CHECK-NEXT: 0 | C::~C() [vector deleting]
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
   // CHECK-NEXT: 1 | void C::f()
   // CHECK-LABEL: VFTable indices for 'C' (2 entries).
-  // CHECK-NEXT: 0 | C::~C() [vector deleting]
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
   // CHECK-NEXT: 1 | void C::f()
 
   virtual ~C();
@@ -60,10 +60,10 @@ void use(C *obj) { obj->f(); }
 struct D {
   // CHECK-LABEL: VFTable for 'D' (2 entries)
   // CHECK-NEXT: 0 | void D::f()
-  // CHECK-NEXT: 1 | D::~D() [vector deleting]
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
   // CHECK-LABEL: VFTable indices for 'D' (2 entries)
   // CHECK-NEXT: 0 | void D::f()
-  // CHECK-NEXT: 1 | D::~D() [vector deleting]
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
 
   virtual void f();
   virtual ~D();
@@ -77,10 +77,10 @@ struct E : A {
   // CHECK-NEXT: 0 | void A::f()
   // CHECK-NEXT: 1 | void A::g()
   // CHECK-NEXT: 2 | void A::h()
-  // CHECK-NEXT: 3 | E::~E() [vector deleting]
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
   // CHECK-NEXT: 4 | void E::i()
   // CHECK-LABEL: VFTable indices for 'E' (2 entries).
-  // CHECK-NEXT: 3 | E::~E() [vector deleting]
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
   // CHECK-NEXT: 4 | void E::i()
 
   // ~E would be the key method, but it isn't used, and MS ABI has no key
@@ -98,10 +98,10 @@ struct F : A {
   // CHECK-NEXT: 1 | void A::g()
   // CHECK-NEXT: 2 | void A::h()
   // CHECK-NEXT: 3 | void F::i()
-  // CHECK-NEXT: 4 | F::~F() [vector deleting]
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
   // CHECK-LABEL: VFTable indices for 'F' (2 entries).
   // CHECK-NEXT: 3 | void F::i()
-  // CHECK-NEXT: 4 | F::~F() [vector deleting]
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
 
   virtual void i();
   virtual ~F();
@@ -115,12 +115,12 @@ struct G : E {
   // CHECK-NEXT: 0 | void G::f()
   // CHECK-NEXT: 1 | void A::g()
   // CHECK-NEXT: 2 | void A::h()
-  // CHECK-NEXT: 3 | G::~G() [vector deleting]
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
   // CHECK-NEXT: 4 | void E::i()
   // CHECK-NEXT: 5 | void G::j()
   // CHECK-LABEL: VFTable indices for 'G' (3 entries).
   // CHECK-NEXT: 0 | void G::f()
-  // CHECK-NEXT: 3 | G::~G() [vector deleting]
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
   // CHECK-NEXT: 5 | void G::j()
 
   virtual void f();  // overrides A::f()
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
index be9f281560dcf..c5ce69f5cbcac 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
@@ -57,7 +57,7 @@ struct A : virtual V1 {
   // CHECK-LABEL: VFTable for 'V1' in 'simple::A' (2 entries).
   // CHECK-NEXT: 0 | void simple::A::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
-  // CHECK-NEXT: 1 | simple::A::~A() [vector deleting]
+  // CHECK-NEXT: 1 | simple::A::~A() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::A::~A()' (1 entry).
@@ -79,7 +79,7 @@ void use(A *obj) { obj->f(); }
 struct B : virtual V3 {
   // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::B' (2 entries).
   // CHECK-NEXT: 0 | void Z::g()
-  // CHECK-NEXT: 1 | simple::B::~B() [vector deleting]
+  // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
@@ -88,7 +88,7 @@ struct B : virtual V3 {
   // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' (2 entries).
   // CHECK-NEXT: 0 | void simple::B::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
-  // CHECK-NEXT: 1 | simple::B::~B() [vector deleting]
+  // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
@@ -115,7 +115,7 @@ void use(B *obj) { obj->f(); }
 struct C : virtual V4 {
   // CHECK-LABEL: VFTable for 'Z' in 'V4' in 'simple::C' (2 entries).
   // CHECK-NEXT: 0 | void Z::g()
-  // CHECK-NEXT: 1 | simple::C::~C() [vector deleting]
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
@@ -124,7 +124,7 @@ struct C : virtual V4 {
   // CHECK-LABEL: VFTable for 'V1' in 'V4' in 'simple::C' (2 entries).
   // CHECK-NEXT: 0 | void simple::C::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
-  // CHECK-NEXT: 1 | simple::C::~C() [vector deleting]
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
@@ -136,7 +136,7 @@ struct C : virtual V4 {
   // CHECK-LABEL: VFTable for 'V2' in 'V4' in 'simple::C' (2 entries).
   // CHECK-NEXT: 0 | void simple::C::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -16, -4 non-virtual]
-  // CHECK-NEXT: 1 | simple::C::~C() [vector deleting]
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -16, -12 non-virtual]
 
   // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
@@ -162,7 +162,7 @@ class D : B {
   // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' in 'simple::D' (2 entries).
   // CHECK-NEXT: 0 | void simple::B::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, -4 non-virtual]
-  // CHECK-NEXT: 1 | simple::D::~D() [vector deleting]
+  // CHECK-NEXT: 1 | simple::D::~D() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
   D();
   int z;
@@ -180,12 +180,12 @@ struct F : virtual E {
   // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
   // CHECK-NEXT:   0 | void simple::F::g()
   // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
-  // CHECK-NEXT:   1 | simple::F::~F() [vector deleting]
+  // CHECK-NEXT:   1 | simple::F::~F() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
   // CHECK-NEXT:   0 | void simple::E::f()
-  // CHECK-NEXT:   1 | simple::F::~F() [vector deleting]
+  // CHECK-NEXT:   1 | simple::F::~F() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: vtordisp at -12, -8 non-virtual]
 
   F();
@@ -202,12 +202,12 @@ struct G : F {
   // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
   // CHECK-NEXT:   0 | void simple::F::g()
   // CHECK-NEXT:       [this adjustment: vtordisp at -4, -4 non-virtual]
-  // CHECK-NEXT:   1 | simple::G::~G() [vector deleting]
+  // CHECK-NEXT:   1 | simple::G::~G() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
   // CHECK-NEXT:   0 | void simple::E::f()
-  // CHECK-NEXT:   1 | simple::G::~G() [vector deleting]
+  // CHECK-NEXT:   1 | simple::G::~G() [scalar deleting]
   // CHECK-NEXT:       [this adjustment: vtordisp at -12, -8 non-virtual]
 
   G();
@@ -240,7 +240,7 @@ struct A : virtual simple::A {
   // CHECK-NEXT: 0 | void simple::A::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
   // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
-  // CHECK-NEXT: 1 | extended::A::~A() [vector deleting]
+  // CHECK-NEXT: 1 | extended::A::~A() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
@@ -265,7 +265,7 @@ struct B : virtual simple::A {
 
   // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::B' (2 entries).
   //  ...
-  // CHECK: 1 | extended::B::~B() [vector deleting]
+  // CHECK: 1 | extended::B::~B() [scalar deleting]
   // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
@@ -353,7 +353,7 @@ struct G : virtual simple::A {
   // CHECK-NEXT: 0 | void simple::A::f()
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
   // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
-  // CHECK-NEXT: 1 | extended::G::~G() [vector deleting]
+  // CHECK-NEXT: 1 | extended::G::~G() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
   // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
@@ -374,7 +374,7 @@ void use(G *obj) { obj->g(); }
 struct H : Z, A {
   // CHECK-LABEL: VFTable for 'Z' in 'extended::H' (2 entries).
   // CHECK-NEXT: 0 | void Z::g()
-  // CHECK-NEXT: 1 | extended::H::~H() [vector deleting]
+  // CHECK-NEXT: 1 | extended::H::~H() [scalar deleting]
 
   // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::A' in 'extended::H' (2 entries).
   // CHECK-NEXT: 0 | void simple::A::f()
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index e5e6ea5f42c1c..257ba270291c8 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -492,7 +492,7 @@ struct X {
 
 struct Y : virtual X {
   // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::Y' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::Y::~Y() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::Y::~Y() [scalar deleting]
   // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
   // CHECK-NOT: Thunks for 'vdtors::Y::~Y()'
@@ -515,7 +515,7 @@ struct U : virtual W {
   // CHECK-NEXT: 0 | void vdtors::Z::z()
 
   // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::U' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::U::~U() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: -4 non-virtual]
   // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
@@ -524,7 +524,7 @@ struct U : virtual W {
 
   // CHECK-LABEL: VFTable indices for 'vdtors::U' (1 entry).
   // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
-  // CHECK-NEXT: 0 | vdtors::U::~U() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
   virtual ~U();
 };
 
@@ -536,7 +536,7 @@ struct V : virtual W {
   // CHECK-NEXT: 0 | void vdtors::Z::z()
 
   // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::V' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::V::~V() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: -4 non-virtual]
   // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
@@ -545,7 +545,7 @@ struct V : virtual W {
 
   // CHECK-LABEL: VFTable indices for 'vdtors::V' (1 entry).
   // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
-  // CHECK-NEXT: 0 | vdtors::V::~V() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
 };
 
 V v;
@@ -557,7 +557,7 @@ struct T : virtual X {
 
 struct P : T, Y {
   // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::T' in 'vdtors::P' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::P::~P() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::P::~P() [scalar deleting]
   // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
   // CHECK-NOT: Thunks for 'vdtors::P::~P()'
@@ -574,18 +574,18 @@ struct Q {
 // PR19172: Yet another diamond we miscompiled.
 struct R : virtual Q, X {
   // CHECK-LABEL: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
-  // CHECK-NEXT: 0 | vdtors::R::~R() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: -8 non-virtual]
 
   // CHECK-LABEL: Thunks for 'vdtors::R::~R()' (1 entry).
   // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
   // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::R::~R() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
   // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
   // CHECK-LABEL: VFTable indices for 'vdtors::R' (1 entry).
-  // CHECK-NEXT: 0 | vdtors::R::~R() [vector deleting]
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
   virtual ~R();
 };
 
diff --git a/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp
index c8e374e51a031..069f0226ab948 100644
--- a/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp
+++ b/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -2,7 +2,7 @@
 
 // vftable shouldn't have RTTI data in it.
 // CHECK-NOT: @"??_R4S@@6B@"
-// CHECK: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_ES@@UAEPAXI at Z"] }, comdat
+// CHECK: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_GS@@UAEPAXI at Z"] }, comdat
 
 struct type_info;
 namespace std { using ::type_info; }
diff --git a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp b/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
deleted file mode 100644
index e8012abb79aee..0000000000000
--- a/clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=x86_64-pc-windows-msvc -o - | FileCheck --check-prefixes=X64,CHECK %s
-// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=i386-pc-windows-msvc -o - | FileCheck --check-prefixes=X86,CHECK %s
-// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=x86_64-pc-windows-msvc -fclang-abi-compat=21 -o - | FileCheck --check-prefixes=CLANG21 %s
-
-struct Bird {
-  virtual ~Bird();
-};
-
-struct Parrot : public Bird {
-// X64: @[[ParrotVtable:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Parrot@@6B@", ptr @"??_EParrot@@UEAAPEAXI at Z"] }, comdat($"??_7Parrot@@6B@")
-// X86: @[[ParrotVtable:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Parrot@@6B@", ptr @"??_EParrot@@UAEPAXI at Z"] }, comdat($"??_7Parrot@@6B@")
-// CLANG21: @[[ParrotVtable:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Parrot@@6B@", ptr @"??_GParrot@@UEAAPEAXI at Z"] }, comdat($"??_7Parrot@@6B@")
-// X64: @[[Bird:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Bird@@6B@", ptr @"??_EBird@@UEAAPEAXI at Z"] }, comdat($"??_7Bird@@6B@")
-// X86: @[[Bird:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Bird@@6B@", ptr @"??_EBird@@UAEPAXI at Z"] }, comdat($"??_7Bird@@6B@")
-// CLANG21: @[[Bird:[0-9]+]] = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4Bird@@6B@", ptr @"??_GBird@@UEAAPEAXI at Z"] }, comdat($"??_7Bird@@6B@")
-  virtual ~Parrot() {}
-};
-
-Bird::~Bird() {}
-
-// For the weird bird we first emit scalar deleting destructor, then find out
-// that we need vector deleting destructor and remove the alias.
-struct JustAWeirdBird {
-  virtual ~JustAWeirdBird() {}
-
-  bool doSmth(int n) {
-    JustAWeirdBird *c = new JustAWeirdBird[n];
-
-    delete[] c;
-    return true;
-  }
-};
-
-int i = 0;
-struct HasOperatorDelete : public Bird{
-~HasOperatorDelete() { }
-void operator delete(void *p) { i-=2; }
-void operator delete[](void *p) { i--; }
-};
-
-struct AllocatedAsArray : public Bird {
-
-};
-
-// Vector deleting dtor for Bird is an alias because no new Bird[] expressions
-// in the TU.
-// X64: @"??_EBird@@UEAAPEAXI at Z" = weak dso_local unnamed_addr alias ptr (ptr, i32), ptr @"??_GBird@@UEAAPEAXI at Z"
-// X86: @"??_EBird@@UAEPAXI at Z" = weak dso_local unnamed_addr alias ptr (ptr, i32), ptr @"??_GBird@@UAEPAXI at Z"
-// No scalar destructor for Parrot.
-// CHECK-NOT: @"??_GParrot"
-// No vector destructor definition for Bird.
-// CHECK-NOT: define{{.*}}@"??_EBird"
-// No scalar deleting dtor for JustAWeirdBird.
-// CHECK-NOT: @"??_GJustAWeirdBird"
-// CLANG21-NOT: @"??_E
-
-void dealloc(Bird *p) {
-  delete[] p;
-}
-
-Bird* alloc() {
-  Parrot* P = new Parrot[38];
-  return P;
-}
-
-
-template<class C>
-struct S {
-  void foo() { void *p = new C(); delete (C *)p; }
-};
-
-S<AllocatedAsArray[1][3]> sp;
-
-void bar() {
-  dealloc(alloc());
-
-  JustAWeirdBird B;
-  B.doSmth(38);
-
-  Bird *p = new HasOperatorDelete[2];
-  dealloc(p);
-
-  sp.foo();
-}
-
-// CHECK-LABEL: define dso_local void @{{.*}}dealloc{{.*}}(
-// CHECK-SAME: ptr noundef %[[PTR:.*]])
-// CHECK: entry:
-// CHECK-NEXT:   %[[PTRADDR:.*]] = alloca ptr
-// CHECK-NEXT:   store ptr %[[PTR]], ptr %[[PTRADDR]]
-// CHECK-NEXT:   %[[LPTR:.*]] = load ptr, ptr %[[PTRADDR]]
-// CHECK-NEXT:   %[[ISNULL:.*]] = icmp eq ptr %[[LPTR]], null
-// CHECK-NEXT:   br i1 %[[ISNULL]], label %delete.end, label %delete.notnull
-// CHECK: delete.notnull:
-// X64-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LPTR]], i64 -8
-// X86-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LPTR]], i32 -4
-// X64-NEXT:   %[[HOWMANY:.*]] = load i64, ptr %[[COOKIEGEP]]
-// X86-NEXT:   %[[HOWMANY:.*]] = load i32, ptr %[[COOKIEGEP]]
-// X64-NEXT:   %[[ISNOELEM:.*]] = icmp eq i64 %2, 0
-// X86-NEXT:   %[[ISNOELEM:.*]] = icmp eq i32 %2, 0
-// CHECK-NEXT:   br i1 %[[ISNOELEM]], label %vdtor.nocall, label %vdtor.call
-// CHECK: vdtor.nocall:
-// X64-NEXT:   %[[HOWMANYBYTES:.*]] = mul i64 8, %[[HOWMANY]]
-// X86-NEXT:   %[[HOWMANYBYTES:.*]] = mul i32 4, %[[HOWMANY]]
-// X64-NEXT:   %[[ADDCOOKIESIZE:.*]] = add i64 %[[HOWMANYBYTES]], 8
-// X86-NEXT:   %[[ADDCOOKIESIZE:.*]] = add i32 %[[HOWMANYBYTES]], 4
-// X64-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef %[[ADDCOOKIESIZE]])
-// X86-NEXT:   call void @"??_V at YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef %[[ADDCOOKIESIZE]])
-// CHECK-NEXT:   br label %delete.end
-// CHECK: vdtor.call:
-// CHECK-NEXT:   %[[VTABLE:.*]] = load ptr, ptr %[[LPTR]]
-// CHECK-NEXT:   %[[FPGEP:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
-// CHECK-NEXT:   %[[FPLOAD:.*]]  = load ptr, ptr %[[FPGEP]]
-// X64-NEXT:   %[[CALL:.*]] = call noundef ptr %[[FPLOAD]](ptr noundef nonnull align 8 dereferenceable(8) %[[LPTR]], i32 noundef 3)
-// X86-NEXT:   %[[CALL:.*]] = call x86_thiscallcc noundef ptr %[[FPLOAD]](ptr noundef nonnull align 4 dereferenceable(4) %[[LPTR]], i32 noundef 3)
-// CHECK-NEXT:   br label %delete.end
-// CHECK: delete.end:
-// CHECK-NEXT:   ret void
-
-// Normal loop over the array elements for clang21 ABI
-// CLANG21-LABEL: define dso_local void @"?dealloc@@YAXPEAUBird@@@Z"
-// CLANG21:   %p.addr = alloca ptr
-// CLANG21-NEXT:   store ptr %p, ptr %p.addr
-// CLANG21-NEXT:   %0 = load ptr, ptr %p.addr
-// CLANG21-NEXT:   %isnull = icmp eq ptr %0, null
-// CLANG21-NEXT:   br i1 %isnull, label %delete.end2, label %delete.notnull
-// CLANG21: delete.notnull:
-// CLANG21-NEXT:   %1 = getelementptr inbounds i8, ptr %0, i64 -8
-// CLANG21-NEXT:   %2 = load i64, ptr %1
-// CLANG21-NEXT:   %delete.end = getelementptr inbounds %struct.Bird, ptr %0, i64 %2
-// CLANG21-NEXT:   %arraydestroy.isempty = icmp eq ptr %0, %delete.end
-// CLANG21-NEXT:   br i1 %arraydestroy.isempty, label %arraydestroy.done1, label %arraydestroy.body
-// CLANG21: arraydestroy.body:
-// CLANG21-NEXT:   %arraydestroy.elementPast = phi ptr [ %delete.end, %delete.notnull ], [ %arraydestroy.element, %arraydestroy.body ]
-// CLANG21-NEXT:   %arraydestroy.element = getelementptr inbounds %struct.Bird, ptr %arraydestroy.elementPast, i64 -1
-// CLANG21-NEXT:   call void @"??1Bird@@UEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element)
-// CLANG21-NEXT:   %arraydestroy.done = icmp eq ptr %arraydestroy.element, %0
-// CLANG21-NEXT:   br i1 %arraydestroy.done, label %arraydestroy.done1, label %arraydestroy.body
-// CLANG21: arraydestroy.done1:
-// CLANG21-NEXT:   %3 = mul i64 8, %2
-// CLANG21-NEXT:   %4 = add i64 %3, 8
-// CLANG21-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %1, i64 noundef %4)
-// CLANG21-NEXT:   br label %delete.end2
-
-// Definition of S::foo, check that it has vector deleting destructor call
-// X64-LABEL: define linkonce_odr dso_local void @"?foo@?$S@$$BY102UAllocatedAsArray@@@@QEAAXXZ"
-// X86-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?foo@?$S@$$BY102UAllocatedAsArray@@@@QAEXXZ"
-// X64: %[[NEWCALL:.*]] = call noalias noundef nonnull ptr @"??_U at YAPEAX_K@Z"(i64 noundef 32)
-// X86: %[[NEWCALL:.*]] = call noalias noundef nonnull ptr @"??_U at YAPAXI@Z"(i32 noundef 16)
-// X64: %[[ARR:.*]] = getelementptr inbounds i8, ptr %[[NEWCALL]], i64 8
-// X86: %[[ARR:.*]] = getelementptr inbounds i8, ptr %[[NEWCALL]], i32 4
-// CHECK: store ptr %[[ARR]], ptr %[[DP:.*]]
-// CHECK: %[[DEL_PTR:.*]] = load ptr, ptr %[[DP:.*]]
-// CHECK: delete.notnull:
-// X64-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[DEL_PTR]], i64 -8
-// X86-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[DEL_PTR]], i32 -4
-// X64-NEXT:   %[[HOWMANY:.*]] = load i64, ptr %[[COOKIEGEP]]
-// X86-NEXT:   %[[HOWMANY:.*]] = load i32, ptr %[[COOKIEGEP]]
-// X64-NEXT:   %[[ISNOELEM:.*]] = icmp eq i64 %[[HOWMANY]], 0
-// X86-NEXT:   %[[ISNOELEM:.*]] = icmp eq i32 %[[HOWMANY]], 0
-// CHECK-NEXT:   br i1 %[[ISNOELEM]], label %vdtor.nocall, label %vdtor.call
-// CHECK: vdtor.nocall:                                     ; preds = %delete.notnull
-// X64-NEXT:   %[[HOWMANYBYTES:.*]] = mul i64 8, %[[HOWMANY]]
-// X86-NEXT:   %[[HOWMANYBYTES:.*]] = mul i32 4, %[[HOWMANY]]
-// X64-NEXT:   %[[ADDCOOKIESIZE:.*]] = add i64 %[[HOWMANYBYTES]], 8
-// X86-NEXT:   %[[ADDCOOKIESIZE:.*]] = add i32 %[[HOWMANYBYTES]], 4
-// X64-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef %[[ADDCOOKIESIZE]])
-// X86-NEXT:   call void @"??_V at YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef %[[ADDCOOKIESIZE]])
-// CHECK-NEXT:   br label %delete.end
-// CHECK: vdtor.call:                                       ; preds = %delete.notnull
-// CHECK-NEXT:   %[[VTABLE:.*]] = load ptr, ptr %[[DEL_PTR]]
-// CHECK-NEXT:   %[[FPGEP:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
-// CHECK-NEXT:   %[[FPLOAD:.*]]  = load ptr, ptr %[[FPGEP]]
-// X64-NEXT:   %[[CALL:.*]] = call noundef ptr %[[FPLOAD]](ptr noundef nonnull align 8 dereferenceable(8) %[[DEL_PTR]], i32 noundef 3)
-// X86-NEXT:   %[[CALL:.*]] = call x86_thiscallcc noundef ptr %[[FPLOAD]](ptr noundef nonnull align 4 dereferenceable(4) %[[DEL_PTR]], i32 noundef 3)
-// CHECK-NEXT:   br label %delete.end
-// CHECK: delete.end:
-// CHECK-NEXT:   ret void
-
-// Vector dtor definition for Parrot.
-// X64-LABEL: define weak dso_local noundef ptr @"??_EParrot@@UEAAPEAXI at Z"(
-// X64-SAME: ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[IMPLICIT_PARAM:.*]]) unnamed_addr
-// X86-LABEL: define weak dso_local x86_thiscallcc noundef ptr @"??_EParrot@@UAEPAXI at Z"(
-// X86-SAME: ptr noundef nonnull align 4 dereferenceable(4) %[[THIS:.*]], i32 noundef %[[IMPLICIT_PARAM:.*]]) unnamed_addr
-// CHECK: entry:
-// CHECK-NEXT:   %[[RET:.*]] = alloca ptr
-// CHECK-NEXT:   %[[IPADDR:.*]] = alloca i32
-// CHECK-NEXT:   %[[THISADDR:.*]] = alloca ptr
-// CHECK-NEXT:   store i32 %[[IMPLICIT_PARAM]], ptr %[[IPADDR]]
-// CHECK-NEXT:   store ptr %[[THIS]], ptr %[[THISADDR]]
-// CHECK-NEXT:   %[[LTHIS:.*]] = load ptr, ptr %[[THISADDR]]
-// CHECK-NEXT:   store ptr %[[LTHIS]], ptr %[[RET]]
-// CHECK-NEXT:   %[[LIP:.*]] = load i32, ptr %[[IPADDR]]
-// CHECK-NEXT:   %[[SECONDBIT:.*]] = and i32 %[[LIP]], 2
-// CHECK-NEXT:   %[[ISSECONDBITZERO:.*]] = icmp eq i32 %[[SECONDBIT]], 0
-// CHECK-NEXT:   br i1 %[[ISSECONDBITZERO:.*]], label %dtor.scalar, label %dtor.vector
-// CHECK: dtor.vector:
-// X64-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LTHIS]], i64 -8
-// X86-NEXT:   %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[LTHIS]], i32 -4
-// X64-NEXT:   %[[HOWMANY:.*]] = load i64, ptr %[[COOKIEGEP]]
-// X86-NEXT:   %[[HOWMANY:.*]] = load i32, ptr %[[COOKIEGEP]]
-// X64-NEXT:   %[[END:.*]] = getelementptr inbounds %struct.Parrot, ptr %[[LTHIS]], i64 %[[HOWMANY]]
-// X86-NEXT:   %[[END:.*]] = getelementptr inbounds %struct.Parrot, ptr %[[LTHIS]], i32 %[[HOWMANY]]
-// CHECK-NEXT:   br label %arraydestroy.body
-// CHECK: arraydestroy.body:
-// CHECK-NEXT:   %[[PASTELEM:.*]] = phi ptr [ %delete.end, %dtor.vector ], [ %arraydestroy.element, %arraydestroy.body ]
-// X64-NEXT:   %[[CURELEM:.*]] = getelementptr inbounds %struct.Parrot, ptr %[[PASTELEM]], i64 -1
-// X86-NEXT:   %[[CURELEM:.*]] = getelementptr inbounds %struct.Parrot, ptr %[[PASTELEM]], i32 -1
-// X64-NEXT:   call void @"??1Parrot@@UEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(8) %[[CURELEM]])
-// X86-NEXT:   call x86_thiscallcc void @"??1Parrot@@UAE at XZ"(ptr noundef nonnull align 4 dereferenceable(4) %[[CURELEM]])
-// CHECK-NEXT:   %[[DONE:.*]] = icmp eq ptr %[[CURELEM]], %[[LTHIS]]
-// CHECK-NEXT:   br i1 %[[DONE]], label %arraydestroy.done3, label %arraydestroy.body
-// CHECK: arraydestroy.done3:
-// CHECK-NEXT:   br label %dtor.vector.cont
-// CHECK: dtor.vector.cont:
-// CHECK-NEXT:   %[[FIRSTBIT:.*]] = and i32 %[[LIP]], 1
-// CHECK-NEXT:   %[[ISFIRSTBITZERO:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
-// CHECK-NEXT:   br i1 %[[ISFIRSTBITZERO]], label %dtor.continue, label %dtor.call_delete_after_array_destroy
-// CHECK: dtor.call_delete_after_array_destroy:
-// X64-NEXT:     call void @"??_V at YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef 8)
-// X86-NEXT:     call void @"??_V at YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef 4)
-// CHECK-NEXT:   br label %dtor.continue
-// CHECK: dtor.scalar:
-// X64-NEXT:   call void @"??1Parrot@@UEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(8) %[[LTHIS]])
-// X86-NEXT:   call x86_thiscallcc void @"??1Parrot@@UAE at XZ"(ptr noundef nonnull align 4 dereferenceable(4) %[[LTHIS]])
-// CHECK-NEXT:   %[[FIRSTBIT:.*]] = and i32 %[[LIP]], 1
-// CHECK-NEXT:   %[[ISFIRSTBITZERO:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
-// CHECK-NEXT:   br i1 %[[ISFIRSTBITZERO]], label %dtor.continue, label %dtor.call_delete
-// CHECK: dtor.call_delete:
-// X64-NEXT:     call void @"??3 at YAXPEAX_K@Z"(ptr noundef %[[LTHIS]], i64 noundef 8)
-// X86-NEXT:     call void @"??3 at YAXPAXI@Z"(ptr noundef %[[LTHIS]], i32 noundef 4)
-// CHECK-NEXT:   br label %dtor.continue
-// CHECK: dtor.continue:
-// CHECK-NEXT:   %[[LOADRET:.*]] = load ptr, ptr %[[RET]]
-// CHECK-NEXT:   ret ptr %[[LOADRET]]
-
-// X64: define weak dso_local noundef ptr @"??_EJustAWeirdBird@@UEAAPEAXI at Z"(
-// X64-SAME: ptr noundef nonnull align 8 dereferenceable(8) %this, i32 noundef %should_call_delete)
-// CLANG21: define linkonce_odr dso_local noundef ptr @"??_GJustAWeirdBird@@UEAAPEAXI at Z"(
-// X86: define weak dso_local x86_thiscallcc noundef ptr @"??_EJustAWeirdBird@@UAEPAXI at Z"(
-// X86-SAME: ptr noundef nonnull align 4 dereferenceable(4) %this, i32 noundef %should_call_delete) unnamed_addr
-
-// X64-LABEL: define weak dso_local noundef ptr @"??_EHasOperatorDelete@@UEAAPEAXI at Z"
-// X86-LABEL: define weak dso_local x86_thiscallcc noundef ptr @"??_EHasOperatorDelete@@UAEPAXI at Z"
-// CLANG21: define linkonce_odr dso_local noundef ptr @"??_GHasOperatorDelete@@UEAAPEAXI at Z"
-// CHECK: dtor.call_delete_after_array_destroy:
-// CHECK-NEXT: %[[SHOULD_CALL_GLOB_DELETE:.*]] = and i32 %should_call_delete2, 4
-// CHECK-NEXT: %[[CHK:.*]] = icmp eq i32 %[[SHOULD_CALL_GLOB_DELETE]], 0
-// CHECK-NEXT: br i1 %[[CHK]], label %dtor.call_class_delete_after_array_destroy, label %dtor.call_glob_delete_after_array_destroy
-// CHECK: dtor.call_class_delete_after_array_destroy:
-// X64-NEXT:   call void @"??_VHasOperatorDelete@@SAXPEAX at Z"(ptr noundef %2)
-// X86-NEXT: call void @"??_VHasOperatorDelete@@SAXPAX at Z"
-// CHECK-NEXT:   br label %dtor.continue
-// CHECK: dtor.call_glob_delete_after_array_destroy:
-// X64-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 8)
-// X86-NEXT:   call void @"??_V at YAXPAXI@Z"(ptr noundef %2, i32 noundef 4)
-// CHECK-NEXT:   br label %dtor.continue
-
-
-
-struct BaseDelete1 {
-  void operator delete[](void *);
-};
-struct BaseDelete2 {
-  void operator delete[](void *);
-};
-struct BaseDestructor {
-  BaseDestructor() {}
-  virtual ~BaseDestructor() = default;
-};
-
-struct Derived : BaseDelete1, BaseDelete2, BaseDestructor {
-  Derived() {}
-};
-
-void foobartest() {
-    Derived *a = new Derived[10]();
-    ::delete[] a;
-}
-
-// X64-LABEL: define weak dso_local noundef ptr @"??_EDerived@@UEAAPEAXI at Z"(ptr {{.*}} %this, i32 noundef %should_call_delete)
-// X86-LABEL: define weak dso_local x86_thiscallcc noundef ptr @"??_EDerived@@UAEPAXI at Z"(ptr {{.*}} %this, i32 noundef %should_call_delete)
-// CHECK:  %retval = alloca ptr
-// CHECK-NEXT:  %should_call_delete.addr = alloca i32, align 4
-// CHECK-NEXT:  %this.addr = alloca ptr
-// CHECK-NEXT:  store i32 %should_call_delete, ptr %should_call_delete.addr, align 4
-// CHECK-NEXT:  store ptr %this, ptr %this.addr
-// CHECK-NEXT:  %this1 = load ptr, ptr %this.addr
-// CHECK-NEXT:  store ptr %this1, ptr %retval
-// CHECK-NEXT:  %should_call_delete2 = load i32, ptr %should_call_delete.addr, align 4
-// CHECK-NEXT:  %0 = and i32 %should_call_delete2, 2
-// CHECK-NEXT:  %1 = icmp eq i32 %0, 0
-// CHECK-NEXT:  br i1 %1, label %dtor.scalar, label %dtor.vector
-// CHECK: dtor.vector:
-// X64-NEXT:  %2 = getelementptr inbounds i8, ptr %this1, i64 -8
-// X86-NEXT:  %2 = getelementptr inbounds i8, ptr %this1, i32 -4
-// X64-NEXT:  %3 = load i64, ptr %2
-// X86-NEXT:  %3 = load i32, ptr %2
-// X64-NEXT:  %delete.end = getelementptr inbounds %struct.Derived, ptr %this1, i64 %3
-// X86-NEXT:  %delete.end = getelementptr inbounds %struct.Derived, ptr %this1, i32 %3
-// CHECK-NEXT:  br label %arraydestroy.body
-// CHECK: arraydestroy.body:
-// CHECK-NEXT:  %arraydestroy.elementPast = phi ptr [ %delete.end, %dtor.vector ], [ %arraydestroy.element, %arraydestroy.body ]
-// X64-NEXT:  %arraydestroy.element = getelementptr inbounds %struct.Derived, ptr %arraydestroy.elementPast, i64 -1
-// X86-NEXT:  %arraydestroy.element = getelementptr inbounds %struct.Derived, ptr %arraydestroy.elementPast, i32 -1
-// X64-NEXT:  call void @"??1Derived@@UEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(16) %arraydestroy.element)
-// X86-NEXT:  call x86_thiscallcc void @"??1Derived@@UAE at XZ"(ptr noundef nonnull align 4 dereferenceable(8) %arraydestroy.element)
-// CHECK-NEXT:  %arraydestroy.done = icmp eq ptr %arraydestroy.element, %this1
-// CHECK-NEXT:  br i1 %arraydestroy.done, label %arraydestroy.done3, label %arraydestroy.body
-// CHECK: arraydestroy.done3:
-// CHECK-NEXT:  br label %dtor.vector.cont
-// CHECK: dtor.vector.cont:
-// CHECK-NEXT:  %4 = and i32 %should_call_delete2, 1
-// CHECK-NEXT:  %5 = icmp eq i32 %4, 0
-// CHECK-NEXT:  br i1 %5, label %dtor.continue, label %dtor.call_delete_after_array_destroy
-// CHECK: dtor.call_delete_after_array_destroy:
-// X64-NEXT:  call void @"??_V at YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
-// X86-NEXT:  call void @"??_V at YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
-// CHECK-NEXT:  br label %dtor.continue
-// CHECK: dtor.scalar:
-// X64-NEXT:  call void @"??1Derived@@UEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(16) %this1)
-// X86-NEXT:  call x86_thiscallcc void @"??1Derived@@UAE at XZ"(ptr noundef nonnull align 4 dereferenceable(8) %this1)
-// CHECK-NEXT:  %6 = and i32 %should_call_delete2, 1
-// CHECK-NEXT:  %7 = icmp eq i32 %6, 0
-// CHECK-NEXT:  br i1 %7, label %dtor.continue, label %dtor.call_delete
-// CHECK: dtor.call_delete:
-// X64-NEXT:  call void @"??3 at YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
-// X86-NEXT:  call void @"??3 at YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
-// CHECK-NEXT:  br label %dtor.continue
-// CHECK: dtor.continue:
-// CHECK-NEXT:  %8 = load ptr, ptr %retval
-// CHECK-NEXT:  ret ptr %8
-
-// X64: define weak dso_local noundef ptr @"??_EAllocatedAsArray@@UEAAPEAXI at Z"
-// X86: define weak dso_local x86_thiscallcc noundef ptr @"??_EAllocatedAsArray@@UAEPAXI at Z"
-// CLANG21: define linkonce_odr dso_local noundef ptr @"??_GAllocatedAsArray@@UEAAPEAXI at Z"
diff --git a/clang/test/CodeGenCXX/vtable-consteval.cpp b/clang/test/CodeGenCXX/vtable-consteval.cpp
index 220143465c574..1454f6fde357d 100644
--- a/clang/test/CodeGenCXX/vtable-consteval.cpp
+++ b/clang/test/CodeGenCXX/vtable-consteval.cpp
@@ -26,7 +26,7 @@ struct B {
 B b;
 
 // ITANIUM-DAG: @_ZTV1C = {{.*}} constant { [4 x ptr] } {{.*}} null, ptr @_ZTI1C, ptr @_ZN1CD1Ev, ptr @_ZN1CD0Ev
-// MSABI-DAG: @[[C_VFTABLE:.*]] = {{.*}} constant { [2 x ptr] } {{.*}} @"??_R4C@@6B@", ptr @"??_EC@@UEAAPEAXI at Z"
+// MSABI-DAG: @[[C_VFTABLE:.*]] = {{.*}} constant { [2 x ptr] } {{.*}} @"??_R4C@@6B@", ptr @"??_GC@@UEAAPEAXI at Z"
 struct C {
   virtual ~C() = default;
   virtual consteval C &operator=(const C&) = default;
@@ -36,7 +36,7 @@ struct C {
 C c;
 
 // ITANIUM-DAG: @_ZTV1D = {{.*}} constant { [4 x ptr] } {{.*}} null, ptr @_ZTI1D, ptr @_ZN1DD1Ev, ptr @_ZN1DD0Ev
-// MSABI-DAG: @[[D_VFTABLE:.*]] = {{.*}} constant { [2 x ptr] } {{.*}} @"??_R4D@@6B@", ptr @"??_ED@@UEAAPEAXI at Z"
+// MSABI-DAG: @[[D_VFTABLE:.*]] = {{.*}} constant { [2 x ptr] } {{.*}} @"??_R4D@@6B@", ptr @"??_GD@@UEAAPEAXI at Z"
 struct D : C {};
 // ITANIUM-DAG: @d = {{.*}}global { ptr } { {{.*}} @_ZTV1D,
 // MSABI-DAG: @"?d@@3UD@@A" = {{.*}}global { ptr } { ptr @"??_7D@@6B@" }
diff --git a/clang/test/DebugInfo/CXX/windows-dtor.cpp b/clang/test/DebugInfo/CXX/windows-dtor.cpp
index ffef45b9f7d1b..beea56ce7368b 100644
--- a/clang/test/DebugInfo/CXX/windows-dtor.cpp
+++ b/clang/test/DebugInfo/CXX/windows-dtor.cpp
@@ -16,7 +16,7 @@ struct AB: A, B {
 template struct AB<int>;
 
 // CHECK: define {{.*}}@"??_E?$AB at H@@W3AEPAXI at Z"({{.*}} !dbg [[THUNK_VEC_DEL_DTOR:![0-9]*]]
-// CHECK: call {{.*}}@"??_E?$AB at H@@UAEPAXI at Z"({{.*}}) #{{[0-9]*}}, !dbg [[THUNK_LOC:![0-9]*]]
+// CHECK: call {{.*}}@"??_G?$AB at H@@UAEPAXI at Z"({{.*}}) #{{[0-9]*}}, !dbg [[THUNK_LOC:![0-9]*]]
 // CHECK: define
 
 // CHECK: [[THUNK_VEC_DEL_DTOR]] = distinct !DISubprogram
diff --git a/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/module.modulemap b/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/module.modulemap
deleted file mode 100644
index bb7ff1c9952c8..0000000000000
--- a/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module msvc_vector_deleting_destructors { header "msvc-vector-deleting-dtors.h" export * }
diff --git a/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/msvc-vector-deleting-dtors.h b/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/msvc-vector-deleting-dtors.h
deleted file mode 100644
index 55492667e39d7..0000000000000
--- a/clang/test/Modules/Inputs/msvc-vector-deleting-dtors/msvc-vector-deleting-dtors.h
+++ /dev/null
@@ -1,16 +0,0 @@
-class Base1 {
-public:
-  void operator delete[](void *);
-};
-class Base2 {
-public:
-  void operator delete(void *);
-};
-struct Derived : Base1, Base2 {
-  virtual ~Derived() {}
-};
-void in_h_tests(Derived *p, Derived *p1) {
-  ::delete[] p;
-
-  delete[] p1;
-}
diff --git a/clang/test/Modules/msvc-vector-deleting-destructors.cpp b/clang/test/Modules/msvc-vector-deleting-destructors.cpp
deleted file mode 100644
index a0806054355db..0000000000000
--- a/clang/test/Modules/msvc-vector-deleting-destructors.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps %s -x c++ -fmodules-cache-path=%t -I %S/Inputs/msvc-vector-deleting-dtors -emit-llvm -triple=i386-pc-win32 -o - | FileCheck %s --check-prefixes CHECK,CHECK32
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps %s -x c++ -fmodules-cache-path=%t -I %S/Inputs/msvc-vector-deleting-dtors -emit-llvm -triple=x86_64-pc-win32 -o - | FileCheck %s --check-prefixes CHECK,CHECK64
-
-#include "msvc-vector-deleting-dtors.h"
-
-void call_in_module_function(void) {
-    in_h_tests(new Derived[2], new Derived[3]);
-}
-
-void out_of_module_tests(Derived *p, Derived *p1) {
-  ::delete[] p;
-
-  delete[] p1;
-}
-
-// CHECK32-LABEL: define weak dso_local x86_thiscallcc noundef ptr @"??_EDerived@@UAEPAXI at Z"
-// CHECK64-LABEL: define weak dso_local noundef ptr @"??_EDerived@@UEAAPEAXI at Z"
-// CHECK: dtor.call_class_delete_after_array_destroy:
-// CHECK32-NEXT:  call void @"??_VBase1@@SAXPAX at Z"(ptr noundef %2)
-// CHECK64-NEXT:  call void @"??_VBase1@@SAXPEAX at Z"(ptr noundef %2)
-// CHECK: dtor.call_glob_delete_after_array_destroy:
-// CHECK32-NEXT:   call void @"??_V at YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
-// CHECK64-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
-// CHECK: dtor.call_glob_delete:
-// CHECK32-NEXT:   call void @"??3 at YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
-// CHECK64-NEXT:   call void @"??3 at YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
-// CHECK: dtor.call_class_delete:
-// CHECK32-NEXT:   call void @"??3Base2@@SAXPAX at Z"(ptr noundef %this1)
-// CHECK64-NEXT:   call void @"??3Base2@@SAXPEAX at Z"(ptr noundef %this1)
diff --git a/clang/test/Modules/vtable-windows.cppm b/clang/test/Modules/vtable-windows.cppm
index e45e32d6b4d60..dbde24c8a9bdd 100644
--- a/clang/test/Modules/vtable-windows.cppm
+++ b/clang/test/Modules/vtable-windows.cppm
@@ -23,4 +23,4 @@ void test() {
 
 // Check that the virtual table is an unnamed_addr constant in comdat that can
 // be merged with the virtual table with other TUs.
-// CHECK: unnamed_addr constant {{.*}}[ptr @"??_R4Fruit@@6B@", ptr @"??_EFruit@@UAEPAXI at Z", ptr @"?eval at Fruit@@UAEXXZ"{{.*}}comdat($"??_7Fruit@@6B@")
+// CHECK: unnamed_addr constant {{.*}}[ptr @"??_R4Fruit@@6B@", ptr @"??_GFruit@@UAEPAXI at Z", ptr @"?eval at Fruit@@UAEXXZ"{{.*}}comdat($"??_7Fruit@@6B@")
diff --git a/clang/test/PCH/Inputs/msvc-vector-deleting-dtors.h b/clang/test/PCH/Inputs/msvc-vector-deleting-dtors.h
deleted file mode 100644
index 55492667e39d7..0000000000000
--- a/clang/test/PCH/Inputs/msvc-vector-deleting-dtors.h
+++ /dev/null
@@ -1,16 +0,0 @@
-class Base1 {
-public:
-  void operator delete[](void *);
-};
-class Base2 {
-public:
-  void operator delete(void *);
-};
-struct Derived : Base1, Base2 {
-  virtual ~Derived() {}
-};
-void in_h_tests(Derived *p, Derived *p1) {
-  ::delete[] p;
-
-  delete[] p1;
-}
diff --git a/clang/test/PCH/msvc-vector-deleting-destructors.cpp b/clang/test/PCH/msvc-vector-deleting-destructors.cpp
deleted file mode 100644
index f548dba8efd20..0000000000000
--- a/clang/test/PCH/msvc-vector-deleting-destructors.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Test this without pch.
-// RUN: %clang_cc1 -x c++ -include %S/Inputs/msvc-vector-deleting-dtors.h -emit-llvm -o - %s -triple=i386-pc-win32 | FileCheck %s --check-prefixes CHECK,CHECK32
-// RUN: %clang_cc1 -x c++ -include %S/Inputs/msvc-vector-deleting-dtors.h -emit-llvm -o - %s -triple=x86_64-pc-win32 | FileCheck %s --check-prefixes CHECK,CHECK64
-
-// Test with pch.
-// RUN: %clang_cc1 -x c++ -emit-pch -o %t -triple=i386-pc-win32 %S/Inputs/msvc-vector-deleting-dtors.h
-// RUN: %clang_cc1 -x c++ -include-pch %t -emit-llvm -triple=i386-pc-win32 -o - %s | FileCheck %s --check-prefixes CHECK,CHECK32
-// RUN: %clang_cc1 -x c++ -emit-pch -o %t -triple=x86_64-pc-win32 %S/Inputs/msvc-vector-deleting-dtors.h
-// RUN: %clang_cc1 -x c++ -include-pch %t -emit-llvm -triple=x86_64-pc-win32 -o - %s | FileCheck %s --check-prefixes CHECK,CHECK64
-
-void call_in_module_function(void) {
-    in_h_tests(new Derived[2], new Derived[3]);
-}
-
-void out_of_module_tests(Derived *p, Derived *p1) {
-  ::delete[] p;
-
-  delete[] p1;
-}
-
-// CHECK32-LABEL: define weak dso_local x86_thiscallcc noundef ptr @"??_EDerived@@UAEPAXI at Z"
-// CHECK64-LABEL: define weak dso_local noundef ptr @"??_EDerived@@UEAAPEAXI at Z"
-// CHECK: dtor.call_class_delete_after_array_destroy:
-// CHECK32-NEXT:  call void @"??_VBase1@@SAXPAX at Z"(ptr noundef %2)
-// CHECK64-NEXT:  call void @"??_VBase1@@SAXPEAX at Z"(ptr noundef %2)
-// CHECK: dtor.call_glob_delete_after_array_destroy:
-// CHECK32-NEXT:   call void @"??_V at YAXPAXI@Z"(ptr noundef %2, i32 noundef 8)
-// CHECK64-NEXT:   call void @"??_V at YAXPEAX_K@Z"(ptr noundef %2, i64 noundef 16)
-// CHECK: dtor.call_glob_delete:
-// CHECK32-NEXT:   call void @"??3 at YAXPAXI@Z"(ptr noundef %this1, i32 noundef 8)
-// CHECK64-NEXT:   call void @"??3 at YAXPEAX_K@Z"(ptr noundef %this1, i64 noundef 16)
-// CHECK: dtor.call_class_delete:
-// CHECK32-NEXT:   call void @"??3Base2@@SAXPAX at Z"(ptr noundef %this1)
-// CHECK64-NEXT:   call void @"??3Base2@@SAXPEAX at Z"(ptr noundef %this1)
diff --git a/clang/test/Profile/cxx-abc-deleting-dtor.cpp b/clang/test/Profile/cxx-abc-deleting-dtor.cpp
index 7c2a5bbc93af3..c65a8e8013c35 100644
--- a/clang/test/Profile/cxx-abc-deleting-dtor.cpp
+++ b/clang/test/Profile/cxx-abc-deleting-dtor.cpp
@@ -24,15 +24,16 @@ DerivedABC *useABCVTable() { return new DerivedABC(); }
 // MSVC: @"__profn_??1ABC@@{{.*}}" =
 // MSVC-NOT: @"__profn_??_G{{.*}}" =
 
+// MSVC-LABEL: define linkonce_odr dso_local noundef ptr @"??_GDerivedABC@@UEAAPEAXI at Z"(ptr {{[^,]*}} %this, {{.*}})
+// MSVC-NOT:   call void @llvm.instrprof.increment({{.*}})
+// MSVC:   call void @"??1DerivedABC@@UEAA at XZ"({{.*}})
+// MSVC:   ret void
+
 // MSVC-LABEL: define linkonce_odr dso_local noundef ptr @"??_GABC@@UEAAPEAXI at Z"(ptr {{[^,]*}} %this, {{.*}})
 // MSVC-NOT:   call void @llvm.instrprof.increment({{.*}})
 // MSVC:   call void @llvm.trap()
 // MSVC-NEXT:   unreachable
 
-// MSVC-LABEL: define linkonce_odr dso_local noundef ptr @"??_GDerivedABC@@UEAAPEAXI at Z"(ptr {{[^,]*}} %this, {{.*}})
-// MSVC-NOT:   call void @llvm.instrprof.increment({{.*}})
-// MSVC:   call void @"??1DerivedABC@@UEAA at XZ"({{.*}})
-
 // MSVC-LABEL: define linkonce_odr dso_local void @"??1DerivedABC@@UEAA at XZ"({{.*}})
 // MSVC:   call void @llvm.instrprof.increment({{.*}})
 // MSVC:   call void @"??1ABC@@UEAA at XZ"({{.*}})
diff --git a/clang/test/SemaCXX/gh134265.cpp b/clang/test/SemaCXX/gh134265.cpp
deleted file mode 100644
index 790165411c938..0000000000000
--- a/clang/test/SemaCXX/gh134265.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// RUN: %clang_cc1 %s -verify=expected -fsyntax-only -triple=x86_64-unknown-linux-gnu
-// RUN: %clang_cc1 %s -verify=expected -fsyntax-only -triple=x86_64-unknown-linux-gnu -std=c++20
-// RUN: %clang_cc1 %s -verify=expected,ms -fms-extensions -fms-compatibility -triple=x86_64-pc-windows-msvc -DMS
-
-// Verify that clang doesn't emit additional errors when searching for
-// additional operators delete for vector deleting destructors support.
-
-struct Foo {
-  virtual ~Foo() {} // expected-error {{attempt to use a deleted function}}
-  static void operator delete(void* ptr) = delete; // expected-note {{explicitly marked deleted here}}
-};
-
-
-struct Bar {
-  virtual ~Bar() {}
-  static void operator delete[](void* ptr) = delete;
-};
-
-struct Baz {
-  virtual ~Baz() {}
-  static void operator delete[](void* ptr) = delete; // expected-note {{explicitly marked deleted here}}
-};
-
-struct BarBaz {
-  ~BarBaz() {}
-  static void operator delete[](void* ptr) = delete;
-};
-
-void foobar() {
-  Baz *B = new Baz[10]();
-  delete [] B; // expected-error {{attempt to use a deleted function}}
-  BarBaz *BB = new BarBaz[10]();
-}
-
-struct BaseDelete1 {
-  void operator delete[](void *);
-};
-struct BaseDelete2 {
-  void operator delete[](void *);
-};
-struct BaseDestructor {
-  BaseDestructor() {}
-  virtual ~BaseDestructor() = default;
-};
-struct Final : BaseDelete1, BaseDelete2, BaseDestructor {
-  Final() {}
-};
-struct FinalExplicit : BaseDelete1, BaseDelete2, BaseDestructor {
-  FinalExplicit() {}
-  inline ~FinalExplicit() {}
-};
-
-#ifdef MS
-struct Final1 : BaseDelete1, BaseDelete2, BaseDestructor {
-  __declspec(dllexport) ~Final1() {}
-};
-#endif // MS
-
-void foo() {
-    Final* a = new Final[10]();
-    FinalExplicit* b = new FinalExplicit[10]();
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 35c63129b71f2..a8654869d6093 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2516,7 +2516,6 @@ static llvm::StringRef ClangToItaniumDtorKind(clang::CXXDtorType kind) {
   case clang::CXXDtorType::Dtor_Unified:
     return "D4";
   case clang::CXXDtorType::Dtor_Comdat:
-  case clang::CXXDtorType::Dtor_VectorDeleting:
     llvm_unreachable("Unexpected destructor kind.");
   }
   llvm_unreachable("Fully covered switch above");

>From 55ac1beeaf0488f18f71b32d7d67d9d2664d811b Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Fri, 21 Nov 2025 09:37:17 -0800
Subject: [PATCH 3/3] Revert "[clang][CIR] Fix build after
 4d10c1165442cbbbc0017b48fcdd7dae1ccf3678"

This reverts commit c243406a695ca056a07ef4064b0f9feee7685320.
---
 clang/lib/CIR/CodeGen/CIRGenVTables.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
index 301954405027b..36bab625c4dd2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
@@ -145,9 +145,7 @@ mlir::Attribute CIRGenVTables::getVTableComponent(
   case VTableComponent::CK_FunctionPointer:
   case VTableComponent::CK_CompleteDtorPointer:
   case VTableComponent::CK_DeletingDtorPointer: {
-    GlobalDecl gd = component.getGlobalDecl(
-        cgm.getASTContext().getTargetInfo().emitVectorDeletingDtors(
-            cgm.getASTContext().getLangOpts()));
+    GlobalDecl gd = component.getGlobalDecl();
 
     assert(!cir::MissingFeatures::cudaSupport());
 



More information about the cfe-commits mailing list