[Mlir-commits] [clang] [llvm] [mlir] [Clang][CodeGen] Start migrating away from assuming the Default AS is 0 (PR #88182)

Alex Voicu llvmlistbot at llvm.org
Sat May 11 18:01:23 PDT 2024


https://github.com/AlexVlx updated https://github.com/llvm/llvm-project/pull/88182

>From 426e74cabb003eb5dc83adf347a5800d49bc87b7 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 18 Mar 2024 11:49:12 +0000
Subject: [PATCH 01/15] Start migrating away from the embedded assumption that
 the default AS **must** be 0.

---
 clang/lib/CodeGen/CGExprCXX.cpp      |  2 +-
 clang/lib/CodeGen/CodeGenModule.cpp  | 10 ++++++----
 clang/lib/CodeGen/CodeGenTypeCache.h |  2 +-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 2adbef6d55122..b9c920a81d79c 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2222,7 +2222,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
-  llvm::Type *PtrTy = llvm::PointerType::getUnqual(getLLVMContext());
+  llvm::Type *PtrTy = Int8PtrTy;
   LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
 
   auto MaybeASCast = [=](auto &&TypeInfo) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ceecff28cbc6..7dd14d32aa2d0 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -364,7 +364,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
   IntPtrTy = llvm::IntegerType::get(LLVMContext,
     C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
+  Int8PtrTy = llvm::PointerType::get(
+      LLVMContext, C.getTargetInfo().getTargetAddressSpace(LangAS::Default));
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
       llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
@@ -4512,9 +4513,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
     IsIncompleteFunction = true;
   }
 
-  llvm::Function *F =
-      llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
-                             Entry ? StringRef() : MangledName, &getModule());
+  llvm::Function *F = llvm::Function::Create(
+      FTy, llvm::Function::ExternalLinkage,
+      getDataLayout().getProgramAddressSpace(),
+      Entry ? StringRef() : MangledName, &getModule());
 
   // Store the declaration associated with this function so it is potentially
   // updated by further declarations or definitions and emitted at the end.
diff --git a/clang/lib/CodeGen/CodeGenTypeCache.h b/clang/lib/CodeGen/CodeGenTypeCache.h
index 083d69214fb3c..e273ebe3b060f 100644
--- a/clang/lib/CodeGen/CodeGenTypeCache.h
+++ b/clang/lib/CodeGen/CodeGenTypeCache.h
@@ -51,7 +51,7 @@ struct CodeGenTypeCache {
     llvm::IntegerType *PtrDiffTy;
   };
 
-  /// void*, void** in address space 0
+  /// void*, void** in the target's default address space (often 0)
   union {
     llvm::PointerType *UnqualPtrTy;
     llvm::PointerType *VoidPtrTy;

>From 74ae6f52a5f84f8fc92135df3ff93a4a89b914ed Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 25 Mar 2024 10:55:22 +0200
Subject: [PATCH 02/15] Make querying the Global AS more robust, add 1 new test
 (WiP).

---
 clang/lib/CodeGen/CodeGenModule.cpp           | 10 ++++---
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |  4 ++-
 ...x11-with-nonzero-default-address-space.cpp | 29 +++++++++++++++++++
 3 files changed, 38 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 63d54f9b1c0b6..39ccd40bf1adb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -371,8 +371,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
       llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
-  GlobalsInt8PtrTy =
-      llvm::PointerType::get(LLVMContext, DL.getDefaultGlobalsAddressSpace());
+  GlobalsInt8PtrTy = llvm::PointerType::get(
+      LLVMContext, C.getTargetAddressSpace(GetGlobalVarAddressSpace(nullptr)));
   ConstGlobalsPtrTy = llvm::PointerType::get(
       LLVMContext, C.getTargetAddressSpace(GetGlobalConstantAddressSpace()));
   ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace();
@@ -5018,7 +5018,9 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
 
   // Create a new variable.
   GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
-                                Linkage, nullptr, Name);
+                                Linkage, nullptr, Name, nullptr,
+                                llvm::GlobalValue::NotThreadLocal,
+                                GlobalsInt8PtrTy->getAddressSpace());
 
   if (OldGV) {
     // Replace occurrences of the old variable if needed.
@@ -5133,7 +5135,7 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
     return LangAS::cuda_device;
   }
 
-  if (LangOpts.OpenMP) {
+  if (LangOpts.OpenMP && OpenMPRuntime) {
     LangAS AS;
     if (OpenMPRuntime->hasAllocateAttributeForGlobalVar(D, AS))
       return AS;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index bdd53a192f828..907798cf60b91 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3938,7 +3938,9 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
   llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
   llvm::GlobalVariable *GV =
       new llvm::GlobalVariable(M, Init->getType(),
-                               /*isConstant=*/true, Linkage, Init, Name);
+                               /*isConstant=*/true, Linkage, Init, Name,
+                               nullptr, llvm::GlobalValue::NotThreadLocal,
+                               CGM.GlobalsInt8PtrTy->getAddressSpace());
 
   // Export the typeinfo in the same circumstances as the vtable is exported.
   auto GVDLLStorageClass = DLLStorageClass;
diff --git a/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..c7a9808ba4eb0
--- /dev/null
+++ b/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s
+#include "typeinfo"
+
+namespace Test1 {
+
+struct Item {
+  const std::type_info &ti;
+  const char *name;
+  void *(*make)();
+};
+
+template<typename T> void *make_impl() { return new T; }
+template<typename T> constexpr Item item(const char *name) {
+  return { typeid(T), name, make_impl<T> };
+}
+
+struct A { virtual ~A(); };
+struct B : virtual A {};
+struct C { int n; };
+
+extern constexpr Item items[] = {
+  item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
+};
+
+constexpr auto &x = items[0].ti;
+
+constexpr auto &y = typeid(B{});
+
+}

>From ef0bd832d7fce2bd70cbdcec8de5c41003c93246 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 9 Apr 2024 18:23:41 +0100
Subject: [PATCH 03/15] Fix a few additional places where we emit globals in AS
 0 implicitly; add (more) tests.

---
 clang/lib/CodeGen/CodeGenModule.cpp           |   4 +-
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |  18 +-
 ...mic-cast-nonzero-default-address-space.cpp |  24 ++
 ...-objects-nonzero-default-address-space.cpp |  32 ++
 ...einfo-in-nonzero-default-address-space.cpp |  17 ++
 ...tch-with-nonzero-default-address-space.cpp |  25 ++
 ...x11-with-nonzero-default-address-space.cpp |   5 +-
 ...eid-with-nonzero-default-address-space.cpp |  50 +++
 ...nfo-with-nonzero-default-address-space.cpp |  48 +++
 ...le-align-nonzero-default-address-space.cpp |  13 +
 ...ume-load-nonzero-default-address-space.cpp | 288 ++++++++++++++++++
 ...onsteval-nonzero-default-address-space.cpp |  44 +++
 ...onstexpr-nonzero-default-address-space.cpp |  27 ++
 ...function-nonzero-default-address-space.cpp |  33 ++
 ...-extreme-nonzero-default-address-space.cpp | 210 +++++++++++++
 ...-linkage-nonzero-default-address-space.cpp | 217 +++++++++++++
 ...lization-nonzero-default-address-space.cpp |  60 ++++
 ...out-with-nonzero-default-address-space.cpp |  89 ++++++
 .../vtt-nonzero-default-address-space.cpp     |  27 ++
 19 files changed, 1226 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
 create mode 100644 clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4a3e4b45ca838..01763308e6c17 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3583,7 +3583,9 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
           ? llvm::GlobalValue::LinkOnceODRLinkage
           : llvm::GlobalValue::InternalLinkage;
   auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
-                                      /*isConstant=*/true, Linkage, Init, Name);
+                                      /*isConstant=*/true, Linkage, Init, Name,
+                                      nullptr, llvm::GlobalValue::NotThreadLocal,
+                                      GlobalsInt8PtrTy->getAddressSpace());
   setGVProperties(GV, TPO);
   if (supportsCOMDAT())
     GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 7589b85c9930b..942ab4c3a43d0 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3279,7 +3279,9 @@ ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
 
     GV = new llvm::GlobalVariable(
         CGM.getModule(), CGM.GlobalsInt8PtrTy,
-        /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr, Name);
+        /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr, Name,
+        nullptr, llvm::GlobalValue::NotThreadLocal,
+        CGM.GlobalsInt8PtrTy->getAddressSpace());
     const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
     CGM.setGVProperties(GV, RD);
     // Import the typeinfo symbol when all non-inline virtual methods are
@@ -3673,8 +3675,18 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
   if (CGM.getItaniumVTableContext().isRelativeLayout())
     VTable = CGM.getModule().getNamedAlias(VTableName);
   if (!VTable) {
-    llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);
-    VTable = CGM.getModule().getOrInsertGlobal(VTableName, Ty);
+    VTable = CGM.GetGlobalValue(VTableName);
+    if (!VTable) {
+      llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);
+      // FIXME: External StdLib VTables should be constant as well, but changing
+      //        it *might* constitute a very subtle ABI break.
+      VTable = new llvm::GlobalVariable(CGM.getModule(), Ty,
+                                        /*isConstant=*/false,
+                                        llvm::GlobalVariable::ExternalLinkage,
+                                        nullptr, VTableName, nullptr,
+                                        llvm::GlobalValue::NotThreadLocal,
+                                        CGM.GlobalsInt8PtrTy->getAddressSpace());
+    }
   }
 
   CGM.setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
diff --git a/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..9a9fbdbd14582
--- /dev/null
+++ b/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+struct A { virtual void f(); };
+struct B : A { };
+
+// CHECK: {{define.*@_Z1fP1A}}
+// CHECK-SAME:  personality ptr @__gxx_personality_v0
+B fail;
+const B& f(A *a) {
+  try {
+    // CHECK: call {{.*}} ptr addrspace(4) @__dynamic_cast
+    // CHECK: br i1
+    // CHECK: invoke {{.*}} void @__cxa_bad_cast() [[NR:#[0-9]+]]
+    dynamic_cast<const B&>(*a);
+  } catch (...) {
+    // CHECK:      landingpad { ptr addrspace(4), i32 }
+    // CHECK-NEXT:   catch ptr addrspace(4) null
+  }
+  return fail;
+}
+
+// CHECK: declare {{.*}} ptr addrspace(4) @__dynamic_cast(ptr addrspace(4), ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]
+
+// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..9fc95acaebc7b
--- /dev/null
+++ b/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -std=c++20 %s -emit-llvm -o - | FileCheck %s
+
+struct S { char buf[32]; };
+template<S s> constexpr const char *begin() { return s.buf; }
+template<S s> constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); }
+template<S s> constexpr const void *retval() { return &s; }
+extern const void *callee(const S*);
+template<S s> constexpr const void* observable_addr() { return callee(&s); }
+
+// CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
+// CHECK-SAME: = linkonce_odr addrspace(1) constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat
+
+// CHECK: @p
+// CHECK-SAME: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
+const char *p = begin<S{"hello world"}>();
+
+// CHECK: @q
+// CHECK-SAME: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr addrspace(4))
+const char *q = end<S{"hello world"}>();
+
+const void *(*r)() = &retval<S{"hello world"}>;
+
+// CHECK: @s
+// CHECK-SAME: addrspace(1) global ptr addrspace(4) null
+const void *s = observable_addr<S{"hello world"}>();
+
+// CHECK: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
+// CHECK: ret ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
+
+// CHECK: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
+// CHECK: %call = call {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4)))
+// CHECK: declare {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef)
diff --git a/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..b7fcde23efe6d
--- /dev/null
+++ b/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
+
+struct X {
+  ~X();
+};
+
+struct Error {
+  Error(const X&) noexcept;
+};
+
+void f() {
+  try {
+    throw Error(X());
+  } catch (...) { }
+}
+
+// CHECK: declare{{.*}} void @__cxa_throw(ptr addrspace(4), ptr addrspace(1), ptr addrspace(4))
diff --git a/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..62143ef580835
--- /dev/null
+++ b/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+struct X { };
+
+const X g();
+
+void f() {
+  try {
+    throw g();
+    // CHECK: ptr addrspace(1) @_ZTI1X
+  } catch (const X x) {
+    // CHECK: catch ptr addrspace(1) @_ZTI1X
+    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
+  }
+}
+
+void h() {
+  try {
+    throw "ABC";
+    // CHECK: ptr addrspace(1) @_ZTIPKc
+  } catch (char const(&)[4]) {
+    // CHECK: catch ptr addrspace(1) @_ZTIA4_c
+    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
+  }
+}
diff --git a/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
index c7a9808ba4eb0..cc6bc7f53b70a 100644
--- a/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
+++ b/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s
 #include "typeinfo"
 
 namespace Test1 {
@@ -18,12 +18,15 @@ struct A { virtual ~A(); };
 struct B : virtual A {};
 struct C { int n; };
 
+// CHECK: @_ZN5Test15itemsE ={{.*}} addrspace(1) constant [4 x {{.*}}] [{{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implIiEEPvv }]
 extern constexpr Item items[] = {
   item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
 };
 
+// CHECK: @_ZN5Test11xE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
 constexpr auto &x = items[0].ti;
 
+// CHECK: @_ZN5Test11yE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), align 8
 constexpr auto &y = typeid(B{});
 
 }
diff --git a/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..3a5a5515c46b4
--- /dev/null
+++ b/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+#include <typeinfo>
+
+namespace Test1 {
+
+// PR7400
+struct A { virtual void f(); };
+
+// CHECK: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), align 8
+const std::type_info &int_ti = typeid(int);
+
+// CHECK: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
+const std::type_info &A_ti = typeid(const volatile A &);
+
+volatile char c;
+
+// CHECK: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIc to ptr addrspace(4)), align 8
+const std::type_info &c_ti = typeid(c);
+
+extern const double &d;
+
+// CHECK: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTId to ptr addrspace(4)), align 8
+const std::type_info &d_ti = typeid(d);
+
+extern A &a;
+
+// CHECK: @_ZN5Test14a_tiE ={{.*}} global
+const std::type_info &a_ti = typeid(a);
+
+// CHECK: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr addrspace(4)), align 8
+const std::type_info &A10_c_ti = typeid(char const[10]);
+
+// CHECK-LABEL: define{{.*}} ptr addrspace(4) @_ZN5Test11fEv
+// CHECK-SAME:  personality ptr @__gxx_personality_v0
+const char *f() {
+  try {
+    // CHECK: br i1
+    // CHECK: invoke{{.*}} void @__cxa_bad_typeid() [[NR:#[0-9]+]]
+    return typeid(*static_cast<A *>(0)).name();
+  } catch (...) {
+    // CHECK:      landingpad { ptr addrspace(4), i32 }
+    // CHECK-NEXT:   catch ptr addrspace(4) null
+  }
+
+  return 0;
+}
+
+}
+
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..7eab1ba86b9df
--- /dev/null
+++ b/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s -check-prefix=AS
+// RUN: %clang_cc1 -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s -check-prefix=NO-AS
+#include <typeinfo>
+
+class A {
+    virtual void f() = 0;
+};
+
+class B : A {
+    void f() override;
+};
+
+// AS: @_ZTISt9type_info = external addrspace(1) constant ptr addrspace(1)
+// NO-AS: @_ZTISt9type_info = external constant ptr
+// AS: @_ZTIi = external addrspace(1) constant ptr addrspace(1)
+// NO-AS: @_ZTIi = external constant ptr
+// AS: @_ZTVN10__cxxabiv117__class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
+// NO-AS: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
+// AS: @_ZTS1A = linkonce_odr addrspace(1) constant [3 x i8] c"1A\00", comdat, align 1
+// NO-AS: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00", comdat, align 1
+// AS: @_ZTI1A = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1A }, comdat, align 8
+// NO-AS: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1A }, comdat, align 8
+// AS: @_ZTIf = external addrspace(1) constant ptr addrspace(1)
+// NO-AS: @_ZTIf = external constant ptr
+
+unsigned long Fn(B& b) {
+// AS: %call = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr addrspace(4)), ptr addrspace(4) {{.*}} %2)
+// NO-AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} @_ZTISt9type_info, ptr {{.*}} %2)
+    if (typeid(std::type_info) == typeid(b))
+        return 42;
+// AS: %call2 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), ptr addrspace(4) {{.*}} %5)
+// NO-AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} @_ZTIi, ptr {{.*}} %5)
+    if (typeid(int) != typeid(b))
+        return 1712;
+// AS: %call5 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr addrspace(4)))
+// NO-AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} @_ZTI1A)
+// AS: %call7 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} %8)
+// NO-AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
+    if (typeid(A).name() == typeid(b).name())
+        return 0;
+// AS: %call11 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr addrspace(4) {{.*}} %11, ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr addrspace(4)))
+// NO-AS:   %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} @_ZTIf)
+    if (typeid(b).before(typeid(float)))
+        return 1;
+// AS: %call15 = call{{.*}} noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr addrspace(4) {{.*}} %14)
+// NO-AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
+    return typeid(b).hash_code();
+}
diff --git a/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..2a1a7293982f1
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual void f();
+  virtual void g();
+  virtual void h();
+};
+
+void A::f() {}
+
+// CHECK: @_ZTV1A ={{.*}} unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1A, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1A1gEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1A1hEv to ptr addrspace(1))]
+// CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1
+// CHECK: @_ZTI1A ={{.*}} addrspace(1) constant { ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1A }, align 8
diff --git a/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..63e7bb8b570a6
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp
@@ -0,0 +1,288 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// FIXME: Assume load should not require -fstrict-vtable-pointers
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
+namespace test1 {
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : A {
+  virtual void foo();
+};
+
+void g(A *a) { a->foo(); }
+
+// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv()
+// CHECK1: call{{.*}} void @_ZN5test11AC1Ev(ptr addrspace(4)
+// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, i32 0, i32 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: {{^}}}
+
+void fooA() {
+  A a;
+  g(&a);
+}
+
+// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv()
+// CHECK1: call{{.*}} void @_ZN5test11BC1Ev(ptr addrspace(4) {{[^,]*}} %{{.*}})
+// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, i32 0, i32 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: {{^}}}
+
+void fooB() {
+  B b;
+  g(&b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr{{.*}} void @_ZN5test11BC2Ev(ptr addrspace(4)
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: {{^}}}
+}
+namespace test2 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B {
+  B();
+  virtual void bar();
+};
+
+struct C : A, B {
+  C();
+  virtual void foo();
+};
+void g(A *a) { a->foo(); }
+void h(B *b) { b->bar(); }
+
+// CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv()
+// CHECK2: call{{.*}} void @_ZN5test21CC1Ev(ptr
+// CHECK2: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) {{.*}}
+// CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 0, i32 2)
+// CHECK2: call void @llvm.assume(i1 %[[CMP]])
+
+// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 8
+// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr addrspace(4) %[[ADD_PTR]]
+// CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 1, i32 2)
+// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
+
+// CHECK2: call{{.*}} void @_ZN5test21gEPNS_1AE(ptr addrspace(4)
+// CHECK2-LABEL: {{^}}}
+
+void test() {
+  C c;
+  g(&c);
+  h(&c);
+}
+}
+
+namespace test3 {
+struct A {
+  A();
+};
+
+struct B : A {
+  B();
+  virtual void foo();
+};
+
+struct C : virtual A, B {
+  C();
+  virtual void foo();
+};
+void g(B *a) { a->foo(); }
+
+// CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv()
+// CHECK3: call{{.*}} void @_ZN5test31CC1Ev(ptr addrspace(4)
+// CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, i32 0, i32 3)
+// CHECK3: call void @llvm.assume(i1 %[[CMP]])
+// CHECK3-LABLEL: }
+void test() {
+  C c;
+  g(&c);
+}
+} // test3
+
+namespace test4 {
+struct A {
+  A();
+  virtual void foo();
+};
+
+struct B : virtual A {
+  B();
+  virtual void foo();
+};
+struct C : B {
+  C();
+  virtual void foo();
+};
+
+void g(C *c) { c->foo(); }
+
+// CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv()
+// CHECK4: call{{.*}} void @_ZN5test41CC1Ev(ptr addrspace(4)
+// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
+// CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
+// CHECK4: call void @llvm.assume(i1 %[[CMP]]
+
+// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
+// CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
+// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
+// CHECK4-LABEL: {{^}}}
+
+void test() {
+  C c;
+  g(&c);
+}
+} // test4
+
+namespace test6 {
+struct A {
+  A();
+  virtual void foo();
+  virtual ~A() {}
+};
+struct B : A {
+  B();
+};
+// FIXME: Because A's vtable is external, and no virtual functions are hidden,
+// it's safe to generate assumption loads.
+// CHECK5-LABEL: define{{.*}} void @_ZN5test61gEv()
+// CHECK5: call{{.*}} void @_ZN5test61AC1Ev(ptr addrspace(4)
+// CHECK5-NOT: call void @llvm.assume(
+
+// We can't emit assumption loads for B, because if we would refer to vtable
+// it would refer to functions that will not be able to find (like implicit
+// inline destructor).
+
+// CHECK5-LABEL:   call{{.*}} void @_ZN5test61BC1Ev(ptr addrspace(4)
+// CHECK5-NOT: call void @llvm.assume(
+// CHECK5-LABEL: {{^}}}
+void g() {
+  A *a = new A;
+  B *b = new B;
+}
+}
+
+namespace test7 {
+// Because A's key function is defined here, vtable is generated in this TU
+// CHECK6: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
+struct A {
+  A();
+  virtual void foo();
+  virtual void bar();
+};
+void A::foo() {}
+
+// CHECK6-LABEL: define{{.*}} void @_ZN5test71gEv()
+// CHECK6: call{{.*}} void @_ZN5test71AC1Ev(ptr addrspace(4)
+// CHECK6: call void @llvm.assume(
+// CHECK6-LABEL: {{^}}}
+void g() {
+  A *a = new A();
+  a->bar();
+}
+}
+
+namespace test8 {
+
+struct A {
+  virtual void foo();
+  virtual void bar();
+};
+
+// CHECK7-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
+struct B : A {
+  B();
+  void foo();
+  void bar();
+};
+
+// CHECK7-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
+struct C : A {
+  C();
+  void bar();
+  void foo() {}
+};
+inline void C::bar() {}
+
+struct D : A {
+  D();
+  void foo();
+  void inline bar();
+};
+void D::bar() {}
+
+// CHECK7-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
+struct E : A {
+  E();
+};
+
+// CHECK7-LABEL: define{{.*}} void @_ZN5test81bEv()
+// CHECK7: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
+void b() {
+  B b;
+  b.bar();
+}
+
+// FIXME: C has inline virtual functions which prohibits as from generating
+// assumption loads, but because vtable is generated in this TU (key function
+// defined here) it would be correct to refer to it.
+// CHECK7-LABEL: define{{.*}} void @_ZN5test81cEv()
+// CHECK7-NOT: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
+void c() {
+  C c;
+  c.bar();
+}
+
+// FIXME: We could generate assumption loads here.
+// CHECK7-LABEL: define{{.*}} void @_ZN5test81dEv()
+// CHECK7-NOT: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
+void d() {
+  D d;
+  d.bar();
+}
+
+// CHECK7-LABEL: define{{.*}} void @_ZN5test81eEv()
+// CHECK7: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
+void e() {
+  E e;
+  e.bar();
+}
+}
+
+namespace test9 {
+
+struct S {
+  S();
+  __attribute__((visibility("hidden"))) virtual void doStuff();
+};
+
+// CHECK8-LABEL: define{{.*}} void @_ZN5test94testEv()
+// CHECK8-NOT: @llvm.assume(
+// CHECK8: }
+void test() {
+  S *s = new S();
+  s->doStuff();
+  delete s;
+}
+}
+
diff --git a/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..4e3850264d42f
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++20 -triple=spirv64-unknown-unknown -fsycl-is-device %s -emit-llvm -o - | FileCheck %s --check-prefix=ITANIUM --implicit-check-not=DoNotEmit
+
+// FIXME: The MSVC ABI rule in use here was discussed with MS folks prior to
+// them implementing virtual consteval functions, but we do not know for sure
+// if this is the ABI rule they will use.
+
+// ITANIUM-DAG: @_ZTV1A = {{.*}} addrspace(1) constant { [2 x ptr addrspace(1)] } {{.*}} null, {{.*}} @_ZTI1A
+struct A {
+  virtual consteval void DoNotEmit_f() {}
+};
+// ITANIUM-DAG: @a = addrspace(1) global { {{.*}} ptr addrspace(1) @_ZTV1A,
+A a;
+
+// ITANIUM-DAG: @_ZTV1B = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1B1fEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1B1hEv to ptr addrspace(1))
+struct B {
+  virtual void f() {}
+  virtual consteval void DoNotEmit_g() {}
+  virtual void h() {}
+};
+// ITANIUM-DAG: @b = addrspace(1) global { {{.*}} @_ZTV1B,
+B b;
+
+// ITANIUM-DAG: @_ZTV1C = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1C, ptr addrspace(1) addrspacecast (ptr @_ZN1CD1Ev to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1CD0Ev to ptr addrspace(1))
+struct C {
+  virtual ~C() = default;
+  virtual consteval C &operator=(const C&) = default;
+};
+// ITANIUM-DAG: @c = addrspace(1) global { {{.*}} @_ZTV1C,
+C c;
+
+// ITANIUM-DAG: @_ZTV1D = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1D, ptr addrspace(1) addrspacecast (ptr @_ZN1DD1Ev to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1DD0Ev to ptr addrspace(1))
+struct D : C {};
+// ITANIUM-DAG: @d = addrspace(1) global { ptr addrspace(1) } { {{.*}} @_ZTV1D,
+D d;
+
+// ITANIUM-DAG: @_ZTV1E = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1E, ptr addrspace(1) addrspacecast (ptr @_ZN1E1fEv to ptr addrspace(1))
+struct E { virtual void f() {} };
+// ITANIUM-DAG: @e = addrspace(1) global { {{.*}} @_ZTV1E,
+E e;
+
+// ITANIUM-DAG: @_ZTV1F = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1F, ptr addrspace(1) addrspacecast (ptr @_ZN1E1fEv to ptr addrspace(1))
+struct F : E { virtual consteval void DoNotEmit_g(); };
+// ITANIUM-DAG: @f = addrspace(1) global { ptr addrspace(1) } { {{.*}} @_ZTV1F,
+F f;
diff --git a/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..ea53d7208fc39
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++20 -triple=spirv64-unknown-unknown -fsycl-is-device %s -emit-llvm -o - | FileCheck %s --implicit-check-not=DoNotEmit
+
+// constexpr virtual functions can be called at runtime and go in the vtable as
+// normal. But they are implicitly inline so are never the key function.
+
+struct DoNotEmit {
+  virtual constexpr void f();
+};
+constexpr void DoNotEmit::f() {}
+
+// CHECK-DAG: @_ZTV1B = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } { {{.*}} null, {{.*}} @_ZTI1B, {{.*}} @_ZN1B1fEv
+struct B {
+  // CHECK-DAG: define {{.*}} @_ZN1B1fEv
+  virtual constexpr void f() {}
+};
+B b;
+
+struct CBase {
+  virtual constexpr void f(); // not key function
+};
+
+// CHECK-DAG: @_ZTV1C = {{.*}} addrspace(1) constant {{.*}} null, {{.*}} @_ZTI1C, {{.*}} @_ZN1C1fEv
+struct C : CBase {
+  void f(); // key function
+};
+// CHECK-DAG: define {{.*}} @_ZN1C1fEv
+void C::f() {}
diff --git a/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..3805afe61b8a2
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s
+// PR5697
+namespace PR5697 {
+struct A {
+  virtual void f() { }
+  A();
+  A(int);
+};
+
+// A does not have a key function, so the first constructor we emit should
+// cause the vtable to be defined (without assertions.)
+// CHECK: @_ZTVN6PR56971AE = linkonce_odr unnamed_addr addrspace(1) constant
+A::A() { }
+A::A(int) { }
+}
+
+// Make sure that we don't assert when building the vtable for a class
+// template specialization or explicit instantiation with a key
+// function.
+template<typename T>
+struct Base {
+  virtual ~Base();
+};
+
+template<typename T>
+struct Derived : public Base<T> { };
+
+template<>
+struct Derived<char> : public Base<char> {
+  virtual void anchor();
+};
+
+void Derived<char>::anchor() { }
diff --git a/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..d639bfcf4d82a
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// A collection of big class hierarchies and their vtables.
+
+namespace Test1 {
+
+class C0
+{
+};
+class C1
+ :  virtual public C0
+{
+  int k0;
+};
+class C2
+ :  public C0
+ ,  virtual public C1
+{
+  int k0;
+};
+class C3
+ :  virtual public C0
+ ,  virtual public C1
+ ,  public C2
+{
+  int k0;
+  int k1;
+  int k2;
+  int k3;
+};
+class C4
+ :  public C2
+ ,  virtual public C3
+ ,  public C0
+{
+  int k0;
+};
+class C5
+ :  public C0
+ ,  virtual public C4
+ ,  public C2
+ ,  public C1
+ ,  virtual public C3
+{
+  int k0;
+};
+class C6
+ :  virtual public C3
+ ,  public C0
+ ,  public C5
+ ,  public C4
+ ,  public C1
+{
+  int k0;
+};
+class C7
+ :  virtual public C5
+ ,  virtual public C6
+ ,  virtual public C3
+ ,  public C4
+ ,  virtual public C2
+{
+  int k0;
+  int k1;
+};
+class C8
+ :  public C7
+ ,  public C5
+ ,  public C3
+ ,  virtual public C4
+ ,  public C1
+ ,  public C2
+{
+  int k0;
+  int k1;
+};
+
+// CHECK:     Vtable for 'Test1::C9' (87 entries).
+// CHECK-NEXT:   0 | vbase_offset (344)
+// CHECK-NEXT:   1 | vbase_offset (312)
+// CHECK-NEXT:   2 | vbase_offset (184)
+// CHECK-NEXT:   3 | vbase_offset (168)
+// CHECK-NEXT:   4 | vbase_offset (120)
+// CHECK-NEXT:   5 | vbase_offset (48)
+// CHECK-NEXT:   6 | vbase_offset (148)
+// CHECK-NEXT:   7 | vbase_offset (152)
+// CHECK-NEXT:   8 | offset_to_top (0)
+// CHECK-NEXT:   9 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 0) vtable address --
+// CHECK-NEXT:       -- (Test1::C9, 0) vtable address --
+// CHECK-NEXT:  10 | void Test1::C9::f()
+// CHECK-NEXT:  11 | vbase_offset (104)
+// CHECK-NEXT:  12 | vbase_offset (132)
+// CHECK-NEXT:  13 | vbase_offset (136)
+// CHECK-NEXT:  14 | offset_to_top (-16)
+// CHECK-NEXT:  15 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 16) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 16) vtable address --
+// CHECK-NEXT:  16 | vbase_offset (72)
+// CHECK-NEXT:  17 | vbase_offset (120)
+// CHECK-NEXT:  18 | vbase_offset (100)
+// CHECK-NEXT:  19 | vbase_offset (104)
+// CHECK-NEXT:  20 | offset_to_top (-48)
+// CHECK-NEXT:  21 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 48) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 48) vtable address --
+// CHECK-NEXT:       -- (Test1::C6, 48) vtable address --
+// CHECK-NEXT:  22 | vbase_offset (84)
+// CHECK-NEXT:  23 | offset_to_top (-64)
+// CHECK-NEXT:  24 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 64) vtable address --
+// CHECK-NEXT:  25 | vbase_offset (32)
+// CHECK-NEXT:  26 | vbase_offset (60)
+// CHECK-NEXT:  27 | vbase_offset (64)
+// CHECK-NEXT:  28 | offset_to_top (-88)
+// CHECK-NEXT:  29 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 88) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 88) vtable address --
+// CHECK-NEXT:  30 | vbase_offset (44)
+// CHECK-NEXT:  31 | offset_to_top (-104)
+// CHECK-NEXT:  32 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 104) vtable address --
+// CHECK-NEXT:  33 | vbase_offset (28)
+// CHECK-NEXT:  34 | vbase_offset (32)
+// CHECK-NEXT:  35 | offset_to_top (-120)
+// CHECK-NEXT:  36 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 120) vtable address --
+// CHECK-NEXT:       -- (Test1::C3, 120) vtable address --
+// CHECK-NEXT:  37 | vbase_offset (-4)
+// CHECK-NEXT:  38 | offset_to_top (-152)
+// CHECK-NEXT:  39 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 152) vtable address --
+// CHECK-NEXT:  40 | vbase_offset (-48)
+// CHECK-NEXT:  41 | vbase_offset (-20)
+// CHECK-NEXT:  42 | vbase_offset (-16)
+// CHECK-NEXT:  43 | offset_to_top (-168)
+// CHECK-NEXT:  44 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 168) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 168) vtable address --
+// CHECK-NEXT:  45 | vbase_offset (160)
+// CHECK-NEXT:  46 | vbase_offset (-136)
+// CHECK-NEXT:  47 | vbase_offset (-16)
+// CHECK-NEXT:  48 | vbase_offset (128)
+// CHECK-NEXT:  49 | vbase_offset (-64)
+// CHECK-NEXT:  50 | vbase_offset (-36)
+// CHECK-NEXT:  51 | vbase_offset (-32)
+// CHECK-NEXT:  52 | offset_to_top (-184)
+// CHECK-NEXT:  53 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C4, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C7, 184) vtable address --
+// CHECK-NEXT:       -- (Test1::C8, 184) vtable address --
+// CHECK-NEXT:  54 | vbase_offset (-88)
+// CHECK-NEXT:  55 | vbase_offset (-40)
+// CHECK-NEXT:  56 | vbase_offset (-60)
+// CHECK-NEXT:  57 | vbase_offset (-56)
+// CHECK-NEXT:  58 | offset_to_top (-208)
+// CHECK-NEXT:  59 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 208) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 208) vtable address --
+// CHECK-NEXT:  60 | vbase_offset (-76)
+// CHECK-NEXT:  61 | offset_to_top (-224)
+// CHECK-NEXT:  62 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 224) vtable address --
+// CHECK-NEXT:  63 | vbase_offset (-92)
+// CHECK-NEXT:  64 | vbase_offset (-88)
+// CHECK-NEXT:  65 | offset_to_top (-240)
+// CHECK-NEXT:  66 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 240) vtable address --
+// CHECK-NEXT:       -- (Test1::C3, 240) vtable address --
+// CHECK-NEXT:  67 | vbase_offset (-124)
+// CHECK-NEXT:  68 | offset_to_top (-272)
+// CHECK-NEXT:  69 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 272) vtable address --
+// CHECK-NEXT:  70 | vbase_offset (-140)
+// CHECK-NEXT:  71 | vbase_offset (-136)
+// CHECK-NEXT:  72 | offset_to_top (-288)
+// CHECK-NEXT:  73 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 288) vtable address --
+// CHECK-NEXT:  74 | vbase_offset (-192)
+// CHECK-NEXT:  75 | vbase_offset (-144)
+// CHECK-NEXT:  76 | vbase_offset (-164)
+// CHECK-NEXT:  77 | vbase_offset (-160)
+// CHECK-NEXT:  78 | offset_to_top (-312)
+// CHECK-NEXT:  79 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C2, 312) vtable address --
+// CHECK-NEXT:       -- (Test1::C5, 312) vtable address --
+// CHECK-NEXT:  80 | vbase_offset (-180)
+// CHECK-NEXT:  81 | offset_to_top (-328)
+// CHECK-NEXT:  82 | Test1::C9 RTTI
+// CHECK-NEXT:       -- (Test1::C1, 328) vtable address --
+// CHECK-NEXT:  83 | vbase_offset (-196)
+// CHECK-NEXT:  84 | vbase_offset (-192)
+// CHECK-NEXT:  85 | offset_to_top (-344)
+// CHECK-NEXT:  86 | Test1::C9 RTTI
+class C9
+ :  virtual public C6
+ ,  public C2
+ ,  public C4
+ ,  virtual public C8
+{
+  int k0;
+  int k1;
+  int k2;
+  int k3;
+  virtual void f();
+};
+void C9::f() { }
+
+}
diff --git a/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..38f6b6a352bb8
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++03 -o %t.03
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o %t.11
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -disable-llvm-passes -O3 -emit-llvm -o %t.opt
+// RUN: FileCheck %s < %t
+// RUN: FileCheck %s < %t.03
+// RUN: FileCheck %s < %t.11
+// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
+
+namespace {
+  struct A {
+    virtual void f() { }
+  };
+}
+
+void f() { A b; }
+
+struct B {
+  B();
+  virtual void f();
+};
+
+B::B() { }
+
+struct C : virtual B {
+  C();
+  virtual void f() { }
+};
+
+C::C() { }
+
+struct D {
+  virtual void f();
+};
+
+void D::f() { }
+
+static struct : D { } e;
+
+// Force 'e' to be constructed and therefore have a vtable defined.
+void use_e() {
+  e.f();
+}
+
+// The destructor is the key function.
+template<typename T>
+struct E {
+  virtual ~E();
+};
+
+template<typename T> E<T>::~E() { }
+
+// Anchor is the key function
+template<>
+struct E<char> {
+  virtual void anchor();
+};
+
+void E<char>::anchor() { }
+
+template struct E<short>;
+extern template struct E<int>;
+
+void use_E() {
+  E<int> ei;
+  (void)ei;
+  E<long> el;
+  (void)el;
+}
+
+// No key function
+template<typename T>
+struct F {
+  virtual void foo() { }
+};
+
+// No key function
+template<>
+struct F<char> {
+  virtual void foo() { }
+};
+
+template struct F<short>;
+extern template struct F<int>;
+
+void use_F() {
+  F<char> fc;
+  fc.foo();
+  F<int> fi;
+  fi.foo();
+  F<long> fl;
+  (void)fl;
+}
+
+// B has a key function that is not defined in this translation unit so its vtable
+// has external linkage.
+// CHECK-DAG: @_ZTV1B = external unnamed_addr addrspace(1) constant
+
+// C has no key function, so its vtable should have weak_odr linkage
+// and hidden visibility
+// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTS1C = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1C = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// D has a key function that is defined in this translation unit so its vtable is
+// defined in the translation unit.
+// CHECK-DAG: @_ZTV1D ={{.*}} unnamed_addr addrspace(1) constant
+// CHECK-DAG: @_ZTS1D ={{.*}} addrspace(1) constant
+// CHECK-DAG: @_ZTI1D ={{.*}} addrspace(1) constant
+
+// E<char> is an explicit specialization with a key function defined
+// in this translation unit, so its vtable should have external
+// linkage.
+// CHECK-DAG: @_ZTV1EIcE ={{.*}} unnamed_addr addrspace(1) constant
+// CHECK-DAG: @_ZTS1EIcE ={{.*}} addrspace(1) constant
+// CHECK-DAG: @_ZTI1EIcE ={{.*}} addrspace(1) constant
+
+// E<short> is an explicit template instantiation with a key function
+// defined in this translation unit, so its vtable should have
+// weak_odr linkage.
+// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// F<short> is an explicit template instantiation without a key
+// function, so its vtable should have weak_odr linkage
+// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// E<long> is an implicit template instantiation with a key function
+// defined in this translation unit, so its vtable should have
+// linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// F<long> is an implicit template instantiation with no key function,
+// so its vtable should have linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// F<int> is an explicit template instantiation declaration without a
+// key function, so its vtable should have external linkage.
+// CHECK-DAG: @_ZTV1FIiE = external unnamed_addr addrspace(1) constant
+// CHECK-OPT-DAG: @_ZTV1FIiE = available_externally unnamed_addr addrspace(1) constant
+
+// E<int> is an explicit template instantiation declaration. It has a
+// key function is not instantiated, so we know that vtable definition
+// will be generated in TU where key function will be defined
+// so we can mark it as external (without optimizations) and
+// available_externally (with optimizations) because all of the inline
+// virtual functions have been emitted.
+// CHECK-DAG: @_ZTV1EIiE = external unnamed_addr addrspace(1) constant
+// CHECK-OPT-DAG: @_ZTV1EIiE = available_externally unnamed_addr addrspace(1) constant
+
+// The anonymous struct for e has no linkage, so the vtable should have
+// internal linkage.
+// CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr addrspace(1) constant
+// CHECK-DAG: @"_ZTS3$_0" = internal addrspace(1) constant
+// CHECK-DAG: @"_ZTI3$_0" = internal addrspace(1) constant
+
+// The A vtable should have internal linkage since it is inside an anonymous
+// namespace.
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr addrspace(1) constant
+// CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal addrspace(1) constant
+// CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal addrspace(1) constant
+
+// F<char> is an explicit specialization without a key function, so
+// its vtable should have linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIcE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIcE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
+
+// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+template <typename T>
+class G {
+public:
+  G() {}
+  virtual void f0();
+  virtual void f1();
+};
+template <>
+void G<int>::f1() {}
+template <typename T>
+void G<T>::f0() {}
+void G_f0()  { new G<int>(); }
+
+// H<int> has a key function without a body but it's a template instantiation
+// so its VTable must be emitted.
+// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
+template <typename T>
+class H {
+public:
+  virtual ~H();
+};
+
+void use_H() {
+  H<int> h;
+}
+
+// I<int> has an explicit instantiation declaration and needs a VTT and
+// construction vtables.
+
+// CHECK-DAG: @_ZTV1IIiE = external unnamed_addr addrspace(1) constant
+// CHECK-DAG: @_ZTT1IIiE = external unnamed_addr addrspace(1) constant
+// CHECK-NOT: @_ZTC1IIiE
+//
+// CHECK-OPT-DAG: @_ZTV1IIiE = available_externally unnamed_addr addrspace(1) constant
+// CHECK-OPT-DAG: @_ZTT1IIiE = available_externally unnamed_addr addrspace(1) constant
+struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {};
+template<typename T>
+struct I : VBase2 {};
+extern template struct I<int>;
+I<int> i;
diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..efb4afb38f5e8
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
+
+struct Field {
+  Field();
+  ~Field();
+};
+
+struct Base {
+  Base();
+  ~Base();
+};
+
+struct A : Base {
+  A();
+  ~A();
+
+  virtual void f();
+
+  Field field;
+};
+
+// CHECK-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: call{{.*}} void @_ZN4BaseC2Ev(
+// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
+// CHECK: call{{.*}} void @_ZN5FieldC1Ev(
+// CHECK: ret void
+A::A() { }
+
+// CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
+// CHECK: call{{.*}} void @_ZN5FieldD1Ev(
+// CHECK: call{{.*}} void @_ZN4BaseD2Ev(
+// CHECK: ret void
+A::~A() { }
+
+struct B : Base {
+  virtual void f();
+
+  Field field;
+};
+
+void f() { B b; }
+
+// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BC1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: call{{.*}} void @_ZN1BC2Ev(
+
+// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BD1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: call{{.*}} void @_ZN1BD2Ev(
+
+// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: call{{.*}} void @_ZN4BaseC2Ev(
+// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
+// CHECK: call{{.*}} void @_ZN5FieldC1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
+// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
+// CHECK: call{{.*}} void @_ZN5FieldD1Ev(
+// CHECK: call{{.*}} void @_ZN4BaseD2Ev(
+// CHECK: ret void
diff --git a/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..52c6249af9f51
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
+
+// Test1::B should just have a single entry in its VTT, which points to the vtable.
+namespace Test1 {
+struct A { };
+
+struct B : virtual A {
+  virtual void f();
+};
+
+void B::f() { }
+}
+
+// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
+namespace Test2 {
+  struct A { };
+
+  struct B : A { virtual void f(); };
+  struct C : virtual B { };
+
+  C c;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2.
+namespace Test3 {
+  class A1 { int i; };
+  class A2 { int i; virtual void f(); };
+  class V1 : public A1, public A2 { int i; };
+  class B1 { int i; };
+  class B2 { int i; };
+  class V2 : public B1, public B2, public virtual V1 { int i; };
+  class V3 {virtual void g(); };
+  class C1 : public virtual V1 { int i; };
+  class C2 : public virtual V3, virtual V2 { int i; };
+  class X1 { int i; };
+  class C3 : public X1 { int i; };
+  class D : public C1, public C2, public C3 { int i;  };
+
+  D d;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2, with the change suggested
+// (making A2 a virtual base of V1)
+namespace Test4 {
+  class A1 { int i; };
+  class A2 { int i; virtual void f(); };
+  class V1 : public A1, public virtual A2 { int i; };
+  class B1 { int i; };
+  class B2 { int i; };
+  class V2 : public B1, public B2, public virtual V1 { int i; };
+  class V3 {virtual void g(); };
+  class C1 : public virtual V1 { int i; };
+  class C2 : public virtual V3, virtual V2 { int i; };
+  class X1 { int i; };
+  class C3 : public X1 { int i; };
+  class D : public C1, public C2, public C3 { int i;  };
+
+  D d;
+}
+
+namespace Test5 {
+  struct A {
+    virtual void f() = 0;
+    virtual void anchor();
+  };
+
+  void A::anchor() {
+  }
+}
+
+namespace Test6 {
+  struct A {
+    virtual void f() = delete;
+    virtual void anchor();
+  };
+
+  void A::anchor() {
+  }
+}
+
+// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr addrspace(1) constant [1 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test11BE, i32 0, i32 0, i32 3)]
+// CHECK: @_ZTVN5Test51AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test51AE, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test51A6anchorEv to ptr addrspace(1))] }
+// CHECK: @_ZTVN5Test61AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test61AE, ptr addrspace(1) addrspacecast (ptr @__cxa_deleted_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test61A6anchorEv to ptr addrspace(1))] }
+// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr addrspace(1) constant [2 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4)]
+// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 1, i32 3)]
+// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant { [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [6 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 72 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test41DE], [8 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 24 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42V31gEv to ptr addrspace(1))], [3 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -40 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE], [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -56 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42A21fEv to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -32 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -72 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE] }
+// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant [19 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-48, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 1, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 4, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 2, i32 3)]
+// CHECK: declare{{.*}} void @__cxa_pure_virtual() unnamed_addr
+// CHECK: declare{{.*}} void @__cxa_deleted_virtual() unnamed_addr
diff --git a/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp
new file mode 100644
index 0000000000000..c7f388959201f
--- /dev/null
+++ b/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
+
+// This is the sample from the C++ Itanium ABI, p2.6.2.
+namespace Test {
+  class A1 { int i; };
+  class A2 { int i; virtual void f(); };
+  class V1 : public A1, public A2 { int i; };
+  class B1 { int i; };
+  class B2 { int i; };
+  class V2 : public B1, public B2, public virtual V1 { int i; };
+  class V3 { virtual void g(); };
+  class C1 : public virtual V1 { int i; };
+  class C2 : public virtual V3, virtual V2 { int i; };
+  class X1 { int i; };
+  class C3 : public X1 { int i; };
+  class D : public C1, public C2, public C3 { int i;  };
+
+  D d;
+}
+
+// CHECK: linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 1, i32 3)], comdat, align 8
+// CHECK: call {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %2, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 11))
+// CHECK: call {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this1, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 1))
+// CHECK: call {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %3, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 3))
+// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %this, ptr addrspace(1) noundef %vtt)
+// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
+// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)

>From 453e96aafd02bd19f44c0383acb74b930d2767c9 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 9 Apr 2024 19:25:02 +0100
Subject: [PATCH 04/15] Simplify generic pointer type retrieval.

---
 clang/lib/CodeGen/CodeGenModule.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 01763308e6c17..158dca114679c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -366,8 +366,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
   IntPtrTy = llvm::IntegerType::get(LLVMContext,
     C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(
-      LLVMContext, C.getTargetInfo().getTargetAddressSpace(LangAS::Default));
+  Int8PtrTy = llvm::PointerType::get(LLVMContext,
+                                     C.getTargetAddressSpace(LangAS::Default));
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
       llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());

>From 6c096210bebe999392b2c3432ad8c8bc5b6288e9 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 9 Apr 2024 20:50:39 +0100
Subject: [PATCH 05/15] Fix formatting.

---
 clang/lib/CodeGen/CodeGenModule.cpp | 24 ++++++++++++------------
 clang/lib/CodeGen/ItaniumCXXABI.cpp | 11 +++++------
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 158dca114679c..faa1058f8ec23 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3582,10 +3582,11 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
       isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage())
           ? llvm::GlobalValue::LinkOnceODRLinkage
           : llvm::GlobalValue::InternalLinkage;
-  auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
-                                      /*isConstant=*/true, Linkage, Init, Name,
-                                      nullptr, llvm::GlobalValue::NotThreadLocal,
-                                      GlobalsInt8PtrTy->getAddressSpace());
+  auto *GV = new llvm::GlobalVariable(
+      getModule(), Init->getType(),
+      /*isConstant=*/true, Linkage, Init, Name, nullptr,
+      llvm::GlobalValue::NotThreadLocal,
+      GlobalsInt8PtrTy->getAddressSpace());
   setGVProperties(GV, TPO);
   if (supportsCOMDAT())
     GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
@@ -4552,10 +4553,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
     IsIncompleteFunction = true;
   }
 
-  llvm::Function *F = llvm::Function::Create(
-      FTy, llvm::Function::ExternalLinkage,
-      getDataLayout().getProgramAddressSpace(),
-      Entry ? StringRef() : MangledName, &getModule());
+  llvm::Function *F =
+      llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
+                             getDataLayout().getProgramAddressSpace(),
+                             Entry ? StringRef() : MangledName, &getModule());
 
   // Store the declaration associated with this function so it is potentially
   // updated by further declarations or definitions and emitted at the end.
@@ -5025,10 +5026,9 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
   }
 
   // Create a new variable.
-  GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
-                                Linkage, nullptr, Name, nullptr,
-                                llvm::GlobalValue::NotThreadLocal,
-                                GlobalsInt8PtrTy->getAddressSpace());
+  GV = new llvm::GlobalVariable(
+    getModule(), Ty, /*isConstant=*/true, Linkage, nullptr, Name, nullptr,
+    llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
 
   if (OldGV) {
     // Replace occurrences of the old variable if needed.
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 942ab4c3a43d0..823244a411531 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3680,12 +3680,11 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
       llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);
       // FIXME: External StdLib VTables should be constant as well, but changing
       //        it *might* constitute a very subtle ABI break.
-      VTable = new llvm::GlobalVariable(CGM.getModule(), Ty,
-                                        /*isConstant=*/false,
-                                        llvm::GlobalVariable::ExternalLinkage,
-                                        nullptr, VTableName, nullptr,
-                                        llvm::GlobalValue::NotThreadLocal,
-                                        CGM.GlobalsInt8PtrTy->getAddressSpace());
+      VTable = new llvm::GlobalVariable(
+        CGM.getModule(), Ty,
+        /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage, nullptr,
+        VTableName, nullptr, llvm::GlobalValue::NotThreadLocal,
+        CGM.GlobalsInt8PtrTy->getAddressSpace());
     }
   }
 

>From 2549f5ac5a29933c76ea5eb868f1d3f0612280a0 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 9 Apr 2024 21:03:35 +0100
Subject: [PATCH 06/15] (Actually) Fix formatting.

---
 clang/lib/CodeGen/CodeGenModule.cpp | 7 +++----
 clang/lib/CodeGen/ItaniumCXXABI.cpp | 8 ++++----
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index faa1058f8ec23..8ed88b34b4a00 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3585,8 +3585,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
   auto *GV = new llvm::GlobalVariable(
       getModule(), Init->getType(),
       /*isConstant=*/true, Linkage, Init, Name, nullptr,
-      llvm::GlobalValue::NotThreadLocal,
-      GlobalsInt8PtrTy->getAddressSpace());
+      llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
   setGVProperties(GV, TPO);
   if (supportsCOMDAT())
     GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
@@ -5027,8 +5026,8 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
 
   // Create a new variable.
   GV = new llvm::GlobalVariable(
-    getModule(), Ty, /*isConstant=*/true, Linkage, nullptr, Name, nullptr,
-    llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
+      getModule(), Ty, /*isConstant=*/true, Linkage, nullptr, Name, nullptr,
+      llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
 
   if (OldGV) {
     // Replace occurrences of the old variable if needed.
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 823244a411531..5e42e94bf3175 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3681,10 +3681,10 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
       // FIXME: External StdLib VTables should be constant as well, but changing
       //        it *might* constitute a very subtle ABI break.
       VTable = new llvm::GlobalVariable(
-        CGM.getModule(), Ty,
-        /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage, nullptr,
-        VTableName, nullptr, llvm::GlobalValue::NotThreadLocal,
-        CGM.GlobalsInt8PtrTy->getAddressSpace());
+          CGM.getModule(), Ty,
+          /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage, nullptr,
+          VTableName, nullptr, llvm::GlobalValue::NotThreadLocal,
+          CGM.GlobalsInt8PtrTy->getAddressSpace());
     }
   }
 

>From 0b3dac3be59d0c9a65e04e5a6ba53a706d8f8695 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Wed, 10 Apr 2024 00:25:13 +0100
Subject: [PATCH 07/15] Delete unnecessary leftover diff.

---
 clang/lib/CodeGen/CodeGenModule.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ed88b34b4a00..3c5acfffabfea 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4554,7 +4554,6 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
 
   llvm::Function *F =
       llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
-                             getDataLayout().getProgramAddressSpace(),
                              Entry ? StringRef() : MangledName, &getModule());
 
   // Store the declaration associated with this function so it is potentially

>From c18febe32478aaf4d5602ab6f0a41554ae8a6ab2 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 16 Apr 2024 14:21:49 +0100
Subject: [PATCH 08/15] Roll-back Global generation to use defaults now that
 #88455 went in.

---
 clang/lib/CodeGen/CodeGenModule.cpp | 17 +++++++----------
 clang/lib/CodeGen/ItaniumCXXABI.cpp | 21 ++++-----------------
 2 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 070ad5d374168..0307099344c0d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -371,8 +371,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
       llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
-  GlobalsInt8PtrTy = llvm::PointerType::get(
-      LLVMContext, C.getTargetAddressSpace(GetGlobalVarAddressSpace(nullptr)));
+  GlobalsInt8PtrTy =
+      llvm::PointerType::get(LLVMContext, DL.getDefaultGlobalsAddressSpace());
   ConstGlobalsPtrTy = llvm::PointerType::get(
       LLVMContext, C.getTargetAddressSpace(GetGlobalConstantAddressSpace()));
   ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace();
@@ -3590,10 +3590,8 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
       isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage())
           ? llvm::GlobalValue::LinkOnceODRLinkage
           : llvm::GlobalValue::InternalLinkage;
-  auto *GV = new llvm::GlobalVariable(
-      getModule(), Init->getType(),
-      /*isConstant=*/true, Linkage, Init, Name, nullptr,
-      llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
+  auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
+                                      /*isConstant=*/true, Linkage, Init, Name);
   setGVProperties(GV, TPO);
   if (supportsCOMDAT())
     GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
@@ -5044,9 +5042,8 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
   }
 
   // Create a new variable.
-  GV = new llvm::GlobalVariable(
-      getModule(), Ty, /*isConstant=*/true, Linkage, nullptr, Name, nullptr,
-      llvm::GlobalValue::NotThreadLocal, GlobalsInt8PtrTy->getAddressSpace());
+  GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
+                                Linkage, nullptr, Name);
 
   if (OldGV) {
     // Replace occurrences of the old variable if needed.
@@ -5161,7 +5158,7 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
     return LangAS::cuda_device;
   }
 
-  if (LangOpts.OpenMP && OpenMPRuntime) {
+  if (LangOpts.OpenMP) {
     LangAS AS;
     if (OpenMPRuntime->hasAllocateAttributeForGlobalVar(D, AS))
       return AS;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 5e42e94bf3175..18acf7784f714 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3279,9 +3279,7 @@ ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
 
     GV = new llvm::GlobalVariable(
         CGM.getModule(), CGM.GlobalsInt8PtrTy,
-        /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr, Name,
-        nullptr, llvm::GlobalValue::NotThreadLocal,
-        CGM.GlobalsInt8PtrTy->getAddressSpace());
+        /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr, Name);
     const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
     CGM.setGVProperties(GV, RD);
     // Import the typeinfo symbol when all non-inline virtual methods are
@@ -3675,17 +3673,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
   if (CGM.getItaniumVTableContext().isRelativeLayout())
     VTable = CGM.getModule().getNamedAlias(VTableName);
   if (!VTable) {
-    VTable = CGM.GetGlobalValue(VTableName);
-    if (!VTable) {
-      llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);
-      // FIXME: External StdLib VTables should be constant as well, but changing
-      //        it *might* constitute a very subtle ABI break.
-      VTable = new llvm::GlobalVariable(
-          CGM.getModule(), Ty,
-          /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage, nullptr,
-          VTableName, nullptr, llvm::GlobalValue::NotThreadLocal,
-          CGM.GlobalsInt8PtrTy->getAddressSpace());
-    }
+    llvm::Type *Ty = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, 0);
+    VTable = CGM.getModule().getOrInsertGlobal(VTableName, Ty);
   }
 
   CGM.setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
@@ -3945,9 +3934,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
   llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
   llvm::GlobalVariable *GV =
       new llvm::GlobalVariable(M, Init->getType(),
-                               /*isConstant=*/true, Linkage, Init, Name,
-                               nullptr, llvm::GlobalValue::NotThreadLocal,
-                               CGM.GlobalsInt8PtrTy->getAddressSpace());
+                               /*isConstant=*/true, Linkage, Init, Name);
 
   // Export the typeinfo in the same circumstances as the vtable is exported.
   auto GVDLLStorageClass = DLLStorageClass;

>From df94ae049613a044384489db47960e02acd4da12 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Wed, 24 Apr 2024 00:59:49 +0100
Subject: [PATCH 09/15] Add comment trying to explain why `typeid` cannot (for
 now) return a pointer to a `type_info` value in the global AS.

---
 clang/lib/CodeGen/CGExprCXX.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index eb41ba5552ad2..b51e41cb5c7aa 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2216,6 +2216,11 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
+  // TODO: ideally, we would like to use GlobalsInt8PtrTy here, however, we
+  //       cannot, primarily because the result of applying typeid is a value of
+  //       type type_info, which is declared & defined by the standard library
+  //       implementation and expects to operate on the generic (default) AS.
+  //       https://reviews.llvm.org/D157452 has more context.
   llvm::Type *PtrTy = Int8PtrTy;
   LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
 

>From 7aeba2820b7c4c41d01a3c139a7718ed55e16c38 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Wed, 24 Apr 2024 18:12:42 +0100
Subject: [PATCH 10/15] Compact tests.

---
 .../CodeGenCXX/dynamic-cast-address-space.cpp | 123 ++++++++++++++++--
 ...mic-cast-nonzero-default-address-space.cpp |  24 ----
 .../template-param-objects-address-space.cpp  |  10 ++
 ...-objects-nonzero-default-address-space.cpp |  32 -----
 4 files changed, 123 insertions(+), 66 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp

diff --git a/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp b/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
index 83a408984b760..3d5e32516c7af 100644
--- a/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
+++ b/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
@@ -1,24 +1,127 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --no-generate-body-for-unused-prefixes --version 4
 // RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
+
 struct A { virtual void f(); };
 struct B : A { };
 
-// CHECK: {{define.*@_Z1fP1A}}
-// CHECK-SAME:  personality ptr @__gxx_personality_v0
 B fail;
+//.
+// CHECK: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
+// CHECK: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
+// CHECK: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
+// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
+// CHECK: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
+// CHECK: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
+// CHECK: @__oclc_ABI_version = weak_odr hidden local_unnamed_addr addrspace(4) constant i32 500
+//.
+// WITH-NONZERO-DEFAULT-AS: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
+// WITH-NONZERO-DEFAULT-AS: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
+// WITH-NONZERO-DEFAULT-AS: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
+// WITH-NONZERO-DEFAULT-AS: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
+// WITH-NONZERO-DEFAULT-AS: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
+//.
+// CHECK-LABEL: define dso_local noundef nonnull align 8 dereferenceable(8) ptr @_Z1fP1A(
+// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RETVAL:%.*]] = alloca ptr, align 8, addrspace(5)
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8, addrspace(5)
+// CHECK-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr, align 8, addrspace(5)
+// CHECK-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4, addrspace(5)
+// CHECK-NEXT:    [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
+// CHECK-NEXT:    [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[A_ADDR]] to ptr
+// CHECK-NEXT:    store ptr [[A]], ptr [[A_ADDR_ASCAST]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[A_ADDR_ASCAST]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = call ptr @__dynamic_cast(ptr [[TMP0]], ptr addrspace(1) @_ZTI1A, ptr addrspace(1) @_ZTI1B, i64 0) #[[ATTR3:[0-9]+]]
+// CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
+// CHECK-NEXT:    br i1 [[TMP2]], label [[DYNAMIC_CAST_BAD_CAST:%.*]], label [[DYNAMIC_CAST_END:%.*]]
+// CHECK:       dynamic_cast.bad_cast:
+// CHECK-NEXT:    invoke void @__cxa_bad_cast() #[[ATTR4:[0-9]+]]
+// CHECK-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// CHECK:       invoke.cont:
+// CHECK-NEXT:    unreachable
+// CHECK:       dynamic_cast.end:
+// CHECK-NEXT:    br label [[TRY_CONT:%.*]]
+// CHECK:       lpad:
+// CHECK-NEXT:    [[TMP3:%.*]] = landingpad { ptr, i32 }
+// CHECK-NEXT:            catch ptr null
+// CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0
+// CHECK-NEXT:    store ptr [[TMP4]], ptr addrspace(5) [[EXN_SLOT]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1
+// CHECK-NEXT:    store i32 [[TMP5]], ptr addrspace(5) [[EHSELECTOR_SLOT]], align 4
+// CHECK-NEXT:    br label [[CATCH:%.*]]
+// CHECK:       catch:
+// CHECK-NEXT:    [[EXN:%.*]] = load ptr, ptr addrspace(5) [[EXN_SLOT]], align 8
+// CHECK-NEXT:    [[TMP6:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]]
+// CHECK-NEXT:    call void @__cxa_end_catch()
+// CHECK-NEXT:    br label [[TRY_CONT]]
+// CHECK:       try.cont:
+// CHECK-NEXT:    ret ptr addrspacecast (ptr addrspace(1) @fail to ptr)
+//
+// WITH-NONZERO-DEFAULT-AS-LABEL: define spir_func noundef align 8 dereferenceable(8) ptr addrspace(4) @_Z1fP1A(
+// WITH-NONZERO-DEFAULT-AS-SAME: ptr addrspace(4) noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
+// WITH-NONZERO-DEFAULT-AS-NEXT:  entry:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[RETVAL:%.*]] = alloca ptr addrspace(4), align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[A_ADDR:%.*]] = alloca ptr addrspace(4), align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[EXN_SLOT:%.*]] = alloca ptr addrspace(4), align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[RETVAL_ASCAST:%.*]] = addrspacecast ptr [[RETVAL]] to ptr addrspace(4)
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr [[A_ADDR]] to ptr addrspace(4)
+// WITH-NONZERO-DEFAULT-AS-NEXT:    store ptr addrspace(4) [[A]], ptr addrspace(4) [[A_ADDR_ASCAST]], align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[A_ADDR_ASCAST]], align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP1:%.*]] = call spir_func ptr addrspace(4) @__dynamic_cast(ptr addrspace(4) [[TMP0]], ptr addrspace(1) @_ZTI1A, ptr addrspace(1) @_ZTI1B, i64 0) #[[ATTR3:[0-9]+]]
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP2:%.*]] = icmp eq ptr addrspace(4) [[TMP1]], null
+// WITH-NONZERO-DEFAULT-AS-NEXT:    br i1 [[TMP2]], label [[DYNAMIC_CAST_BAD_CAST:%.*]], label [[DYNAMIC_CAST_END:%.*]]
+// WITH-NONZERO-DEFAULT-AS:       dynamic_cast.bad_cast:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    invoke spir_func void @__cxa_bad_cast() #[[ATTR4:[0-9]+]]
+// WITH-NONZERO-DEFAULT-AS-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
+// WITH-NONZERO-DEFAULT-AS:       invoke.cont:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    unreachable
+// WITH-NONZERO-DEFAULT-AS:       dynamic_cast.end:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    br label [[TRY_CONT:%.*]]
+// WITH-NONZERO-DEFAULT-AS:       lpad:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP3:%.*]] = landingpad { ptr addrspace(4), i32 }
+// WITH-NONZERO-DEFAULT-AS-NEXT:            catch ptr addrspace(4) null
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP4:%.*]] = extractvalue { ptr addrspace(4), i32 } [[TMP3]], 0
+// WITH-NONZERO-DEFAULT-AS-NEXT:    store ptr addrspace(4) [[TMP4]], ptr [[EXN_SLOT]], align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP5:%.*]] = extractvalue { ptr addrspace(4), i32 } [[TMP3]], 1
+// WITH-NONZERO-DEFAULT-AS-NEXT:    store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4
+// WITH-NONZERO-DEFAULT-AS-NEXT:    br label [[CATCH:%.*]]
+// WITH-NONZERO-DEFAULT-AS:       catch:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[EXN:%.*]] = load ptr addrspace(4), ptr [[EXN_SLOT]], align 8
+// WITH-NONZERO-DEFAULT-AS-NEXT:    [[TMP6:%.*]] = call spir_func ptr addrspace(4) @__cxa_begin_catch(ptr addrspace(4) [[EXN]]) #[[ATTR3]]
+// WITH-NONZERO-DEFAULT-AS-NEXT:    call spir_func void @__cxa_end_catch()
+// WITH-NONZERO-DEFAULT-AS-NEXT:    br label [[TRY_CONT]]
+// WITH-NONZERO-DEFAULT-AS:       try.cont:
+// WITH-NONZERO-DEFAULT-AS-NEXT:    ret ptr addrspace(4) addrspacecast (ptr addrspace(1) @fail to ptr addrspace(4))
+//
 const B& f(A *a) {
   try {
-    // CHECK: call ptr @__dynamic_cast
-    // CHECK: br i1
-    // CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]]
     dynamic_cast<const B&>(*a);
   } catch (...) {
-    // CHECK:      landingpad { ptr, i32 }
-    // CHECK-NEXT:   catch ptr null
   }
   return fail;
 }
 
-// CHECK: declare ptr @__dynamic_cast(ptr, ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]
 
-// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
-// CHECK: attributes [[NR]] = { noreturn }
+//.
+// CHECK: attributes #[[ATTR0]] = { mustprogress noinline optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+// CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn memory(read) }
+// CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+// CHECK: attributes #[[ATTR3]] = { nounwind }
+// CHECK: attributes #[[ATTR4]] = { noreturn }
+//.
+// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR0]] = { convergent mustprogress noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn memory(read) }
+// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR2:[0-9]+]] = { convergent nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR3]] = { nounwind }
+// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR4]] = { noreturn }
+//.
+// CHECK: [[META0:![0-9]+]] = !{i32 1, !"amdhsa_code_object_version", i32 500}
+// CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// CHECK: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+//.
+// WITH-NONZERO-DEFAULT-AS: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// WITH-NONZERO-DEFAULT-AS: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+//.
diff --git a/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
deleted file mode 100644
index 9a9fbdbd14582..0000000000000
--- a/clang/test/CodeGenCXX/dynamic-cast-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
-struct A { virtual void f(); };
-struct B : A { };
-
-// CHECK: {{define.*@_Z1fP1A}}
-// CHECK-SAME:  personality ptr @__gxx_personality_v0
-B fail;
-const B& f(A *a) {
-  try {
-    // CHECK: call {{.*}} ptr addrspace(4) @__dynamic_cast
-    // CHECK: br i1
-    // CHECK: invoke {{.*}} void @__cxa_bad_cast() [[NR:#[0-9]+]]
-    dynamic_cast<const B&>(*a);
-  } catch (...) {
-    // CHECK:      landingpad { ptr addrspace(4), i32 }
-    // CHECK-NEXT:   catch ptr addrspace(4) null
-  }
-  return fail;
-}
-
-// CHECK: declare {{.*}} ptr addrspace(4) @__dynamic_cast(ptr addrspace(4), ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]
-
-// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
-// CHECK: attributes [[NR]] = { noreturn }
diff --git a/clang/test/CodeGenCXX/template-param-objects-address-space.cpp b/clang/test/CodeGenCXX/template-param-objects-address-space.cpp
index b54dcfe77934e..b3733decdb550 100644
--- a/clang/test/CodeGenCXX/template-param-objects-address-space.cpp
+++ b/clang/test/CodeGenCXX/template-param-objects-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -std=c++20 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -std=c++20 %s -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 
 struct S { char buf[32]; };
 template<S s> constexpr const char *begin() { return s.buf; }
@@ -8,25 +9,34 @@ extern const void *callee(const S*);
 template<S s> constexpr const void* observable_addr() { return callee(&s); }
 
 // CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
+// WITH-NONZERO-DEFAULT-AS: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
 // CHECK-SAME: = linkonce_odr addrspace(1) constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat
 
 // CHECK: @p
 // CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
+// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
 const char *p = begin<S{"hello world"}>();
 
 // CHECK: @q
 // CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr)
+// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr addrspace(4))
 const char *q = end<S{"hello world"}>();
 
 const void *(*r)() = &retval<S{"hello world"}>;
 
 // CHECK: @s
 // CHECK-SAME: addrspace(1) global ptr null
+// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) null
 const void *s = observable_addr<S{"hello world"}>();
 
 // CHECK: define linkonce_odr noundef ptr @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
+// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
 // CHECK: ret ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
+// WITH-NONZERO-DEFAULT-AS: ret ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
 
 // CHECK: define linkonce_odr noundef ptr @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
+// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
 // CHECK: %call = call noundef ptr @_Z6calleePK1S(ptr noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr))
+// WITH-NONZERO-DEFAULT-AS: %call = call {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4)))
 // CHECK: declare noundef ptr @_Z6calleePK1S(ptr noundef)
+// WITH-NONZERO-DEFAULT-AS: declare {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef)
diff --git a/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp
deleted file mode 100644
index 9fc95acaebc7b..0000000000000
--- a/clang/test/CodeGenCXX/template-param-objects-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -std=c++20 %s -emit-llvm -o - | FileCheck %s
-
-struct S { char buf[32]; };
-template<S s> constexpr const char *begin() { return s.buf; }
-template<S s> constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); }
-template<S s> constexpr const void *retval() { return &s; }
-extern const void *callee(const S*);
-template<S s> constexpr const void* observable_addr() { return callee(&s); }
-
-// CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
-// CHECK-SAME: = linkonce_odr addrspace(1) constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat
-
-// CHECK: @p
-// CHECK-SAME: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
-const char *p = begin<S{"hello world"}>();
-
-// CHECK: @q
-// CHECK-SAME: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr addrspace(4))
-const char *q = end<S{"hello world"}>();
-
-const void *(*r)() = &retval<S{"hello world"}>;
-
-// CHECK: @s
-// CHECK-SAME: addrspace(1) global ptr addrspace(4) null
-const void *s = observable_addr<S{"hello world"}>();
-
-// CHECK: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
-// CHECK: ret ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
-
-// CHECK: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
-// CHECK: %call = call {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4)))
-// CHECK: declare {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef)

>From 65adbb6503a1104d480154bbc94ed48e3c388436 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Thu, 25 Apr 2024 01:15:11 +0100
Subject: [PATCH 11/15] Compact more tests, remove redundant ones.

---
 ...w-expression-typeinfo-in-address-space.cpp |   2 +
 ...einfo-in-nonzero-default-address-space.cpp |  17 --
 .../try-catch-with-address-space.cpp          |   7 +-
 ...tch-with-nonzero-default-address-space.cpp |  25 --
 .../typeid-cxx11-with-address-space.cpp       |   4 +
 ...x11-with-nonzero-default-address-space.cpp |  32 ---
 .../CodeGenCXX/typeid-with-address-space.cpp  |  11 +
 ...eid-with-nonzero-default-address-space.cpp |  50 ----
 .../typeinfo-with-address-space.cpp           |   7 +
 ...nfo-with-nonzero-default-address-space.cpp |  48 ----
 ...le-align-nonzero-default-address-space.cpp |  13 --
 ...onsteval-nonzero-default-address-space.cpp |  44 ----
 ...onstexpr-nonzero-default-address-space.cpp |  27 ---
 ...function-nonzero-default-address-space.cpp |  33 ---
 ...-extreme-nonzero-default-address-space.cpp | 210 -----------------
 ...-linkage-nonzero-default-address-space.cpp | 217 ------------------
 ...e-pointer-initialization-address-space.cpp |   7 +
 ...lization-nonzero-default-address-space.cpp |  60 -----
 clang/test/CodeGenCXX/vtt-address-space.cpp   |   7 +
 ...out-with-nonzero-default-address-space.cpp |  89 -------
 .../vtt-nonzero-default-address-space.cpp     |  27 ---
 21 files changed, 43 insertions(+), 894 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
 delete mode 100644 clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp

diff --git a/clang/test/CodeGenCXX/throw-expression-typeinfo-in-address-space.cpp b/clang/test/CodeGenCXX/throw-expression-typeinfo-in-address-space.cpp
index d8c23d427e67a..3acbdd8fd97ee 100644
--- a/clang/test/CodeGenCXX/throw-expression-typeinfo-in-address-space.cpp
+++ b/clang/test/CodeGenCXX/throw-expression-typeinfo-in-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 
 struct X {
   ~X();
@@ -15,3 +16,4 @@ void f() {
 }
 
 // CHECK: declare void @__cxa_throw(ptr, ptr addrspace(1), ptr)
+// WITH-NONZERO-DEFAULT-AS: declare{{.*}} void @__cxa_throw(ptr addrspace(4), ptr addrspace(1), ptr addrspace(4))
diff --git a/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
deleted file mode 100644
index b7fcde23efe6d..0000000000000
--- a/clang/test/CodeGenCXX/throw-expression-typeinfo-in-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
-
-struct X {
-  ~X();
-};
-
-struct Error {
-  Error(const X&) noexcept;
-};
-
-void f() {
-  try {
-    throw Error(X());
-  } catch (...) { }
-}
-
-// CHECK: declare{{.*}} void @__cxa_throw(ptr addrspace(4), ptr addrspace(1), ptr addrspace(4))
diff --git a/clang/test/CodeGenCXX/try-catch-with-address-space.cpp b/clang/test/CodeGenCXX/try-catch-with-address-space.cpp
index 279d29f50fd41..412ac6c287258 100644
--- a/clang/test/CodeGenCXX/try-catch-with-address-space.cpp
+++ b/clang/test/CodeGenCXX/try-catch-with-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 
 struct X { };
 
@@ -10,7 +11,8 @@ void f() {
     // CHECK: ptr addrspace(1) @_ZTI1X
   } catch (const X x) {
     // CHECK: catch ptr addrspace(1) @_ZTI1X
-    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
+    // CHECK: call i32 @llvm.eh.typeid.for.p0(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
+    // WITH-NONZERO-DEFAULT-AS: call i32 @llvm.eh.typeid.for.p4(ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTI1X to ptr addrspace(4)))
   }
 }
 
@@ -20,6 +22,7 @@ void h() {
     // CHECK: ptr addrspace(1) @_ZTIPKc
   } catch (char const(&)[4]) {
     // CHECK: catch ptr addrspace(1) @_ZTIA4_c
-    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
+    // CHECK: call i32 @llvm.eh.typeid.for.p0(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
+    // WITH-NONZERO-DEFAULT-AS: call i32 @llvm.eh.typeid.for.p4(ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr addrspace(4)))
   }
 }
diff --git a/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
deleted file mode 100644
index 62143ef580835..0000000000000
--- a/clang/test/CodeGenCXX/try-catch-with-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
-
-struct X { };
-
-const X g();
-
-void f() {
-  try {
-    throw g();
-    // CHECK: ptr addrspace(1) @_ZTI1X
-  } catch (const X x) {
-    // CHECK: catch ptr addrspace(1) @_ZTI1X
-    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
-  }
-}
-
-void h() {
-  try {
-    throw "ABC";
-    // CHECK: ptr addrspace(1) @_ZTIPKc
-  } catch (char const(&)[4]) {
-    // CHECK: catch ptr addrspace(1) @_ZTIA4_c
-    // CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
-  }
-}
diff --git a/clang/test/CodeGenCXX/typeid-cxx11-with-address-space.cpp b/clang/test/CodeGenCXX/typeid-cxx11-with-address-space.cpp
index c4e7d36acff13..f6dc38ec9f292 100644
--- a/clang/test/CodeGenCXX/typeid-cxx11-with-address-space.cpp
+++ b/clang/test/CodeGenCXX/typeid-cxx11-with-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 #include <typeinfo>
 
 namespace Test1 {
@@ -19,14 +20,17 @@ struct B : virtual A {};
 struct C { int n; };
 
 // CHECK: @_ZN5Test15itemsE ={{.*}} constant [4 x {{.*}}] [{{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIi to ptr), {{.*}} @_ZN5Test19make_implIiEEPvv }]
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test15itemsE ={{.*}} addrspace(1) constant [4 x {{.*}}] [{{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implIiEEPvv }]
 extern constexpr Item items[] = {
   item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
 };
 
 // CHECK: @_ZN5Test11xE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test11xE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
 constexpr auto &x = items[0].ti;
 
 // CHECK: @_ZN5Test11yE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test11yE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), align 8
 constexpr auto &y = typeid(B{});
 
 }
diff --git a/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
deleted file mode 100644
index cc6bc7f53b70a..0000000000000
--- a/clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s
-#include "typeinfo"
-
-namespace Test1 {
-
-struct Item {
-  const std::type_info &ti;
-  const char *name;
-  void *(*make)();
-};
-
-template<typename T> void *make_impl() { return new T; }
-template<typename T> constexpr Item item(const char *name) {
-  return { typeid(T), name, make_impl<T> };
-}
-
-struct A { virtual ~A(); };
-struct B : virtual A {};
-struct C { int n; };
-
-// CHECK: @_ZN5Test15itemsE ={{.*}} addrspace(1) constant [4 x {{.*}}] [{{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implIiEEPvv }]
-extern constexpr Item items[] = {
-  item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
-};
-
-// CHECK: @_ZN5Test11xE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
-constexpr auto &x = items[0].ti;
-
-// CHECK: @_ZN5Test11yE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), align 8
-constexpr auto &y = typeid(B{});
-
-}
diff --git a/clang/test/CodeGenCXX/typeid-with-address-space.cpp b/clang/test/CodeGenCXX/typeid-with-address-space.cpp
index b439770a8b631..98af17f4fc888 100644
--- a/clang/test/CodeGenCXX/typeid-with-address-space.cpp
+++ b/clang/test/CodeGenCXX/typeid-with-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 #include <typeinfo>
 
 namespace Test1 {
@@ -7,19 +8,23 @@ namespace Test1 {
 struct A { virtual void f(); };
 
 // CHECK: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIi to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), align 8
 const std::type_info &int_ti = typeid(int);
 
 // CHECK: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
 const std::type_info &A_ti = typeid(const volatile A &);
 
 volatile char c;
 
 // CHECK: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIc to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIc to ptr addrspace(4)), align 8
 const std::type_info &c_ti = typeid(c);
 
 extern const double &d;
 
 // CHECK: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTId to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTId to ptr addrspace(4)), align 8
 const std::type_info &d_ti = typeid(d);
 
 extern A &a;
@@ -28,18 +33,24 @@ extern A &a;
 const std::type_info &a_ti = typeid(a);
 
 // CHECK: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr), align 8
+// WITH-NONZERO-DEFAULT-AS: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr addrspace(4)), align 8
 const std::type_info &A10_c_ti = typeid(char const[10]);
 
 // CHECK-LABEL: define{{.*}} ptr @_ZN5Test11fEv
 // CHECK-SAME:  personality ptr @__gxx_personality_v0
+// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} ptr addrspace(4) @_ZN5Test11fEv
+// WITH-NONZERO-DEFAULT-AS-SAME:  personality ptr @__gxx_personality_v0
 const char *f() {
   try {
     // CHECK: br i1
     // CHECK: invoke void @__cxa_bad_typeid() [[NR:#[0-9]+]]
+    // WITH-NONZERO-DEFAULT-AS: invoke{{.*}} void @__cxa_bad_typeid() [[NR:#[0-9]+]]
     return typeid(*static_cast<A *>(0)).name();
   } catch (...) {
     // CHECK:      landingpad { ptr, i32 }
     // CHECK-NEXT:   catch ptr null
+    // WITH-NONZERO-DEFAULT-AS:      landingpad { ptr addrspace(4), i32 }
+    // WITH-NONZERO-DEFAULT-AS-NEXT:   catch ptr addrspace(4) null
   }
 
   return 0;
diff --git a/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
deleted file mode 100644
index 3a5a5515c46b4..0000000000000
--- a/clang/test/CodeGenCXX/typeid-with-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
-#include <typeinfo>
-
-namespace Test1 {
-
-// PR7400
-struct A { virtual void f(); };
-
-// CHECK: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), align 8
-const std::type_info &int_ti = typeid(int);
-
-// CHECK: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
-const std::type_info &A_ti = typeid(const volatile A &);
-
-volatile char c;
-
-// CHECK: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIc to ptr addrspace(4)), align 8
-const std::type_info &c_ti = typeid(c);
-
-extern const double &d;
-
-// CHECK: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTId to ptr addrspace(4)), align 8
-const std::type_info &d_ti = typeid(d);
-
-extern A &a;
-
-// CHECK: @_ZN5Test14a_tiE ={{.*}} global
-const std::type_info &a_ti = typeid(a);
-
-// CHECK: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr addrspace(4)), align 8
-const std::type_info &A10_c_ti = typeid(char const[10]);
-
-// CHECK-LABEL: define{{.*}} ptr addrspace(4) @_ZN5Test11fEv
-// CHECK-SAME:  personality ptr @__gxx_personality_v0
-const char *f() {
-  try {
-    // CHECK: br i1
-    // CHECK: invoke{{.*}} void @__cxa_bad_typeid() [[NR:#[0-9]+]]
-    return typeid(*static_cast<A *>(0)).name();
-  } catch (...) {
-    // CHECK:      landingpad { ptr addrspace(4), i32 }
-    // CHECK-NEXT:   catch ptr addrspace(4) null
-  }
-
-  return 0;
-}
-
-}
-
-// CHECK: attributes [[NR]] = { noreturn }
diff --git a/clang/test/CodeGenCXX/typeinfo-with-address-space.cpp b/clang/test/CodeGenCXX/typeinfo-with-address-space.cpp
index 80f6ab0903e51..350303cc6e9b3 100644
--- a/clang/test/CodeGenCXX/typeinfo-with-address-space.cpp
+++ b/clang/test/CodeGenCXX/typeinfo-with-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s -check-prefix=AS
+// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s -check-prefix=NONZERO-DEFAULT-AS
 // RUN: %clang_cc1 -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s -check-prefix=NO-AS
 #include <typeinfo>
 
@@ -25,24 +26,30 @@ class B : A {
 
 unsigned long Fn(B& b) {
 // AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr), ptr {{.*}} %2)
+// NONZERO-DEFAULT-AS: %call = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr addrspace(4)), ptr addrspace(4) {{.*}} %2)
 // NO-AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} @_ZTISt9type_info, ptr {{.*}} %2)
     if (typeid(std::type_info) == typeid(b))
         return 42;
 // AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr), ptr {{.*}} %5)
+// NONZERO-DEFAULT-AS: %call2 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), ptr addrspace(4) {{.*}} %5)
 // NO-AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} @_ZTIi, ptr {{.*}} %5)
     if (typeid(int) != typeid(b))
         return 1712;
 // AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr))
+// NONZERO-DEFAULT-AS: %call5 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr addrspace(4)))
 // NO-AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} @_ZTI1A)
 // AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
+// NONZERO-DEFAULT-AS: %call7 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} %8)
 // NO-AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
     if (typeid(A).name() == typeid(b).name())
         return 0;
 // AS: %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr))
+// NONZERO-DEFAULT-AS: %call11 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr addrspace(4) {{.*}} %11, ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr addrspace(4)))
 // NO-AS:   %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} @_ZTIf)
     if (typeid(b).before(typeid(float)))
         return 1;
 // AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
+// NONZERO-DEFAULT-AS: %call15 = call{{.*}} noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr addrspace(4) {{.*}} %14)
 // NO-AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
     return typeid(b).hash_code();
 }
diff --git a/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
deleted file mode 100644
index 7eab1ba86b9df..0000000000000
--- a/clang/test/CodeGenCXX/typeinfo-with-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s -check-prefix=AS
-// RUN: %clang_cc1 -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s -check-prefix=NO-AS
-#include <typeinfo>
-
-class A {
-    virtual void f() = 0;
-};
-
-class B : A {
-    void f() override;
-};
-
-// AS: @_ZTISt9type_info = external addrspace(1) constant ptr addrspace(1)
-// NO-AS: @_ZTISt9type_info = external constant ptr
-// AS: @_ZTIi = external addrspace(1) constant ptr addrspace(1)
-// NO-AS: @_ZTIi = external constant ptr
-// AS: @_ZTVN10__cxxabiv117__class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
-// NO-AS: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
-// AS: @_ZTS1A = linkonce_odr addrspace(1) constant [3 x i8] c"1A\00", comdat, align 1
-// NO-AS: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00", comdat, align 1
-// AS: @_ZTI1A = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1A }, comdat, align 8
-// NO-AS: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1A }, comdat, align 8
-// AS: @_ZTIf = external addrspace(1) constant ptr addrspace(1)
-// NO-AS: @_ZTIf = external constant ptr
-
-unsigned long Fn(B& b) {
-// AS: %call = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr addrspace(4)), ptr addrspace(4) {{.*}} %2)
-// NO-AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} @_ZTISt9type_info, ptr {{.*}} %2)
-    if (typeid(std::type_info) == typeid(b))
-        return 42;
-// AS: %call2 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), ptr addrspace(4) {{.*}} %5)
-// NO-AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} @_ZTIi, ptr {{.*}} %5)
-    if (typeid(int) != typeid(b))
-        return 1712;
-// AS: %call5 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr addrspace(4)))
-// NO-AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} @_ZTI1A)
-// AS: %call7 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} %8)
-// NO-AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
-    if (typeid(A).name() == typeid(b).name())
-        return 0;
-// AS: %call11 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr addrspace(4) {{.*}} %11, ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr addrspace(4)))
-// NO-AS:   %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} @_ZTIf)
-    if (typeid(b).before(typeid(float)))
-        return 1;
-// AS: %call15 = call{{.*}} noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr addrspace(4) {{.*}} %14)
-// NO-AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
-    return typeid(b).hash_code();
-}
diff --git a/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
deleted file mode 100644
index 2a1a7293982f1..0000000000000
--- a/clang/test/CodeGenCXX/vtable-align-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
-
-struct A {
-  virtual void f();
-  virtual void g();
-  virtual void h();
-};
-
-void A::f() {}
-
-// CHECK: @_ZTV1A ={{.*}} unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1A, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1A1gEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1A1hEv to ptr addrspace(1))]
-// CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1
-// CHECK: @_ZTI1A ={{.*}} addrspace(1) constant { ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1A }, align 8
diff --git a/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
deleted file mode 100644
index 4e3850264d42f..0000000000000
--- a/clang/test/CodeGenCXX/vtable-consteval-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -triple=spirv64-unknown-unknown -fsycl-is-device %s -emit-llvm -o - | FileCheck %s --check-prefix=ITANIUM --implicit-check-not=DoNotEmit
-
-// FIXME: The MSVC ABI rule in use here was discussed with MS folks prior to
-// them implementing virtual consteval functions, but we do not know for sure
-// if this is the ABI rule they will use.
-
-// ITANIUM-DAG: @_ZTV1A = {{.*}} addrspace(1) constant { [2 x ptr addrspace(1)] } {{.*}} null, {{.*}} @_ZTI1A
-struct A {
-  virtual consteval void DoNotEmit_f() {}
-};
-// ITANIUM-DAG: @a = addrspace(1) global { {{.*}} ptr addrspace(1) @_ZTV1A,
-A a;
-
-// ITANIUM-DAG: @_ZTV1B = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1B1fEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1B1hEv to ptr addrspace(1))
-struct B {
-  virtual void f() {}
-  virtual consteval void DoNotEmit_g() {}
-  virtual void h() {}
-};
-// ITANIUM-DAG: @b = addrspace(1) global { {{.*}} @_ZTV1B,
-B b;
-
-// ITANIUM-DAG: @_ZTV1C = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1C, ptr addrspace(1) addrspacecast (ptr @_ZN1CD1Ev to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1CD0Ev to ptr addrspace(1))
-struct C {
-  virtual ~C() = default;
-  virtual consteval C &operator=(const C&) = default;
-};
-// ITANIUM-DAG: @c = addrspace(1) global { {{.*}} @_ZTV1C,
-C c;
-
-// ITANIUM-DAG: @_ZTV1D = {{.*}} addrspace(1) constant { [4 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1D, ptr addrspace(1) addrspacecast (ptr @_ZN1DD1Ev to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1DD0Ev to ptr addrspace(1))
-struct D : C {};
-// ITANIUM-DAG: @d = addrspace(1) global { ptr addrspace(1) } { {{.*}} @_ZTV1D,
-D d;
-
-// ITANIUM-DAG: @_ZTV1E = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1E, ptr addrspace(1) addrspacecast (ptr @_ZN1E1fEv to ptr addrspace(1))
-struct E { virtual void f() {} };
-// ITANIUM-DAG: @e = addrspace(1) global { {{.*}} @_ZTV1E,
-E e;
-
-// ITANIUM-DAG: @_ZTV1F = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } {{.*}} addrspace(1) null, ptr addrspace(1) @_ZTI1F, ptr addrspace(1) addrspacecast (ptr @_ZN1E1fEv to ptr addrspace(1))
-struct F : E { virtual consteval void DoNotEmit_g(); };
-// ITANIUM-DAG: @f = addrspace(1) global { ptr addrspace(1) } { {{.*}} @_ZTV1F,
-F f;
diff --git a/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
deleted file mode 100644
index ea53d7208fc39..0000000000000
--- a/clang/test/CodeGenCXX/vtable-constexpr-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -triple=spirv64-unknown-unknown -fsycl-is-device %s -emit-llvm -o - | FileCheck %s --implicit-check-not=DoNotEmit
-
-// constexpr virtual functions can be called at runtime and go in the vtable as
-// normal. But they are implicitly inline so are never the key function.
-
-struct DoNotEmit {
-  virtual constexpr void f();
-};
-constexpr void DoNotEmit::f() {}
-
-// CHECK-DAG: @_ZTV1B = {{.*}} addrspace(1) constant { [3 x ptr addrspace(1)] } { {{.*}} null, {{.*}} @_ZTI1B, {{.*}} @_ZN1B1fEv
-struct B {
-  // CHECK-DAG: define {{.*}} @_ZN1B1fEv
-  virtual constexpr void f() {}
-};
-B b;
-
-struct CBase {
-  virtual constexpr void f(); // not key function
-};
-
-// CHECK-DAG: @_ZTV1C = {{.*}} addrspace(1) constant {{.*}} null, {{.*}} @_ZTI1C, {{.*}} @_ZN1C1fEv
-struct C : CBase {
-  void f(); // key function
-};
-// CHECK-DAG: define {{.*}} @_ZN1C1fEv
-void C::f() {}
diff --git a/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
deleted file mode 100644
index 3805afe61b8a2..0000000000000
--- a/clang/test/CodeGenCXX/vtable-key-function-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s
-// PR5697
-namespace PR5697 {
-struct A {
-  virtual void f() { }
-  A();
-  A(int);
-};
-
-// A does not have a key function, so the first constructor we emit should
-// cause the vtable to be defined (without assertions.)
-// CHECK: @_ZTVN6PR56971AE = linkonce_odr unnamed_addr addrspace(1) constant
-A::A() { }
-A::A(int) { }
-}
-
-// Make sure that we don't assert when building the vtable for a class
-// template specialization or explicit instantiation with a key
-// function.
-template<typename T>
-struct Base {
-  virtual ~Base();
-};
-
-template<typename T>
-struct Derived : public Base<T> { };
-
-template<>
-struct Derived<char> : public Base<char> {
-  virtual void anchor();
-};
-
-void Derived<char>::anchor() { }
diff --git a/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
deleted file mode 100644
index d639bfcf4d82a..0000000000000
--- a/clang/test/CodeGenCXX/vtable-layout-extreme-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
-
-// A collection of big class hierarchies and their vtables.
-
-namespace Test1 {
-
-class C0
-{
-};
-class C1
- :  virtual public C0
-{
-  int k0;
-};
-class C2
- :  public C0
- ,  virtual public C1
-{
-  int k0;
-};
-class C3
- :  virtual public C0
- ,  virtual public C1
- ,  public C2
-{
-  int k0;
-  int k1;
-  int k2;
-  int k3;
-};
-class C4
- :  public C2
- ,  virtual public C3
- ,  public C0
-{
-  int k0;
-};
-class C5
- :  public C0
- ,  virtual public C4
- ,  public C2
- ,  public C1
- ,  virtual public C3
-{
-  int k0;
-};
-class C6
- :  virtual public C3
- ,  public C0
- ,  public C5
- ,  public C4
- ,  public C1
-{
-  int k0;
-};
-class C7
- :  virtual public C5
- ,  virtual public C6
- ,  virtual public C3
- ,  public C4
- ,  virtual public C2
-{
-  int k0;
-  int k1;
-};
-class C8
- :  public C7
- ,  public C5
- ,  public C3
- ,  virtual public C4
- ,  public C1
- ,  public C2
-{
-  int k0;
-  int k1;
-};
-
-// CHECK:     Vtable for 'Test1::C9' (87 entries).
-// CHECK-NEXT:   0 | vbase_offset (344)
-// CHECK-NEXT:   1 | vbase_offset (312)
-// CHECK-NEXT:   2 | vbase_offset (184)
-// CHECK-NEXT:   3 | vbase_offset (168)
-// CHECK-NEXT:   4 | vbase_offset (120)
-// CHECK-NEXT:   5 | vbase_offset (48)
-// CHECK-NEXT:   6 | vbase_offset (148)
-// CHECK-NEXT:   7 | vbase_offset (152)
-// CHECK-NEXT:   8 | offset_to_top (0)
-// CHECK-NEXT:   9 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 0) vtable address --
-// CHECK-NEXT:       -- (Test1::C9, 0) vtable address --
-// CHECK-NEXT:  10 | void Test1::C9::f()
-// CHECK-NEXT:  11 | vbase_offset (104)
-// CHECK-NEXT:  12 | vbase_offset (132)
-// CHECK-NEXT:  13 | vbase_offset (136)
-// CHECK-NEXT:  14 | offset_to_top (-16)
-// CHECK-NEXT:  15 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 16) vtable address --
-// CHECK-NEXT:       -- (Test1::C4, 16) vtable address --
-// CHECK-NEXT:  16 | vbase_offset (72)
-// CHECK-NEXT:  17 | vbase_offset (120)
-// CHECK-NEXT:  18 | vbase_offset (100)
-// CHECK-NEXT:  19 | vbase_offset (104)
-// CHECK-NEXT:  20 | offset_to_top (-48)
-// CHECK-NEXT:  21 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 48) vtable address --
-// CHECK-NEXT:       -- (Test1::C5, 48) vtable address --
-// CHECK-NEXT:       -- (Test1::C6, 48) vtable address --
-// CHECK-NEXT:  22 | vbase_offset (84)
-// CHECK-NEXT:  23 | offset_to_top (-64)
-// CHECK-NEXT:  24 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 64) vtable address --
-// CHECK-NEXT:  25 | vbase_offset (32)
-// CHECK-NEXT:  26 | vbase_offset (60)
-// CHECK-NEXT:  27 | vbase_offset (64)
-// CHECK-NEXT:  28 | offset_to_top (-88)
-// CHECK-NEXT:  29 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 88) vtable address --
-// CHECK-NEXT:       -- (Test1::C4, 88) vtable address --
-// CHECK-NEXT:  30 | vbase_offset (44)
-// CHECK-NEXT:  31 | offset_to_top (-104)
-// CHECK-NEXT:  32 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 104) vtable address --
-// CHECK-NEXT:  33 | vbase_offset (28)
-// CHECK-NEXT:  34 | vbase_offset (32)
-// CHECK-NEXT:  35 | offset_to_top (-120)
-// CHECK-NEXT:  36 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 120) vtable address --
-// CHECK-NEXT:       -- (Test1::C3, 120) vtable address --
-// CHECK-NEXT:  37 | vbase_offset (-4)
-// CHECK-NEXT:  38 | offset_to_top (-152)
-// CHECK-NEXT:  39 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 152) vtable address --
-// CHECK-NEXT:  40 | vbase_offset (-48)
-// CHECK-NEXT:  41 | vbase_offset (-20)
-// CHECK-NEXT:  42 | vbase_offset (-16)
-// CHECK-NEXT:  43 | offset_to_top (-168)
-// CHECK-NEXT:  44 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 168) vtable address --
-// CHECK-NEXT:       -- (Test1::C4, 168) vtable address --
-// CHECK-NEXT:  45 | vbase_offset (160)
-// CHECK-NEXT:  46 | vbase_offset (-136)
-// CHECK-NEXT:  47 | vbase_offset (-16)
-// CHECK-NEXT:  48 | vbase_offset (128)
-// CHECK-NEXT:  49 | vbase_offset (-64)
-// CHECK-NEXT:  50 | vbase_offset (-36)
-// CHECK-NEXT:  51 | vbase_offset (-32)
-// CHECK-NEXT:  52 | offset_to_top (-184)
-// CHECK-NEXT:  53 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 184) vtable address --
-// CHECK-NEXT:       -- (Test1::C4, 184) vtable address --
-// CHECK-NEXT:       -- (Test1::C7, 184) vtable address --
-// CHECK-NEXT:       -- (Test1::C8, 184) vtable address --
-// CHECK-NEXT:  54 | vbase_offset (-88)
-// CHECK-NEXT:  55 | vbase_offset (-40)
-// CHECK-NEXT:  56 | vbase_offset (-60)
-// CHECK-NEXT:  57 | vbase_offset (-56)
-// CHECK-NEXT:  58 | offset_to_top (-208)
-// CHECK-NEXT:  59 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 208) vtable address --
-// CHECK-NEXT:       -- (Test1::C5, 208) vtable address --
-// CHECK-NEXT:  60 | vbase_offset (-76)
-// CHECK-NEXT:  61 | offset_to_top (-224)
-// CHECK-NEXT:  62 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 224) vtable address --
-// CHECK-NEXT:  63 | vbase_offset (-92)
-// CHECK-NEXT:  64 | vbase_offset (-88)
-// CHECK-NEXT:  65 | offset_to_top (-240)
-// CHECK-NEXT:  66 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 240) vtable address --
-// CHECK-NEXT:       -- (Test1::C3, 240) vtable address --
-// CHECK-NEXT:  67 | vbase_offset (-124)
-// CHECK-NEXT:  68 | offset_to_top (-272)
-// CHECK-NEXT:  69 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 272) vtable address --
-// CHECK-NEXT:  70 | vbase_offset (-140)
-// CHECK-NEXT:  71 | vbase_offset (-136)
-// CHECK-NEXT:  72 | offset_to_top (-288)
-// CHECK-NEXT:  73 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 288) vtable address --
-// CHECK-NEXT:  74 | vbase_offset (-192)
-// CHECK-NEXT:  75 | vbase_offset (-144)
-// CHECK-NEXT:  76 | vbase_offset (-164)
-// CHECK-NEXT:  77 | vbase_offset (-160)
-// CHECK-NEXT:  78 | offset_to_top (-312)
-// CHECK-NEXT:  79 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C2, 312) vtable address --
-// CHECK-NEXT:       -- (Test1::C5, 312) vtable address --
-// CHECK-NEXT:  80 | vbase_offset (-180)
-// CHECK-NEXT:  81 | offset_to_top (-328)
-// CHECK-NEXT:  82 | Test1::C9 RTTI
-// CHECK-NEXT:       -- (Test1::C1, 328) vtable address --
-// CHECK-NEXT:  83 | vbase_offset (-196)
-// CHECK-NEXT:  84 | vbase_offset (-192)
-// CHECK-NEXT:  85 | offset_to_top (-344)
-// CHECK-NEXT:  86 | Test1::C9 RTTI
-class C9
- :  virtual public C6
- ,  public C2
- ,  public C4
- ,  virtual public C8
-{
-  int k0;
-  int k1;
-  int k2;
-  int k3;
-  virtual void f();
-};
-void C9::f() { }
-
-}
diff --git a/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
deleted file mode 100644
index 38f6b6a352bb8..0000000000000
--- a/clang/test/CodeGenCXX/vtable-linkage-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o %t
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++03 -o %t.03
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o %t.11
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -disable-llvm-passes -O3 -emit-llvm -o %t.opt
-// RUN: FileCheck %s < %t
-// RUN: FileCheck %s < %t.03
-// RUN: FileCheck %s < %t.11
-// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
-
-namespace {
-  struct A {
-    virtual void f() { }
-  };
-}
-
-void f() { A b; }
-
-struct B {
-  B();
-  virtual void f();
-};
-
-B::B() { }
-
-struct C : virtual B {
-  C();
-  virtual void f() { }
-};
-
-C::C() { }
-
-struct D {
-  virtual void f();
-};
-
-void D::f() { }
-
-static struct : D { } e;
-
-// Force 'e' to be constructed and therefore have a vtable defined.
-void use_e() {
-  e.f();
-}
-
-// The destructor is the key function.
-template<typename T>
-struct E {
-  virtual ~E();
-};
-
-template<typename T> E<T>::~E() { }
-
-// Anchor is the key function
-template<>
-struct E<char> {
-  virtual void anchor();
-};
-
-void E<char>::anchor() { }
-
-template struct E<short>;
-extern template struct E<int>;
-
-void use_E() {
-  E<int> ei;
-  (void)ei;
-  E<long> el;
-  (void)el;
-}
-
-// No key function
-template<typename T>
-struct F {
-  virtual void foo() { }
-};
-
-// No key function
-template<>
-struct F<char> {
-  virtual void foo() { }
-};
-
-template struct F<short>;
-extern template struct F<int>;
-
-void use_F() {
-  F<char> fc;
-  fc.foo();
-  F<int> fi;
-  fi.foo();
-  F<long> fl;
-  (void)fl;
-}
-
-// B has a key function that is not defined in this translation unit so its vtable
-// has external linkage.
-// CHECK-DAG: @_ZTV1B = external unnamed_addr addrspace(1) constant
-
-// C has no key function, so its vtable should have weak_odr linkage
-// and hidden visibility
-// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-// CHECK-DAG: @_ZTS1C = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1C = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// D has a key function that is defined in this translation unit so its vtable is
-// defined in the translation unit.
-// CHECK-DAG: @_ZTV1D ={{.*}} unnamed_addr addrspace(1) constant
-// CHECK-DAG: @_ZTS1D ={{.*}} addrspace(1) constant
-// CHECK-DAG: @_ZTI1D ={{.*}} addrspace(1) constant
-
-// E<char> is an explicit specialization with a key function defined
-// in this translation unit, so its vtable should have external
-// linkage.
-// CHECK-DAG: @_ZTV1EIcE ={{.*}} unnamed_addr addrspace(1) constant
-// CHECK-DAG: @_ZTS1EIcE ={{.*}} addrspace(1) constant
-// CHECK-DAG: @_ZTI1EIcE ={{.*}} addrspace(1) constant
-
-// E<short> is an explicit template instantiation with a key function
-// defined in this translation unit, so its vtable should have
-// weak_odr linkage.
-// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1EIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1EIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// F<short> is an explicit template instantiation without a key
-// function, so its vtable should have weak_odr linkage
-// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1FIsE = weak_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// E<long> is an implicit template instantiation with a key function
-// defined in this translation unit, so its vtable should have
-// linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1EIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1EIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// F<long> is an implicit template instantiation with no key function,
-// so its vtable should have linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1FIlE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// F<int> is an explicit template instantiation declaration without a
-// key function, so its vtable should have external linkage.
-// CHECK-DAG: @_ZTV1FIiE = external unnamed_addr addrspace(1) constant
-// CHECK-OPT-DAG: @_ZTV1FIiE = available_externally unnamed_addr addrspace(1) constant
-
-// E<int> is an explicit template instantiation declaration. It has a
-// key function is not instantiated, so we know that vtable definition
-// will be generated in TU where key function will be defined
-// so we can mark it as external (without optimizations) and
-// available_externally (with optimizations) because all of the inline
-// virtual functions have been emitted.
-// CHECK-DAG: @_ZTV1EIiE = external unnamed_addr addrspace(1) constant
-// CHECK-OPT-DAG: @_ZTV1EIiE = available_externally unnamed_addr addrspace(1) constant
-
-// The anonymous struct for e has no linkage, so the vtable should have
-// internal linkage.
-// CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr addrspace(1) constant
-// CHECK-DAG: @"_ZTS3$_0" = internal addrspace(1) constant
-// CHECK-DAG: @"_ZTI3$_0" = internal addrspace(1) constant
-
-// The A vtable should have internal linkage since it is inside an anonymous
-// namespace.
-// CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr addrspace(1) constant
-// CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal addrspace(1) constant
-// CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal addrspace(1) constant
-
-// F<char> is an explicit specialization without a key function, so
-// its vtable should have linkonce_odr linkage.
-// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-// CHECK-DAG: @_ZTS1FIcE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 1{{$}}
-// CHECK-DAG: @_ZTI1FIcE = linkonce_odr addrspace(1) constant {{.*}}, comdat, align 8{{$}}
-
-// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-template <typename T>
-class G {
-public:
-  G() {}
-  virtual void f0();
-  virtual void f1();
-};
-template <>
-void G<int>::f1() {}
-template <typename T>
-void G<T>::f0() {}
-void G_f0()  { new G<int>(); }
-
-// H<int> has a key function without a body but it's a template instantiation
-// so its VTable must be emitted.
-// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr addrspace(1) constant {{.*}}, comdat,
-template <typename T>
-class H {
-public:
-  virtual ~H();
-};
-
-void use_H() {
-  H<int> h;
-}
-
-// I<int> has an explicit instantiation declaration and needs a VTT and
-// construction vtables.
-
-// CHECK-DAG: @_ZTV1IIiE = external unnamed_addr addrspace(1) constant
-// CHECK-DAG: @_ZTT1IIiE = external unnamed_addr addrspace(1) constant
-// CHECK-NOT: @_ZTC1IIiE
-//
-// CHECK-OPT-DAG: @_ZTV1IIiE = available_externally unnamed_addr addrspace(1) constant
-// CHECK-OPT-DAG: @_ZTT1IIiE = available_externally unnamed_addr addrspace(1) constant
-struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {};
-template<typename T>
-struct I : VBase2 {};
-extern template struct I<int>;
-I<int> i;
diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp
index a3f12f0ebfc87..876d0845cc515 100644
--- a/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp
+++ b/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 
 struct Field {
   Field();
@@ -24,6 +25,7 @@ struct A : Base {
 // CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
 // CHECK: call void @_ZN5FieldC1Ev(
 // CHECK: ret void
+// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
 A::A() { }
 
 // CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr {{[^,]*}} %this) unnamed_addr
@@ -31,6 +33,7 @@ A::A() { }
 // CHECK: call void @_ZN5FieldD1Ev(
 // CHECK: call void @_ZN4BaseD2Ev(
 // CHECK: ret void
+// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
 A::~A() { }
 
 struct B : Base {
@@ -43,18 +46,22 @@ void f() { B b; }
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ev(ptr {{[^,]*}} %this) unnamed_addr
 // CHECK: call void @_ZN1BC2Ev(
+// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BC1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BD1Ev(ptr {{[^,]*}} %this) unnamed_addr
 // CHECK: call void @_ZN1BD2Ev(
+// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BD1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(ptr {{[^,]*}} %this) unnamed_addr
 // CHECK: call void @_ZN4BaseC2Ev(
 // CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
 // CHECK: call void @_ZN5FieldC1Ev
 // CHECK: ret void
+// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(ptr {{[^,]*}} %this) unnamed_addr
 // CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
 // CHECK: call void @_ZN5FieldD1Ev(
 // CHECK: call void @_ZN4BaseD2Ev(
 // CHECK: ret void
+// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
deleted file mode 100644
index efb4afb38f5e8..0000000000000
--- a/clang/test/CodeGenCXX/vtable-pointer-initialization-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
-
-struct Field {
-  Field();
-  ~Field();
-};
-
-struct Base {
-  Base();
-  ~Base();
-};
-
-struct A : Base {
-  A();
-  ~A();
-
-  virtual void f();
-
-  Field field;
-};
-
-// CHECK-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: call{{.*}} void @_ZN4BaseC2Ev(
-// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
-// CHECK: call{{.*}} void @_ZN5FieldC1Ev(
-// CHECK: ret void
-A::A() { }
-
-// CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
-// CHECK: call{{.*}} void @_ZN5FieldD1Ev(
-// CHECK: call{{.*}} void @_ZN4BaseD2Ev(
-// CHECK: ret void
-A::~A() { }
-
-struct B : Base {
-  virtual void f();
-
-  Field field;
-};
-
-void f() { B b; }
-
-// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BC1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: call{{.*}} void @_ZN1BC2Ev(
-
-// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BD1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: call{{.*}} void @_ZN1BD2Ev(
-
-// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: call{{.*}} void @_ZN4BaseC2Ev(
-// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
-// CHECK: call{{.*}} void @_ZN5FieldC1Ev
-// CHECK: ret void
-
-// CHECK-LABEL: define linkonce_odr{{.*}} void @_ZN1BD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
-// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
-// CHECK: call{{.*}} void @_ZN5FieldD1Ev(
-// CHECK: call{{.*}} void @_ZN4BaseD2Ev(
-// CHECK: ret void
diff --git a/clang/test/CodeGenCXX/vtt-address-space.cpp b/clang/test/CodeGenCXX/vtt-address-space.cpp
index 24f4e2a755da0..4c3d0a534611c 100644
--- a/clang/test/CodeGenCXX/vtt-address-space.cpp
+++ b/clang/test/CodeGenCXX/vtt-address-space.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
 
 // This is the sample from the C++ Itanium ABI, p2.6.2.
 namespace Test {
@@ -25,3 +26,9 @@ namespace Test {
 // CHECK: define linkonce_odr void @_ZN4Test2V2C2Ev(ptr noundef nonnull align 8 dereferenceable(20) %this, ptr addrspace(1) noundef %vtt)
 // CHECK: define linkonce_odr void @_ZN4Test2C1C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this, ptr addrspace(1) noundef %vtt)
 // CHECK: define linkonce_odr void @_ZN4Test2C2C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this, ptr addrspace(1) noundef %vtt)
+// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %2, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 11))
+// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this1, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 1))
+// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %3, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 3))
+// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %this, ptr addrspace(1) noundef %vtt)
+// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
+// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
diff --git a/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
deleted file mode 100644
index 52c6249af9f51..0000000000000
--- a/clang/test/CodeGenCXX/vtt-layout-with-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
-
-// Test1::B should just have a single entry in its VTT, which points to the vtable.
-namespace Test1 {
-struct A { };
-
-struct B : virtual A {
-  virtual void f();
-};
-
-void B::f() { }
-}
-
-// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
-namespace Test2 {
-  struct A { };
-
-  struct B : A { virtual void f(); };
-  struct C : virtual B { };
-
-  C c;
-}
-
-// This is the sample from the C++ Itanium ABI, p2.6.2.
-namespace Test3 {
-  class A1 { int i; };
-  class A2 { int i; virtual void f(); };
-  class V1 : public A1, public A2 { int i; };
-  class B1 { int i; };
-  class B2 { int i; };
-  class V2 : public B1, public B2, public virtual V1 { int i; };
-  class V3 {virtual void g(); };
-  class C1 : public virtual V1 { int i; };
-  class C2 : public virtual V3, virtual V2 { int i; };
-  class X1 { int i; };
-  class C3 : public X1 { int i; };
-  class D : public C1, public C2, public C3 { int i;  };
-
-  D d;
-}
-
-// This is the sample from the C++ Itanium ABI, p2.6.2, with the change suggested
-// (making A2 a virtual base of V1)
-namespace Test4 {
-  class A1 { int i; };
-  class A2 { int i; virtual void f(); };
-  class V1 : public A1, public virtual A2 { int i; };
-  class B1 { int i; };
-  class B2 { int i; };
-  class V2 : public B1, public B2, public virtual V1 { int i; };
-  class V3 {virtual void g(); };
-  class C1 : public virtual V1 { int i; };
-  class C2 : public virtual V3, virtual V2 { int i; };
-  class X1 { int i; };
-  class C3 : public X1 { int i; };
-  class D : public C1, public C2, public C3 { int i;  };
-
-  D d;
-}
-
-namespace Test5 {
-  struct A {
-    virtual void f() = 0;
-    virtual void anchor();
-  };
-
-  void A::anchor() {
-  }
-}
-
-namespace Test6 {
-  struct A {
-    virtual void f() = delete;
-    virtual void anchor();
-  };
-
-  void A::anchor() {
-  }
-}
-
-// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr addrspace(1) constant [1 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test11BE, i32 0, i32 0, i32 3)]
-// CHECK: @_ZTVN5Test51AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test51AE, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test51A6anchorEv to ptr addrspace(1))] }
-// CHECK: @_ZTVN5Test61AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test61AE, ptr addrspace(1) addrspacecast (ptr @__cxa_deleted_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test61A6anchorEv to ptr addrspace(1))] }
-// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr addrspace(1) constant [2 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4)]
-// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 1, i32 3)]
-// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant { [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [6 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 72 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test41DE], [8 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 24 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42V31gEv to ptr addrspace(1))], [3 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -40 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE], [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -56 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42A21fEv to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -32 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -72 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE] }
-// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant [19 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-48, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 1, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 4, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 2, i32 3)]
-// CHECK: declare{{.*}} void @__cxa_pure_virtual() unnamed_addr
-// CHECK: declare{{.*}} void @__cxa_deleted_virtual() unnamed_addr
diff --git a/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp
deleted file mode 100644
index c7f388959201f..0000000000000
--- a/clang/test/CodeGenCXX/vtt-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s
-
-// This is the sample from the C++ Itanium ABI, p2.6.2.
-namespace Test {
-  class A1 { int i; };
-  class A2 { int i; virtual void f(); };
-  class V1 : public A1, public A2 { int i; };
-  class B1 { int i; };
-  class B2 { int i; };
-  class V2 : public B1, public B2, public virtual V1 { int i; };
-  class V3 { virtual void g(); };
-  class C1 : public virtual V1 { int i; };
-  class C2 : public virtual V3, virtual V2 { int i; };
-  class X1 { int i; };
-  class C3 : public X1 { int i; };
-  class D : public C1, public C2, public C3 { int i;  };
-
-  D d;
-}
-
-// CHECK: linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 1, i32 3)], comdat, align 8
-// CHECK: call {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %2, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 11))
-// CHECK: call {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this1, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 1))
-// CHECK: call {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %3, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 3))
-// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %this, ptr addrspace(1) noundef %vtt)
-// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
-// CHECK: define linkonce_odr {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)

>From 515f4f9c4259e887affab0ff525e11cfff8b4c3d Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Thu, 25 Apr 2024 01:18:07 +0100
Subject: [PATCH 12/15] `llvm.eh.typeid.for` should also be generic.

---
 clang/lib/CodeGen/CGException.cpp                  |  5 +++--
 clang/test/CodeGenCXX/eh.cpp                       |  6 +++---
 clang/test/CodeGenCXX/nrvo.cpp                     |  4 ++--
 clang/test/CodeGenCXX/wasm-eh.cpp                  |  4 ++--
 llvm/examples/ExceptionDemo/ExceptionDemo.cpp      |  2 +-
 llvm/include/llvm/IR/Intrinsics.td                 |  4 ++--
 .../CodeGen/WebAssembly/lower-em-exceptions.ll     |  6 +++---
 .../Transforms/GVNHoist/infinite-loop-indirect.ll  |  6 +++---
 llvm/test/Transforms/Inline/inline_invoke.ll       | 10 +++++-----
 llvm/test/Transforms/LICM/scalar-promote-unwind.ll |  6 +++---
 .../LowerTypeTests/cfi-unwind-direct-call.ll       |  6 +++---
 .../test/Transforms/NewGVN/2011-09-07-TypeIdFor.ll | 14 +++++++-------
 .../mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td        |  2 +-
 mlir/test/Target/LLVMIR/Import/intrinsic.ll        |  4 ++--
 mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir     |  2 +-
 15 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 34f289334a7df..8ccb44eee8427 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1052,7 +1052,8 @@ static void emitWasmCatchPadBlock(CodeGenFunction &CGF,
   CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());
   llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
 
-  llvm::Function *TypeIDFn = CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+  llvm::Function *TypeIDFn =
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
 
   // If there's only a single catch-all, branch directly to its handler.
   if (CatchScope.getNumHandlers() == 1 &&
@@ -1137,7 +1138,7 @@ static void emitCatchDispatchBlock(CodeGenFunction &CGF,
 
   // Select the right handler.
   llvm::Function *llvm_eh_typeid_for =
-    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
   llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
   LangAS globAS = CGF.CGM.GetGlobalVarAddressSpace(nullptr);
 
diff --git a/clang/test/CodeGenCXX/eh.cpp b/clang/test/CodeGenCXX/eh.cpp
index 5c592a96e27b7..f174b5d84fdf5 100644
--- a/clang/test/CodeGenCXX/eh.cpp
+++ b/clang/test/CodeGenCXX/eh.cpp
@@ -81,7 +81,7 @@ namespace test5 {
 // CHECK:      invoke void @__cxa_throw(ptr [[EXNOBJ]], ptr @_ZTIN5test51AE, ptr @_ZN5test51AD1Ev) [[NR]]
 // CHECK-NEXT:   to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
 //      :    [[HANDLER]]:  (can't check this in Release-Asserts builds)
-// CHECK:      {{%.*}} = call i32 @llvm.eh.typeid.for(ptr @_ZTIN5test51AE)
+// CHECK:      {{%.*}} = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIN5test51AE)
 }
 
 namespace test6 {
@@ -96,7 +96,7 @@ namespace test6 {
 
 // PR7127
 namespace test7 {
-// CHECK-LABEL:      define{{.*}} i32 @_ZN5test73fooEv() 
+// CHECK-LABEL:      define{{.*}} i32 @_ZN5test73fooEv()
 // CHECK-SAME:  personality ptr @__gxx_personality_v0
   int foo() {
 // CHECK:      [[CAUGHTEXNVAR:%.*]] = alloca ptr
@@ -119,7 +119,7 @@ namespace test7 {
 // CHECK-NEXT: store i32 [[SELECTOR]], ptr [[SELECTORVAR]]
 // CHECK-NEXT: br label
 // CHECK:      [[SELECTOR:%.*]] = load i32, ptr [[SELECTORVAR]]
-// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
 // CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]]
 // CHECK-NEXT: br i1
 // CHECK:      [[T0:%.*]] = load ptr, ptr [[CAUGHTEXNVAR]]
diff --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp
index 33dc4cf9dbc8d..23ac04511514d 100644
--- a/clang/test/CodeGenCXX/nrvo.cpp
+++ b/clang/test/CodeGenCXX/nrvo.cpp
@@ -628,7 +628,7 @@ void may_throw();
 // CHECK-EH-03-NEXT:    br label [[CATCH_DISPATCH:%.*]]
 // CHECK-EH-03:       catch.dispatch:
 // CHECK-EH-03-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4
-// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR7]]
+// CHECK-EH-03-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR7]]
 // CHECK-EH-03-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]
 // CHECK-EH-03-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 // CHECK-EH-03:       catch:
@@ -707,7 +707,7 @@ void may_throw();
 // CHECK-EH-11-NEXT:    br label [[CATCH_DISPATCH:%.*]]
 // CHECK-EH-11:       catch.dispatch:
 // CHECK-EH-11-NEXT:    [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4
-// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR6]]
+// CHECK-EH-11-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR6]]
 // CHECK-EH-11-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]
 // CHECK-EH-11-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 // CHECK-EH-11:       catch:
diff --git a/clang/test/CodeGenCXX/wasm-eh.cpp b/clang/test/CodeGenCXX/wasm-eh.cpp
index af023f52191b9..1b17498ba9ce9 100644
--- a/clang/test/CodeGenCXX/wasm-eh.cpp
+++ b/clang/test/CodeGenCXX/wasm-eh.cpp
@@ -34,7 +34,7 @@ void test0() {
 // CHECK-NEXT:   %[[EXN:.*]] = call ptr @llvm.wasm.get.exception(token %[[CATCHPAD]])
 // CHECK-NEXT:   store ptr %[[EXN]], ptr %exn.slot
 // CHECK-NEXT:   %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector(token %[[CATCHPAD]])
-// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #7
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #7
 // CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
 // CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]]
 
@@ -51,7 +51,7 @@ void test0() {
 // CHECK-NEXT:   br label %[[TRY_CONT_BB:.*]]
 
 // CHECK: [[CATCH_FALLTHROUGH_BB]]
-// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTId) #7
+// CHECK-NEXT:   %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTId) #7
 // CHECK-NEXT:   %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
 // CHECK-NEXT:   br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]]
 
diff --git a/llvm/examples/ExceptionDemo/ExceptionDemo.cpp b/llvm/examples/ExceptionDemo/ExceptionDemo.cpp
index 0afc6b30d140e..fdee76cb96146 100644
--- a/llvm/examples/ExceptionDemo/ExceptionDemo.cpp
+++ b/llvm/examples/ExceptionDemo/ExceptionDemo.cpp
@@ -1865,7 +1865,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
 
   // llvm.eh.typeid.for intrinsic
 
-  getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
+  getDeclaration(&module, llvm::Intrinsic::eh_typeid_for, builder.getPtrTy());
 }
 
 
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 1d20f7e1b1985..a0b8fc50def39 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1365,7 +1365,7 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
 
 // The result of eh.typeid.for depends on the enclosing function, but inside a
 // given function it is 'const' and may be CSE'd etc.
-def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
+def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem]>;
 
 def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
 def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
@@ -1724,7 +1724,7 @@ def int_coro_subfn_addr : DefaultAttrsIntrinsic<
 
 ///===-------------------------- Other Intrinsics --------------------------===//
 //
-// TODO: We should introduce a new memory kind fo traps (and other side effects 
+// TODO: We should introduce a new memory kind fo traps (and other side effects
 //       we only model to keep things alive).
 def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold, IntrInaccessibleMemOnly,
                IntrWriteMem]>, ClangBuiltin<"__builtin_trap">;
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
index d17a5b419e351..f6b36c56c6d3d 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
@@ -44,7 +44,7 @@ lpad:                                             ; preds = %entry
 ; CHECK-NEXT: %[[CDR:.*]] = extractvalue { ptr, i32 } %[[IVI2]], 1
 
 catch.dispatch:                                   ; preds = %lpad
-  %3 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+  %3 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
   %matches = icmp eq i32 %2, %3
   br i1 %matches, label %catch1, label %catch
 ; CHECK: catch.dispatch:
@@ -139,7 +139,7 @@ lpad:                                             ; preds = %entry
   br label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %lpad
-  %4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+  %4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
   %matches = icmp eq i32 %3, %4
   br i1 %matches, label %catch1, label %catch
 
@@ -162,7 +162,7 @@ declare void @foo(i32)
 declare ptr @bar(i8, i8)
 
 declare i32 @__gxx_personality_v0(...)
-declare i32 @llvm.eh.typeid.for(ptr)
+declare i32 @llvm.eh.typeid.for.p0(ptr)
 declare ptr @__cxa_begin_catch(ptr)
 declare void @__cxa_end_catch()
 declare void @__cxa_call_unexpected(ptr)
diff --git a/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll b/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll
index aef55af81dcac..a7e6ff30d8b2f 100644
--- a/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll
+++ b/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll
@@ -292,7 +292,7 @@ define i32 @foo2(ptr nocapture readonly %i) local_unnamed_addr personality ptr @
 ; CHECK-NEXT:    [[BC1:%.*]] = add i32 [[TMP0]], 10
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1
-; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #[[ATTR1]]
+; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #[[ATTR1]]
 ; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP4]], [[TMP5]]
 ; CHECK-NEXT:    [[BC7:%.*]] = add i32 [[TMP0]], 10
 ; CHECK-NEXT:    [[TMP6:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR1]]
@@ -340,7 +340,7 @@ lpad:
   %bc1 = add i32 %0, 10
   %3 = extractvalue { ptr, i32 } %2, 0
   %4 = extractvalue { ptr, i32 } %2, 1
-  %5 = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #2
+  %5 = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #2
   %matches = icmp eq i32 %4, %5
   %bc7 = add i32 %0, 10
   %6 = tail call ptr @__cxa_begin_catch(ptr %3) #2
@@ -383,7 +383,7 @@ declare void @__cxa_throw(ptr, ptr, ptr) local_unnamed_addr
 declare i32 @__gxx_personality_v0(...)
 
 ; Function Attrs: nounwind readnone
-declare i32 @llvm.eh.typeid.for(ptr) #1
+declare i32 @llvm.eh.typeid.for.p0(ptr) #1
 
 declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr
 
diff --git a/llvm/test/Transforms/Inline/inline_invoke.ll b/llvm/test/Transforms/Inline/inline_invoke.ll
index 89c56447c07bd..5441e2a9e63b9 100644
--- a/llvm/test/Transforms/Inline/inline_invoke.ll
+++ b/llvm/test/Transforms/Inline/inline_invoke.ll
@@ -19,7 +19,7 @@ declare void @use(i32) nounwind
 
 declare void @opaque()
 
-declare i32 @llvm.eh.typeid.for(ptr) nounwind
+declare i32 @llvm.eh.typeid.for.p0(ptr) nounwind
 
 declare i32 @__gxx_personality_v0(...)
 
@@ -74,7 +74,7 @@ lpad:                                             ; preds = %entry
             catch ptr @_ZTIi
   %eh.exc = extractvalue { ptr, i32 } %exn, 0
   %eh.selector = extractvalue { ptr, i32 } %exn, 1
-  %0 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) nounwind
+  %0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind
   %1 = icmp eq i32 %eh.selector, %0
   br i1 %1, label %catch, label %eh.resume
 
@@ -109,7 +109,7 @@ eh.resume:
 ; CHECK-NEXT: phi { ptr, i32 } [
 ; CHECK-NEXT: extractvalue { ptr, i32 }
 ; CHECK-NEXT: extractvalue { ptr, i32 }
-; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
+; CHECK-NEXT: call i32 @llvm.eh.typeid.for.p0(
 
 
 ;; Test 1 - Correctly handle phis in outer landing pads.
@@ -133,7 +133,7 @@ lpad:
             catch ptr @_ZTIi
   %eh.exc = extractvalue { ptr, i32 } %exn, 0
   %eh.selector = extractvalue { ptr, i32 } %exn, 1
-  %0 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) nounwind
+  %0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind
   %1 = icmp eq i32 %eh.selector, %0
   br i1 %1, label %catch, label %eh.resume
 
@@ -212,7 +212,7 @@ eh.resume:
 ; CHECK-NEXT: [[EXNJ1:%.*]] = phi { ptr, i32 } [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[LPADVAL1]], %[[RESUME1]] ]
 ; CHECK-NEXT: extractvalue { ptr, i32 } [[EXNJ1]], 0
 ; CHECK-NEXT: [[SELJ1:%.*]] = extractvalue { ptr, i32 } [[EXNJ1]], 1
-; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for(
+; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for.p0(
 ; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]
 
 ; CHECK:      call void @use(i32 [[XJ1]])
diff --git a/llvm/test/Transforms/LICM/scalar-promote-unwind.ll b/llvm/test/Transforms/LICM/scalar-promote-unwind.ll
index be11722d2d567..f7829c4d6e4d9 100644
--- a/llvm/test/Transforms/LICM/scalar-promote-unwind.ll
+++ b/llvm/test/Transforms/LICM/scalar-promote-unwind.ll
@@ -304,7 +304,7 @@ define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
 ; CHECK-NEXT:    br label [[CATCH_DISPATCH:%.*]]
 ; CHECK:       catch.dispatch:
-; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
 ; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
 ; CHECK-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 ; CHECK:       catch:
@@ -355,7 +355,7 @@ lpad:
   br label %catch.dispatch
 
 catch.dispatch:
-  %4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #3
+  %4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #3
   %matches = icmp eq i32 %3, %4
   br i1 %matches, label %catch, label %eh.resume
 
@@ -564,6 +564,6 @@ declare ptr @__cxa_begin_catch(ptr)
 
 declare void @__cxa_end_catch()
 
-declare i32 @llvm.eh.typeid.for(ptr)
+declare i32 @llvm.eh.typeid.for.p0(ptr)
 
 declare void @f() uwtable
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
index 3e1f8b97e98b8..4d5055cc5a760 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
@@ -65,7 +65,7 @@ lpad:                                             ; preds = %cfi.cont
   %1 = landingpad { ptr, i32 }
   catch ptr @_ZTIi
   %2 = extractvalue { ptr, i32 } %1, 1
-  %3 = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #5
+  %3 = tail call i32 @llvm.eh.typeid.for.p0(ptr nonnull @_ZTIi) #5
   %matches = icmp eq i32 %2, %3
   br i1 %matches, label %catch, label %eh.resume
 
@@ -90,7 +90,7 @@ declare void @__cfi_slowpath(i64, ptr) local_unnamed_addr
 declare i32 @__gxx_personality_v0(...)
 
 ; Function Attrs: nofree nosync nounwind memory(none)
-declare i32 @llvm.eh.typeid.for(ptr) #2
+declare i32 @llvm.eh.typeid.for.p0(ptr) #2
 
 declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr
 
@@ -181,7 +181,7 @@ attributes #8 = { noreturn nounwind }
 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
 ; CHECK-NEXT:            catch ptr @_ZTIi
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #[[ATTR6]]
+; CHECK-NEXT:    [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr nonnull @_ZTIi) #[[ATTR6]]
 ; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
 ; CHECK:       catch:
diff --git a/llvm/test/Transforms/NewGVN/2011-09-07-TypeIdFor.ll b/llvm/test/Transforms/NewGVN/2011-09-07-TypeIdFor.ll
index 675e7da26a105..afd7610b71624 100644
--- a/llvm/test/Transforms/NewGVN/2011-09-07-TypeIdFor.ll
+++ b/llvm/test/Transforms/NewGVN/2011-09-07-TypeIdFor.ll
@@ -10,7 +10,7 @@ declare void @_Z4barv()
 
 declare void @_Z7cleanupv()
 
-declare i32 @llvm.eh.typeid.for(ptr) nounwind readonly
+declare i32 @llvm.eh.typeid.for.p0(ptr) nounwind readonly
 
 declare ptr @__cxa_begin_catch(ptr) nounwind
 
@@ -32,11 +32,11 @@ define void @_Z3foov() uwtable personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:            catch ptr @_ZTIb
 ; CHECK-NEXT:    [[EXC_PTR2_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
 ; CHECK-NEXT:    [[FILTER3_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
-; CHECK-NEXT:    [[TYPEID_I:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+; CHECK-NEXT:    [[TYPEID_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID_I]]
 ; CHECK-NEXT:    br i1 [[TMP1]], label [[PPAD:%.*]], label [[NEXT:%.*]]
 ; CHECK:       next:
-; CHECK-NEXT:    [[TYPEID1_I:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
+; CHECK-NEXT:    [[TYPEID1_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID1_I]]
 ; CHECK-NEXT:    br i1 [[TMP2]], label [[PPAD2:%.*]], label [[NEXT2:%.*]]
 ; CHECK:       ppad:
@@ -77,12 +77,12 @@ lpad:                                             ; preds = %entry
   catch ptr @_ZTIb
   %exc_ptr2.i = extractvalue { ptr, i32 } %0, 0
   %filter3.i = extractvalue { ptr, i32 } %0, 1
-  %typeid.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+  %typeid.i = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
   %1 = icmp eq i32 %filter3.i, %typeid.i
   br i1 %1, label %ppad, label %next
 
 next:                                             ; preds = %lpad
-  %typeid1.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
+  %typeid1.i = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
   %2 = icmp eq i32 %filter3.i, %typeid1.i
   br i1 %2, label %ppad2, label %next2
 
@@ -98,12 +98,12 @@ ppad2:                                            ; preds = %next
 
 next2:                                            ; preds = %next
   call void @_Z7cleanupv()
-  %typeid = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
+  %typeid = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
   %4 = icmp eq i32 %filter3.i, %typeid
   br i1 %4, label %ppad3, label %next3
 
 next3:                                            ; preds = %next2
-  %typeid1 = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
+  %typeid1 = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
   %5 = icmp eq i32 %filter3.i, %typeid1
   br i1 %5, label %ppad4, label %unwind
 
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index a52cca3c95dee..5bacd2dac591a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -635,7 +635,7 @@ def LLVM_VaEndOp : LLVM_ZeroResultIntrOp<"vaend", [0]>,
 // Exception handling intrinsics.
 //
 
-def LLVM_EhTypeidForOp : LLVM_OneResultIntrOp<"eh.typeid.for"> {
+def LLVM_EhTypeidForOp : LLVM_OneResultIntrOp<"eh.typeid.for", [], [0]> {
     let arguments = (ins LLVM_AnyPointer:$type_info);
     let assemblyFormat = "$type_info attr-dict `:` functional-type(operands, results)";
 }
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index bf6847a32ff4f..5882d6c2c8dfc 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -732,7 +732,7 @@ define void @coro_promise(ptr %0, i32 %1, i1 %2) {
 ; CHECK-LABEL:  llvm.func @eh_typeid_for
 define void @eh_typeid_for(ptr %0) {
   ; CHECK: llvm.intr.eh.typeid.for %{{.*}} : (!llvm.ptr) -> i32
-  %2 = call i32 @llvm.eh.typeid.for(ptr %0)
+  %2 = call i32 @llvm.eh.typeid.for.p0(ptr %0)
   ret void
 }
 
@@ -1073,7 +1073,7 @@ declare i1 @llvm.coro.end(ptr, i1, token)
 declare ptr @llvm.coro.free(token, ptr nocapture readonly)
 declare void @llvm.coro.resume(ptr)
 declare ptr @llvm.coro.promise(ptr nocapture, i32, i1)
-declare i32 @llvm.eh.typeid.for(ptr)
+declare i32 @llvm.eh.typeid.for.p0(ptr)
 declare ptr @llvm.stacksave.p0()
 declare ptr addrspace(1) @llvm.stacksave.p1()
 declare void @llvm.stackrestore.p0(ptr)
diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index db5184a63d983..d2a131b568e41 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -724,7 +724,7 @@ llvm.func @coro_promise(%arg0: !llvm.ptr, %arg1 : i32, %arg2 : i1) {
 
 // CHECK-LABEL: @eh_typeid_for
 llvm.func @eh_typeid_for(%arg0 : !llvm.ptr) {
-    // CHECK: call i32 @llvm.eh.typeid.for
+    // CHECK: call i32 @llvm.eh.typeid.for.p0
     %0 = llvm.intr.eh.typeid.for %arg0 : (!llvm.ptr) -> i32
     llvm.return
 }

>From c64150fd2e6a15b66b0eb3524674fcf24d99755a Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Sun, 28 Apr 2024 22:54:30 +0100
Subject: [PATCH 13/15] Reword comment.

---
 clang/lib/CodeGen/CGExprCXX.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index b51e41cb5c7aa..f3de6bc58663d 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2216,11 +2216,11 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
-  // TODO: ideally, we would like to use GlobalsInt8PtrTy here, however, we
-  //       cannot, primarily because the result of applying typeid is a value of
-  //       type type_info, which is declared & defined by the standard library
-  //       implementation and expects to operate on the generic (default) AS.
-  //       https://reviews.llvm.org/D157452 has more context.
+  // Ideally, we would like to use GlobalsInt8PtrTy here, however, we cannot,
+  // primarily because the result of applying typeid is a value of type
+  // type_info, which is declared & defined by the standard library
+  // implementation and expects to operate on the generic (default) AS.
+  // https://reviews.llvm.org/D157452 has more context, and a possible solution.
   llvm::Type *PtrTy = Int8PtrTy;
   LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
 

>From 2336c75b51e7029b32e1795a15b298caa9cd2a41 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Sun, 28 Apr 2024 23:23:36 +0100
Subject: [PATCH 14/15] Fix formatting.

---
 clang/lib/CodeGen/CGException.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 8ccb44eee8427..8acda3f2eb864 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1053,7 +1053,7 @@ static void emitWasmCatchPadBlock(CodeGenFunction &CGF,
   llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
 
   llvm::Function *TypeIDFn =
-    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
+      CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
 
   // If there's only a single catch-all, branch directly to its handler.
   if (CatchScope.getNumHandlers() == 1 &&
@@ -1138,7 +1138,7 @@ static void emitCatchDispatchBlock(CodeGenFunction &CGF,
 
   // Select the right handler.
   llvm::Function *llvm_eh_typeid_for =
-    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
+      CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
   llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
   LangAS globAS = CGF.CGM.GetGlobalVarAddressSpace(nullptr);
 

>From db6b04c4ff5272728cb74652d6aa00a96142f8fa Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 7 May 2024 09:52:42 +0300
Subject: [PATCH 15/15] Compact test.

---
 .../vtable-assume-load-address-space.cpp      | 110 ++++---
 ...ume-load-nonzero-default-address-space.cpp | 288 ------------------
 2 files changed, 67 insertions(+), 331 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp

diff --git a/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp b/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp
index d765fe94d9b08..ecafa99d8be00 100644
--- a/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp
+++ b/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp
@@ -1,14 +1,17 @@
 // RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
 // FIXME: Assume load should not require -fstrict-vtable-pointers
 
 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
 // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
 // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
 // RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
 // RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK9 --input-file=%t.ll %s
 namespace test1 {
 
 struct A {
@@ -23,8 +26,8 @@ struct B : A {
 void g(A *a) { a->foo(); }
 
 // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv()
-// CHECK1: call void @_ZN5test11AC1Ev(ptr
-// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
+// CHECK1: call{{.*}} void @_ZN5test11AC1Ev(ptr {{((addrspace(4)){0,1})}}
+// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
 // CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, i32 0, i32 2)
 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
 // CHECK1-LABEL: {{^}}}
@@ -35,8 +38,8 @@ void fooA() {
 }
 
 // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv()
-// CHECK1: call void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}})
-// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
+// CHECK1: call{{.*}} void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}})
+// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
 // CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, i32 0, i32 2)
 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
 // CHECK1-LABEL: {{^}}}
@@ -46,7 +49,7 @@ void fooB() {
   g(&b);
 }
 // there should not be any assumes in the ctor that calls base ctor
-// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(ptr
+// CHECK1-LABEL: define linkonce_odr{{.*}} void @_ZN5test11BC2Ev(ptr
 // CHECK1-NOT: @llvm.assume(
 // CHECK1-LABEL: {{^}}}
 }
@@ -69,17 +72,17 @@ void g(A *a) { a->foo(); }
 void h(B *b) { b->bar(); }
 
 // CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv()
-// CHECK2: call void @_ZN5test21CC1Ev(ptr
+// CHECK2: call{{.*}} void @_ZN5test21CC1Ev(ptr
 // CHECK2: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{.*}}
 // CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 0, i32 2)
 // CHECK2: call void @llvm.assume(i1 %[[CMP]])
 
-// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 8
-// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %[[ADD_PTR]]
+// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}, i64 8
+// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%[[ADD_PTR]]
 // CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 1, i32 2)
 // CHECK2: call void @llvm.assume(i1 %[[CMP2]])
 
-// CHECK2: call void @_ZN5test21gEPNS_1AE(
+// CHECK2: call{{.*}} void @_ZN5test21gEPNS_1AE(
 // CHECK2-LABEL: {{^}}}
 
 void test() {
@@ -106,7 +109,7 @@ struct C : virtual A, B {
 void g(B *a) { a->foo(); }
 
 // CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv()
-// CHECK3: call void @_ZN5test31CC1Ev(ptr
+// CHECK3: call{{.*}} void @_ZN5test31CC1Ev(ptr
 // CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, i32 0, i32 3)
 // CHECK3: call void @llvm.assume(i1 %[[CMP]])
 // CHECK3-LABLEL: }
@@ -134,12 +137,12 @@ struct C : B {
 void g(C *c) { c->foo(); }
 
 // CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv()
-// CHECK4: call void @_ZN5test41CC1Ev(ptr
-// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
+// CHECK4: call{{.*}} void @_ZN5test41CC1Ev(ptr
+// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
 // CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
 // CHECK4: call void @llvm.assume(i1 %[[CMP]]
 
-// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %{{.*}}
+// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
 // CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
 // CHECK4: call void @llvm.assume(i1 %[[CMP2]])
 // CHECK4-LABEL: {{^}}}
@@ -150,6 +153,27 @@ void test() {
 }
 } // test4
 
+namespace testMS {
+
+struct __declspec(novtable) S {
+  virtual void foo();
+};
+
+void g(S &s) { s.foo(); }
+
+// if struct has novtable specifier, then we can't generate assumes
+// CHECK-MS-LABEL: define dso_local void @"?test at testMS@@YAXXZ"()
+// CHECK-MS: call x86_thiscallcc noundef ptr @"??0S at testMS@@QAE at XZ"(
+// CHECK-MS-NOT: @llvm.assume
+// CHECK-MS-LABEL: {{^}}}
+
+void test() {
+  S s;
+  g(s);
+}
+
+} // testMS
+
 namespace test6 {
 struct A {
   A();
@@ -161,17 +185,17 @@ struct B : A {
 };
 // FIXME: Because A's vtable is external, and no virtual functions are hidden,
 // it's safe to generate assumption loads.
-// CHECK5-LABEL: define{{.*}} void @_ZN5test61gEv()
-// CHECK5: call void @_ZN5test61AC1Ev(
-// CHECK5-NOT: call void @llvm.assume(
+// CHECK6-LABEL: define{{.*}} void @_ZN5test61gEv()
+// CHECK6: call{{.*}} void @_ZN5test61AC1Ev(
+// CHECK6-NOT: call void @llvm.assume(
 
 // We can't emit assumption loads for B, because if we would refer to vtable
 // it would refer to functions that will not be able to find (like implicit
 // inline destructor).
 
-// CHECK5-LABEL:   call void @_ZN5test61BC1Ev(
-// CHECK5-NOT: call void @llvm.assume(
-// CHECK5-LABEL: {{^}}}
+// CHECK6-LABEL:   call{{.*}} void @_ZN5test61BC1Ev(
+// CHECK6-NOT: call void @llvm.assume(
+// CHECK6-LABEL: {{^}}}
 void g() {
   A *a = new A;
   B *b = new B;
@@ -180,7 +204,7 @@ void g() {
 
 namespace test7 {
 // Because A's key function is defined here, vtable is generated in this TU
-// CHECK6: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
+// CHECK7: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
 struct A {
   A();
   virtual void foo();
@@ -188,10 +212,10 @@ struct A {
 };
 void A::foo() {}
 
-// CHECK6-LABEL: define{{.*}} void @_ZN5test71gEv()
-// CHECK6: call void @_ZN5test71AC1Ev(
-// CHECK6: call void @llvm.assume(
-// CHECK6-LABEL: {{^}}}
+// CHECK7-LABEL: define{{.*}} void @_ZN5test71gEv()
+// CHECK7: call{{.*}} void @_ZN5test71AC1Ev(
+// CHECK7: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
 void g() {
   A *a = new A();
   a->bar();
@@ -205,14 +229,14 @@ struct A {
   virtual void bar();
 };
 
-// CHECK7-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
+// CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
 struct B : A {
   B();
   void foo();
   void bar();
 };
 
-// CHECK7-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
+// CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
 struct C : A {
   C();
   void bar();
@@ -227,14 +251,14 @@ struct D : A {
 };
 void D::bar() {}
 
-// CHECK7-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
+// CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
 struct E : A {
   E();
 };
 
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81bEv()
-// CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
+// CHECK8-LABEL: define{{.*}} void @_ZN5test81bEv()
+// CHECK8: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
 void b() {
   B b;
   b.bar();
@@ -243,26 +267,26 @@ void b() {
 // FIXME: C has inline virtual functions which prohibits as from generating
 // assumption loads, but because vtable is generated in this TU (key function
 // defined here) it would be correct to refer to it.
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81cEv()
-// CHECK7-NOT: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
+// CHECK8-LABEL: define{{.*}} void @_ZN5test81cEv()
+// CHECK8-NOT: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
 void c() {
   C c;
   c.bar();
 }
 
 // FIXME: We could generate assumption loads here.
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81dEv()
-// CHECK7-NOT: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
+// CHECK8-LABEL: define{{.*}} void @_ZN5test81dEv()
+// CHECK8-NOT: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
 void d() {
   D d;
   d.bar();
 }
 
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81eEv()
-// CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
+// CHECK8-LABEL: define{{.*}} void @_ZN5test81eEv()
+// CHECK8: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
 void e() {
   E e;
   e.bar();
@@ -276,9 +300,9 @@ struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
 };
 
-// CHECK8-LABEL: define{{.*}} void @_ZN5test94testEv()
-// CHECK8-NOT: @llvm.assume(
-// CHECK8: }
+// CHECK9-LABEL: define{{.*}} void @_ZN5test94testEv()
+// CHECK9-NOT: @llvm.assume(
+// CHECK9: }
 void test() {
   S *s = new S();
   s->doStuff();
diff --git a/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp b/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp
deleted file mode 100644
index 63e7bb8b570a6..0000000000000
--- a/clang/test/CodeGenCXX/vtable-assume-load-nonzero-default-address-space.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
-// FIXME: Assume load should not require -fstrict-vtable-pointers
-
-// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
-// RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
-namespace test1 {
-
-struct A {
-  A();
-  virtual void foo();
-};
-
-struct B : A {
-  virtual void foo();
-};
-
-void g(A *a) { a->foo(); }
-
-// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv()
-// CHECK1: call{{.*}} void @_ZN5test11AC1Ev(ptr addrspace(4)
-// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, i32 0, i32 2)
-// CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: {{^}}}
-
-void fooA() {
-  A a;
-  g(&a);
-}
-
-// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv()
-// CHECK1: call{{.*}} void @_ZN5test11BC1Ev(ptr addrspace(4) {{[^,]*}} %{{.*}})
-// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
-// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, i32 0, i32 2)
-// CHECK1: call void @llvm.assume(i1 %[[CMP]])
-// CHECK1-LABEL: {{^}}}
-
-void fooB() {
-  B b;
-  g(&b);
-}
-// there should not be any assumes in the ctor that calls base ctor
-// CHECK1-LABEL: define linkonce_odr{{.*}} void @_ZN5test11BC2Ev(ptr addrspace(4)
-// CHECK1-NOT: @llvm.assume(
-// CHECK1-LABEL: {{^}}}
-}
-namespace test2 {
-struct A {
-  A();
-  virtual void foo();
-};
-
-struct B {
-  B();
-  virtual void bar();
-};
-
-struct C : A, B {
-  C();
-  virtual void foo();
-};
-void g(A *a) { a->foo(); }
-void h(B *b) { b->bar(); }
-
-// CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv()
-// CHECK2: call{{.*}} void @_ZN5test21CC1Ev(ptr
-// CHECK2: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) {{.*}}
-// CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 0, i32 2)
-// CHECK2: call void @llvm.assume(i1 %[[CMP]])
-
-// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 8
-// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr addrspace(4) %[[ADD_PTR]]
-// CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 1, i32 2)
-// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
-
-// CHECK2: call{{.*}} void @_ZN5test21gEPNS_1AE(ptr addrspace(4)
-// CHECK2-LABEL: {{^}}}
-
-void test() {
-  C c;
-  g(&c);
-  h(&c);
-}
-}
-
-namespace test3 {
-struct A {
-  A();
-};
-
-struct B : A {
-  B();
-  virtual void foo();
-};
-
-struct C : virtual A, B {
-  C();
-  virtual void foo();
-};
-void g(B *a) { a->foo(); }
-
-// CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv()
-// CHECK3: call{{.*}} void @_ZN5test31CC1Ev(ptr addrspace(4)
-// CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, i32 0, i32 3)
-// CHECK3: call void @llvm.assume(i1 %[[CMP]])
-// CHECK3-LABLEL: }
-void test() {
-  C c;
-  g(&c);
-}
-} // test3
-
-namespace test4 {
-struct A {
-  A();
-  virtual void foo();
-};
-
-struct B : virtual A {
-  B();
-  virtual void foo();
-};
-struct C : B {
-  C();
-  virtual void foo();
-};
-
-void g(C *c) { c->foo(); }
-
-// CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv()
-// CHECK4: call{{.*}} void @_ZN5test41CC1Ev(ptr addrspace(4)
-// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
-// CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
-// CHECK4: call void @llvm.assume(i1 %[[CMP]]
-
-// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr addrspace(4) %{{.*}}
-// CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
-// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
-// CHECK4-LABEL: {{^}}}
-
-void test() {
-  C c;
-  g(&c);
-}
-} // test4
-
-namespace test6 {
-struct A {
-  A();
-  virtual void foo();
-  virtual ~A() {}
-};
-struct B : A {
-  B();
-};
-// FIXME: Because A's vtable is external, and no virtual functions are hidden,
-// it's safe to generate assumption loads.
-// CHECK5-LABEL: define{{.*}} void @_ZN5test61gEv()
-// CHECK5: call{{.*}} void @_ZN5test61AC1Ev(ptr addrspace(4)
-// CHECK5-NOT: call void @llvm.assume(
-
-// We can't emit assumption loads for B, because if we would refer to vtable
-// it would refer to functions that will not be able to find (like implicit
-// inline destructor).
-
-// CHECK5-LABEL:   call{{.*}} void @_ZN5test61BC1Ev(ptr addrspace(4)
-// CHECK5-NOT: call void @llvm.assume(
-// CHECK5-LABEL: {{^}}}
-void g() {
-  A *a = new A;
-  B *b = new B;
-}
-}
-
-namespace test7 {
-// Because A's key function is defined here, vtable is generated in this TU
-// CHECK6: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
-struct A {
-  A();
-  virtual void foo();
-  virtual void bar();
-};
-void A::foo() {}
-
-// CHECK6-LABEL: define{{.*}} void @_ZN5test71gEv()
-// CHECK6: call{{.*}} void @_ZN5test71AC1Ev(ptr addrspace(4)
-// CHECK6: call void @llvm.assume(
-// CHECK6-LABEL: {{^}}}
-void g() {
-  A *a = new A();
-  a->bar();
-}
-}
-
-namespace test8 {
-
-struct A {
-  virtual void foo();
-  virtual void bar();
-};
-
-// CHECK7-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
-struct B : A {
-  B();
-  void foo();
-  void bar();
-};
-
-// CHECK7-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
-struct C : A {
-  C();
-  void bar();
-  void foo() {}
-};
-inline void C::bar() {}
-
-struct D : A {
-  D();
-  void foo();
-  void inline bar();
-};
-void D::bar() {}
-
-// CHECK7-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
-struct E : A {
-  E();
-};
-
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81bEv()
-// CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
-void b() {
-  B b;
-  b.bar();
-}
-
-// FIXME: C has inline virtual functions which prohibits as from generating
-// assumption loads, but because vtable is generated in this TU (key function
-// defined here) it would be correct to refer to it.
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81cEv()
-// CHECK7-NOT: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
-void c() {
-  C c;
-  c.bar();
-}
-
-// FIXME: We could generate assumption loads here.
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81dEv()
-// CHECK7-NOT: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
-void d() {
-  D d;
-  d.bar();
-}
-
-// CHECK7-LABEL: define{{.*}} void @_ZN5test81eEv()
-// CHECK7: call void @llvm.assume(
-// CHECK7-LABEL: {{^}}}
-void e() {
-  E e;
-  e.bar();
-}
-}
-
-namespace test9 {
-
-struct S {
-  S();
-  __attribute__((visibility("hidden"))) virtual void doStuff();
-};
-
-// CHECK8-LABEL: define{{.*}} void @_ZN5test94testEv()
-// CHECK8-NOT: @llvm.assume(
-// CHECK8: }
-void test() {
-  S *s = new S();
-  s->doStuff();
-  delete s;
-}
-}
-



More information about the Mlir-commits mailing list