Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -332,6 +332,11 @@ // COMDAT key is required for correctness. AddGlobalCtor(Fn, 65535, Addr); DelayedCXXInitPosition.erase(D); + } else if (D->hasAttr()) { + // SelectAny globals will be comdat-folded. Put the initializer into a COMDAT + // group associated with the global, so the initializers get folded too. + AddGlobalCtor(Fn, 65535, Addr); + DelayedCXXInitPosition.erase(D); } else { llvm::DenseMap::iterator I = DelayedCXXInitPosition.find(D); Index: test/CodeGenCXX/microsoft-abi-static-initializers.cpp =================================================================== --- test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s -// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] -// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ", -// CHECK: i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) }, -// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }] +// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [ +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S* @"\01?selectany1@@3US@@A", i32 0, i32 0) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S* @"\01?selectany2@@3US@@A", i32 0, i32 0) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ", i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null } +// CHECK: ] struct S { S(); @@ -21,8 +23,8 @@ // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ" // CHECK: ret void -// These globals should use distinct guard variables, and not different bits of -// the same global. +// These globals should have initializers comdat associative with the global. +// See @llvm.global_ctors above. __declspec(selectany) S selectany1; __declspec(selectany) S selectany2; // CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"()