Restore unnamed_addr on vtables in -fno-rtti builds#201846
Conversation
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Hans Wennborg (zmodem) ChangesThis is a follow-up to #200108 which dropped unnamed_addr from vtables since it can break dynamic_cast under some circumstances. However, that caused significant binary size regressions due to preventing ICF of vtables. This patch restores unnamed_addr on vtables in -fno-rtti builds, since those do not support dynamic_cast, recovering the binary size savings at least for those using that configuration. Patch is 47.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/201846.diff 17 Files Affected:
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 40abf4570f219..4b8514e4e2bc1 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -987,6 +987,11 @@ llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
+ // dynamic_cast assumes the vtable address is unique; see
+ // https://github.com/llvm/llvm-project/pull/200108
+ if (!CGM.shouldEmitRTTI())
+ VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+
llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
CGM.getContext().getCanonicalTagType(Base.getBase()));
@@ -1070,6 +1075,7 @@ void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
assert(VTableAlias->getLinkage() == Linkage);
}
VTableAlias->setVisibility(VTable->getVisibility());
+ VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
// Both of these will now imply dso_local for the vtable.
if (!VTable->hasComdat()) {
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 3c6b2b1227d6c..b4b3284f752ae 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2258,6 +2258,8 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
Name, VTableType, llvm::GlobalValue::ExternalLinkage,
getContext().toCharUnitsFromBits(PAlign).getAsAlign());
+ if (!CGM.shouldEmitRTTI())
+ VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
if (CGM.getTarget().hasPS4DLLImportExport())
setVTableSelectiveDLLImportExport(CGM, VTable, RD);
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index ad2c201bc2518..40c7c00d85395 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1941,6 +1941,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
VTable = new llvm::GlobalVariable(CGM.getModule(), VTableType,
/*isConstant=*/true, VTableLinkage,
/*Initializer=*/nullptr, VTableName);
+ if (!CGM.shouldEmitRTTI())
+ VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
llvm::Comdat *C = nullptr;
if (!VFTableComesFromAnotherTU &&
@@ -1967,6 +1969,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
/*AddressSpace=*/0, VFTableLinkage,
VFTableName.str(), VTableGEP,
&CGM.getModule());
+ if (!CGM.shouldEmitRTTI())
+ VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
} else {
// We don't need a GlobalAlias to be a symbol for the VTable if we won't
// be referencing any RTTI data.
diff --git a/clang/test/CodeGenCUDA/increment-index-for-thunks.cu b/clang/test/CodeGenCUDA/increment-index-for-thunks.cu
index 2d8cc3c29009b..48dbf6ef82b7d 100644
--- a/clang/test/CodeGenCUDA/increment-index-for-thunks.cu
+++ b/clang/test/CodeGenCUDA/increment-index-for-thunks.cu
@@ -3,12 +3,12 @@
// RUN: %clang_cc1 -fcuda-is-device -triple spirv64-amd-amdhsa \
// RUN: -emit-llvm -xhip %s -o - | FileCheck %s --check-prefix=SPIRV
-// GCN: @_ZTV1C = linkonce_odr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
-// GCN: @_ZTV1B = linkonce_odr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
-// GCN: @_ZTV1A = linkonce_odr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
-// SPIRV: @_ZTV1C = linkonce_odr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
-// SPIRV: @_ZTV1B = linkonce_odr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
-// SPIRV: @_ZTV1A = linkonce_odr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
+// GCN: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
+// GCN: @_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) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
+// GCN: @_ZTV1A = linkonce_odr unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
+// SPIRV: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
+// SPIRV: @_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) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
+// SPIRV: @_ZTV1A = linkonce_odr unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
struct A {
__attribute__((device)) A() { }
diff --git a/clang/test/CodeGenCUDA/record-layout.cu b/clang/test/CodeGenCUDA/record-layout.cu
index 9a1950509b8c8..4e27321452ee7 100644
--- a/clang/test/CodeGenCUDA/record-layout.cu
+++ b/clang/test/CodeGenCUDA/record-layout.cu
@@ -48,8 +48,8 @@ struct C : A, B {
// HOST: @"??_7J@@6B@" = alias ptr, getelementptr inbounds ({ [4 x ptr] }, ptr @0, i32 0, i32 0, i32 1)
// HOST: @"??_7I@@6B@" = alias ptr, getelementptr inbounds ({ [4 x ptr] }, ptr @1, i32 0, i32 0, i32 1)
-// DEV: @_ZTV1J = linkonce_odr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1J1gEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1J1hEv to ptr addrspace(1))] }, comdat, align 8
-// DEV: @_ZTV1I = linkonce_odr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
+// DEV: @_ZTV1J = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1J1gEv to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN1J1hEv to ptr addrspace(1))] }, comdat, align 8
+// DEV: @_ZTV1I = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
struct I {
virtual void f() = 0;
__device__ virtual void g() = 0;
diff --git a/clang/test/CodeGenCXX/OmitRTTIComponentABI/simple-vtable-definition.cpp b/clang/test/CodeGenCXX/OmitRTTIComponentABI/simple-vtable-definition.cpp
index aa6357c59ced4..75fd72af11d72 100644
--- a/clang/test/CodeGenCXX/OmitRTTIComponentABI/simple-vtable-definition.cpp
+++ b/clang/test/CodeGenCXX/OmitRTTIComponentABI/simple-vtable-definition.cpp
@@ -10,9 +10,9 @@
/// - A virtual function
///
/// Now vtables should have just two components.
-// POINTER: @_ZTV1A = constant { [2 x ptr] } { [2 x ptr] [ptr null, ptr @_ZN1A3fooEv] }, align 8
-// RELATIVE: @_ZTV1A.local = internal constant { [2 x i32] } { [2 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [2 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 1) to i64)) to i32)] }, align 4
-// RELATIVE: @_ZTV1A = alias { [2 x i32] }, ptr @_ZTV1A.local
+// POINTER: @_ZTV1A = unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr null, ptr @_ZN1A3fooEv] }, align 8
+// RELATIVE: @_ZTV1A.local = internal unnamed_addr constant { [2 x i32] } { [2 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [2 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 1) to i64)) to i32)] }, align 4
+// RELATIVE: @_ZTV1A = unnamed_addr alias { [2 x i32] }, ptr @_ZTV1A.local
/// None of these supplementary symbols should be emitted with -fno-rtti, but
/// as a sanity check lets make sure they're not emitted also.
diff --git a/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
index fb9d87f03370f..d615b5516b752 100644
--- a/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
+++ b/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -disable-O0-optnone -emit-llvm -o - %s | FileCheck %s
-// CHECK: @_ZTV5TemplIiE = internal constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr @_ZN5TemplIiED1Ev, ptr @_ZN5TemplIiED0Ev, ptr @_ZN5TemplIiE1fEv, ptr @_ZN5TemplIiE1gEv, ptr null] }
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr @_ZN5TemplIiED1Ev, ptr @_ZN5TemplIiED0Ev, ptr @_ZN5TemplIiE1fEv, ptr @_ZN5TemplIiE1gEv, ptr null] }
struct B1 {
virtual ~B1();
diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp
index 86fe7561f4c4e..ed1c72c5185d3 100644
--- a/clang/test/CodeGenCXX/dllimport.cpp
+++ b/clang/test/CodeGenCXX/dllimport.cpp
@@ -673,16 +673,16 @@ USEMEMFUNC(V, foo)
struct __declspec(dllimport) W { virtual void foo() {} };
USECLASS(W)
// vftable:
-// MO1-DAG: @"??_SW@@6B@" = linkonce_odr constant { [1 x ptr] } { [1 x ptr] [ptr @"?foo@W@@UAEXXZ"] }
-// GO1-DAG: @_ZTV1W = available_externally dllimport constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZN1W3fooEv] }
+// MO1-DAG: @"??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"?foo@W@@UAEXXZ"] }
+// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZN1W3fooEv] }
struct __declspec(dllimport) KeyFuncClass {
constexpr KeyFuncClass() {}
virtual void foo();
};
extern constexpr KeyFuncClass keyFuncClassVar = {};
-// G32-DAG: @_ZTV12KeyFuncClass = external dllimport constant { [3 x ptr] }
-// C32-DAG: @_ZTV12KeyFuncClass = external dllimport constant { [3 x ptr] }
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }
+// C32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }
struct __declspec(dllimport) X : public virtual W {};
USECLASS(X)
@@ -788,7 +788,7 @@ namespace PR21355 {
// S::~S is a key function, so we would ordinarily emit a strong definition for
// the vtable. However, S is imported, so the vtable should be too.
- // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport constant { [4 x ptr] }
+ // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x ptr] }
}
namespace PR21366 {
@@ -810,7 +810,7 @@ namespace PR27319 {
};
extern template struct __declspec(dllimport) A<int>;
void f() { new A<int>(); }
- // MO1-DAG: @"??_S?$A@H@PR27319@@6B@" = linkonce_odr constant { [1 x ptr] }
+ // MO1-DAG: @"??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] }
}
// MS ignores DLL attributes on partial specializations.
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp b/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
index d00019aaa04d4..c707a286b5129 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -11,7 +11,7 @@ struct S {
// RTTI-DAG: [[VTABLE_S:@.*]] = private constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4S@@6B@", ptr @"??_ES@@UAEPAXI@Z"] }, comdat($"??_7S@@6B@")
// RTTI-DAG: @"??_7S@@6B@" = alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_S]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_7S@@6B@" = linkonce_odr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_ES@@UAEPAXI@Z"] }
+// NO-RTTI-DAG: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_ES@@UAEPAXI@Z"] }
struct __declspec(dllimport) U {
virtual ~U();
@@ -20,7 +20,7 @@ struct __declspec(dllimport) U {
// RTTI-DAG: [[VTABLE_U:@.*]] = private constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4U@@6B@", ptr @"??_EU@@UAEPAXI@Z"] }
// RTTI-DAG: @"??_SU@@6B@" = alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_U]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_SU@@6B@" = linkonce_odr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EU@@UAEPAXI@Z"] }
+// NO-RTTI-DAG: @"??_SU@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EU@@UAEPAXI@Z"] }
struct __declspec(dllexport) V {
virtual ~V();
@@ -29,7 +29,7 @@ struct __declspec(dllexport) V {
// RTTI-DAG: [[VTABLE_V:@.*]] = private constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4V@@6B@", ptr @"??_EV@@UAEPAXI@Z"] }, comdat($"??_7V@@6B@")
// RTTI-DAG: @"??_7V@@6B@" = dllexport alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_V]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_7V@@6B@" = weak_odr dllexport constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EV@@UAEPAXI@Z"] }
+// NO-RTTI-DAG: @"??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EV@@UAEPAXI@Z"] }
namespace {
struct W {
@@ -39,7 +39,7 @@ struct W {
// RTTI-DAG: [[VTABLE_W:@.*]] = private constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4W@?A0x{{[^@]*}}@@6B@", ptr @"??_EW@?A0x{{[^@]*}}@@UAEPAXI@Z"] }
// RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_W]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EW@?A0x{{[^@]*}}@@UAEPAXI@Z"] }
+// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_EW@?A0x{{[^@]*}}@@UAEPAXI@Z"] }
struct X {};
template <class> struct Y : virtual X {
@@ -52,4 +52,4 @@ template Y<int>::Y();
// RTTI-DAG: [[VTABLE_Y:@.*]] = private constant { [2 x ptr] } { [2 x ptr] [ptr @"??_R4?$Y@H@@6B@", ptr @"??_E?$Y@H@@UAEPAXI@Z"] }, comdat($"??_7?$Y@H@@6B@")
// RTTI-DAG: @"??_7?$Y@H@@6B@" = alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr [[VTABLE_Y]], i32 0, i32 0, i32 1)
-// NO-RTTI-DAG: @"??_7?$Y@H@@6B@" = linkonce_odr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_E?$Y@H@@UAEPAXI@Z"] }, comdat
+// NO-RTTI-DAG: @"??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"??_E?$Y@H@@UAEPAXI@Z"] }, comdat
diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
index ffd4d20fb758a..1a589370d3a74 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -26,7 +26,7 @@ J::J() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
// VFTABLES-NEXT: 2 | D *test1::J::foo()
-// GLOBALS-LABEL: @"??_7J@test1@@6B@" = linkonce_odr constant { [3 x ptr] }
+// GLOBALS-LABEL: @"??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant { [3 x ptr] }
// GLOBALS: @"?foo@J@test1@@QAEPAUB@2@XZ"
// GLOBALS: @"?foo@J@test1@@QAEPAUC@2@XZ"
// GLOBALS: @"?foo@J@test1@@UAEPAUD@2@XZ"
@@ -44,7 +44,7 @@ K::K() {}
// Only B to C requires adjustment, but we get 3 thunks in K's vftable, two of
// which are trivial.
-// GLOBALS-LABEL: @"??_7K@test1@@6B@" = linkonce_odr constant { [4 x ptr] }
+// GLOBALS-LABEL: @"??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant { [4 x ptr] }
// GLOBALS: @"?foo@K@test1@@QAEPAUB@2@XZ"
// GLOBALS: @"?foo@K@test1@@QAEPAUC@2@XZ"
// GLOBALS: @"?foo@K@test1@@QAEPAUD@2@XZ"
@@ -90,7 +90,7 @@ J::J() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
// VFTABLES-NEXT: 1 | D *test2::J::foo()
-// GLOBALS-LABEL: @"??_7J@test2@@6B@" = linkonce_odr constant { [2 x ptr] }
+// GLOBALS-LABEL: @"??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant { [2 x ptr] }
K::K() {}
@@ -101,7 +101,7 @@ K::K() {}
// VFTABLES-NEXT: [return adjustment (to type 'struct test2::D *'): 0 non-virtual]
// VFTABLES-NEXT: 2 | E *test2::K::foo()
-// GLOBALS-LABEL: @"??_7K@test2@@6B@" = linkonce_odr constant { [3 x ptr] }
+// GLOBALS-LABEL: @"??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant { [3 x ptr] }
}
@@ -124,7 +124,7 @@ struct C : virtual A, B {
C::C() {}
-// GLOBALS-LABEL: @"??_7C@pr20479@@6B@" = linkonce_odr constant { [2 x ptr] }
+// GLOBALS-LABEL: @"??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant { [2 x ptr] }
// GLOBALS: @"?f@B@pr20479@@QAEPAUA@2@XZ"
// GLOBALS: @"?f@B@pr20479@@UAEPAU12@XZ"
}
@@ -151,7 +151,7 @@ struct C : virtual A, virtual B {
C::C() {}
-// GLOBALS-LABEL: @"??_7C@pr21073@@6B@" = linkonce_odr constant { [2 x ptr] }
+// GLOBALS-LABEL: @"??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant { [2 x ptr] }
// GLOBALS: @"?f@B@pr21073@@WPPPPPPPI@AEPAUA@2@XZ"
// GLOBALS: @"?f@B@pr21073@@WPPPPPPPI@AEPAU12@XZ"
}
@@ -168,7 +168,7 @@ D...
[truncated]
|
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
alanzhao1
left a comment
There was a problem hiding this comment.
LGTM but someone else should also approve.
This is a follow-up to #200108 which dropped unnamed_addr from vtables since it can break dynamic_cast under some circumstances. However, that caused significant binary size regressions due to preventing ICF of vtables.
This patch restores unnamed_addr on vtables in -fno-rtti builds, since those do not support dynamic_cast, recovering the binary size savings at least for those using that configuration.