There is quiet a bit of history behind this.

The llvm IR until very recently had no support for comdats. This was a
problem when targeting C++ on ELF/COFF as just using weak linkage
would cause quiet a bit of dead bits to remain on the executable
(unless -ffunction-sections, -fdata-sections and --gc-sections were
used).

To fix the problem, llvm's codegen will just assume that any weak or
linkonce that is not in an explicit comdat should be output in one
with the same name as the global.

This unfortunately breaks cases like pr19848 where a weak symbol is
not expected to be part of any comdat.

Now that we have explicit comdats in the IR, we can finally get both
cases right.

This first patch just makes clang give explicit comdats to
GlobalValues where it is allowed to.

A followup patch to llvm will then stop implicitly producing comdats.

Cheers,
Rafael
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 4a612c9..39052e5 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -206,6 +206,9 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
   GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
   setGlobalVisibility(GV, &D);
 
+  if (supportsCOMDAT() && GV->isWeakForLinker())
+    GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
+
   if (D.getTLSKind())
     setTLSMode(GV, D);
 
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index e002cdf..8500b56 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -267,15 +267,7 @@ void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
   addUsedGlobal(PtrArray);
 
   // If the GV is already in a comdat group, then we have to join it.
-  llvm::Comdat *C = GV->getComdat();
-
-  // LinkOnce and Weak linkage are lowered down to a single-member comdat group.
-  // Make an explicit group so we can join it.
-  if (!C && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())) {
-    C = TheModule.getOrInsertComdat(GV->getName());
-    GV->setComdat(C);
-  }
-  if (C)
+  if (llvm::Comdat *C = GV->getComdat())
     PtrArray->setComdat(C);
 }
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 25aaa30..a21aee3 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1910,6 +1910,30 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
     R.first->second = nullptr;
 }
 
+static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl *D) {
+  if (!CGM.supportsCOMDAT())
+    return false;
+
+  if (D->hasAttr<SelectAnyAttr>())
+    return true;
+
+  GVALinkage Linkage;
+  if (auto *VD = dyn_cast<VarDecl>(D))
+    Linkage = CGM.getContext().GetGVALinkageForVariable(VD);
+  else
+    Linkage = CGM.getContext().GetGVALinkageForFunction(cast<FunctionDecl>(D));
+
+  switch (Linkage) {
+  case GVA_Internal:
+  case GVA_AvailableExternally:
+  case GVA_StrongExternal:
+    return false;
+  case GVA_DiscardableODR:
+  case GVA_StrongODR:
+    return true;
+  }
+}
+
 void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
   llvm::Constant *Init = nullptr;
   QualType ASTTy = D->getType();
@@ -2053,6 +2077,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
     setTLSMode(GV, *D);
   }
 
+  if (shouldBeInCOMDAT(*this, D))
+    GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
+
   // Emit the initializer function if necessary.
   if (NeedsGlobalCtor || NeedsGlobalDtor)
     EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
@@ -2387,6 +2414,9 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
 
   MaybeHandleStaticInExternC(D, Fn);
 
+  if (shouldBeInCOMDAT(*this, D))
+    Fn->setComdat(TheModule.getOrInsertComdat(Fn->getName()));
+
   CodeGenFunction(*this).GenerateCode(D, Fn, FI);
 
   setFunctionDefinitionAttributes(D, Fn);
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index fd299d1..00f7971 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1709,12 +1709,14 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
     // If the variable is thread-local, so is its guard variable.
     guard->setThreadLocalMode(var->getThreadLocalMode());
 
+    if (CGM.supportsCOMDAT() && guard->isWeakForLinker())
+      guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
+
     // The ABI says: It is suggested that it be emitted in the same COMDAT group
     // as the associated data object
-    if (!D.isLocalVarDecl() && var->isWeakForLinker() && CGM.supportsCOMDAT()) {
-      llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName());
+    llvm::Comdat *C = var->getComdat();
+    if (!D.isLocalVarDecl() && C) {
       guard->setComdat(C);
-      var->setComdat(C);
       CGF.CurFn->setComdat(C);
     }
 
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 83ad22c..d016bd8 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1829,18 +1829,10 @@ void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
     llvm::Function *F = CXXThreadLocalInits[I];
 
     // If the GV is already in a comdat group, then we have to join it.
-    llvm::Comdat *C = GV->getComdat();
-
-    // LinkOnce and Weak linkage are lowered down to a single-member comdat
-    // group.
-    // Make an explicit group so we can join it.
-    if (!C && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())) {
-      C = CGM.getModule().getOrInsertComdat(GV->getName());
-      GV->setComdat(C);
+    if (llvm::Comdat *C = GV->getComdat())
       AddToXDU(F)->setComdat(C);
-    } else {
+    else
       NonComdatInits.push_back(F);
-    }
   }
 
   if (!NonComdatInits.empty()) {
diff --git a/test/CodeGen/attr-minsize.cpp b/test/CodeGen/attr-minsize.cpp
index 0f07725..f15fb90 100644
--- a/test/CodeGen/attr-minsize.cpp
+++ b/test/CodeGen/attr-minsize.cpp
@@ -43,16 +43,16 @@ void test4(T arg) {
 
 template
 void test4<int>(int arg);
-// Oz: define{{.*}}void @{{.*}}test4
+// Oz: define{{.*}}void @{{[^ ]*}}test4
 // Oz: [[MINSIZE]]
-// OTHER: define{{.*}}void @{{.*}}test4
+// OTHER: define{{.*}}void @{{[^ ]*}}test4
 // OTHER: [[MS]]
 
 template
 void test4<float>(float arg);
-// Oz: define{{.*}}void @{{.*}}test4
+// Oz: define{{.*}}void @{{[^ ]*}}test4
 // Oz: [[MINSIZE]]
-// OTHER: define{{.*}}void @{{.*}}test4
+// OTHER: define{{.*}}void @{{[^ ]*}}test4
 // OTHER: [[MS]]
 
 template<typename T>
@@ -62,17 +62,17 @@ void test5(T arg) {
 
 template
 void test5<int>(int arg);
-// Oz: define{{.*}}void @{{.*}}test5
+// Oz: define{{.*}}void @{{[^ ]*}}test5
 // Oz: [[MINSIZE]]
-// OTHER: define{{.*}}void @{{.*}}test5
-// OTHER-NOT: define{{.*}}void @{{.*}}test5{{.*}}[[MS]]
+// OTHER: define{{.*}}void @{{[^ ]*}}test5
+// OTHER-NOT: define{{.*}}void @{{[^ ]*}}test5{{.*}}[[MS]]
 
 template
 void test5<float>(float arg);
-// Oz: define{{.*}}void @{{.*}}test5
+// Oz: define{{.*}}void @{{[^ ]*}}test5
 // Oz: [[MINSIZE]]
-// OTHER: define{{.*}}void @{{.*}}test5
-// OTHER-NOT: define{{.*}}void @{{.*}}test5{{.*}}[[MS]]
+// OTHER: define{{.*}}void @{{[^ ]*}}test5
+// OTHER-NOT: define{{.*}}void @{{.*}}test5{{[^ ]*}}[[MS]]
 
 // Oz: attributes [[MINSIZE]] = { minsize{{.*}} }
 
diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c
index 5dc7787..e226c14 100644
--- a/test/CodeGen/ms-declspecs.c
+++ b/test/CodeGen/ms-declspecs.c
@@ -2,8 +2,8 @@
 
 __declspec(selectany) int x1 = 1;
 const __declspec(selectany) int x2 = 2;
-// CHECK: @x1 = weak_odr global i32 1, align 4
-// CHECK: @x2 = weak_odr constant i32 2, align 4
+// CHECK: @x1 = weak_odr global i32 1, comdat $x1, align 4
+// CHECK: @x2 = weak_odr constant i32 2, comdat $x2, align 4
 
 struct __declspec(align(16)) S {
   char x;
diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp
index 75f939f..02dab4b 100644
--- a/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -22,9 +22,9 @@ template<> void S<short>::f() { h(); }
 // CHECK: define {{.*}} @_ZN1SIA2_sE1fEv() [[NUW]]
 template<> void S<short[2]>::f() noexcept { h(); }
 
-// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] {
+// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] {{.*}} {
 template void f<char16_t>();
-// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]]  {
+// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] {{.*}} {
 template void f<char16_t[2]>();
 
 // CHECK: define {{.*}} @_ZN1SIDsE1fEv()
@@ -34,9 +34,9 @@ template void S<char16_t>::f();
 template void S<char16_t[2]>::f();
 
 void h() {
-  // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] {
+  // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] {{.*}} {
   f<int>();
-  // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] {
+  // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] {{.*}} {
   f<int[2]>();
 
   // CHECK: define {{.*}} @_ZN1SIiE1fEv() [[NUW]]
@@ -45,9 +45,9 @@ void h() {
   // CHECK-NOT: [[NUW]]
   S<int[2]>::f();
 
-  // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] {
+  // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] {{.*}} {
   void (*f1)() = &f<float>;
-  // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] {
+  // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] {{.*}} {
   void (*f2)() = &f<double>;
 
   // CHECK: define {{.*}} @_ZN1SIfE1fEv() [[NUW]]
@@ -56,9 +56,9 @@ void h() {
   // CHECK-NOT: [[NUW]]
   void (*f4)() = &S<double>::f;
 
-  // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] {
+  // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] {{.*}} {
   (void)&f<char[4]>;
-  // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] {
+  // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] {{.*}} {
   (void)&f<char>;
 
   // CHECK: define {{.*}} @_ZN1SIA4_cE1fEv() [[NUW]]
diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp
index d913c09..c7b8d47 100644
--- a/test/CodeGenCXX/dllexport-members.cpp
+++ b/test/CodeGenCXX/dllexport-members.cpp
@@ -110,9 +110,9 @@ public:
 
   // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA"               = dllexport global i32 1, align 4
   // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01?StaticConstFieldEqualInit@ExportMembers@@2HB", align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01?StaticConstFieldBraceInit@ExportMembers@@2HB", align 4
+  // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, comdat $"\01?ConstexprField@ExportMembers@@2HB", align 4
   // GNU-DAG: @_ZN13ExportMembers11StaticFieldE                   = dllexport global i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE              = dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
@@ -233,9 +233,9 @@ public:
 
   // MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA"               = dllexport global i32 1, align 4
   // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
-  // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB", align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB", align 4
+  // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, comdat $"\01?ConstexprField@Nested@ExportMembers@@2HB", align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE                   = dllexport global i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE              = dllexport constant i32 1, align 4
   // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
@@ -599,21 +599,21 @@ template<typename T> const int MemVarTmpl::StaticVar;
 template<typename T> const int MemVarTmpl::ExportedStaticVar;
 
 // Export implicit instantiation of an exported member variable template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB", align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, comdat $_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE, align 4
 int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
 
 // Export explicit instantiation declaration of an exported member variable
 // template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB", align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE       = weak_odr dllexport constant i32 1, comdat $_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE, align 4
 extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
        template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
 
 // Export explicit instantiation definition of an exported member variable
 // template.
-// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB", align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, comdat $_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE, align 4
 template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
 
 // Export specialization of an exported member variable template.
@@ -630,15 +630,15 @@ template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1
 
 // Export explicit instantiation declaration of a non-exported member variable
 // template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB", align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE        = weak_odr dllexport constant i32 1, comdat $_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE, align 4
 extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
        template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
 
 // Export explicit instantiation definition of a non-exported member variable
 // template.
-// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
-// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat $"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB", align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE        = weak_odr dllexport constant i32 1, comdat $_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE, align 4
 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
 
 // Export specialization of a non-exported member variable template.
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
index 0878dff..6482f1a 100644
--- a/test/CodeGenCXX/dllexport.cpp
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -110,43 +110,43 @@ template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
 USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
 
 // Export definition.
-// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE         = weak_odr dllexport global i32 1, comdat $_Z12VarTmplInit1I21ExplicitInst_ExportedE, align 4
 template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
 INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
 
-// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z12VarTmplInit2I21ExplicitInst_ExportedE, align 4
 template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
 INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
 
 // Declare, then export definition.
-// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z15VarTmplDeclInitI21ExplicitInst_ExportedE, align 4
 template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
 template<typename T>                              int VarTmplDeclInit = 1;
 INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
 
 // Redeclarations
-// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z14VarTmplRedecl1I21ExplicitInst_ExportedE, align 4
 template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
 template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
 INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
 
-// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z14VarTmplRedecl2I21ExplicitInst_ExportedE, align 4
 template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
 template<typename T>                              int VarTmplRedecl2 = 1;
 INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
 
-// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA", align 4
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, comdat $_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE,  align 4
 namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
 INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
 
-// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
-// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, align 4
+// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, comdat $"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A", align 4
+// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, comdat $_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE, align 4
 template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
 template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
 
@@ -155,19 +155,19 @@ template<typename T> int VarTmpl = 1;
 template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
 
 // Export implicit instantiation of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z15ExportedVarTmplI21ImplicitInst_ExportedE, align 4
 USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
 
 // Export explicit instantiation declaration of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z15ExportedVarTmplI21ExplicitDecl_ExportedE, align 4
 extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
        template int ExportedVarTmpl<ExplicitDecl_Exported>;
 
 // Export explicit instantiation definition of an exported variable template.
-// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, comdat $_Z15ExportedVarTmplI21ExplicitInst_ExportedE, align 4
 template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
 
 // Export specialization of an exported variable template.
@@ -187,14 +187,14 @@ template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
 
 
 // Export explicit instantiation declaration of a non-exported variable template.
-// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA", align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, comdat $_Z7VarTmplI21ExplicitDecl_ExportedE, align 4
 extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
        template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
 
 // Export explicit instantiation definition of a non-exported variable template.
-// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
-// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, align 4
+// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat $"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA",  align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, comdat $_Z7VarTmplI21ExplicitInst_ExportedE, align 4
 template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
 
 // Export specialization of a non-exported variable template.
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 5ebedd9..4dbe49e 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -243,7 +243,7 @@ __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
 USE(noinline)
 
 // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
-// GNU2-NOT: @_Z12alwaysInlinev()
+// GNU2: define linkonce_odr void @_Z12alwaysInlinev() #{{.*}} comdat $_Z12alwaysInlinev
 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
 USE(alwaysInline)
 
diff --git a/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
index 3f868f3..52fc9ab 100644
--- a/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
+++ b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
@@ -17,6 +17,6 @@ struct __declspec(dllexport) S {
   };
 };
 
-// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, align 2
-// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, align 4
+// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, comdat $"\01?x@S@@2FB", align 2
+// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, comdat $"\01?y@S@@2W4Enum@@B", align 4
 // CHECK-NOT: NonExported
diff --git a/test/CodeGenCXX/ms-integer-static-data-members.cpp b/test/CodeGenCXX/ms-integer-static-data-members.cpp
index b02b679..dfb5815 100644
--- a/test/CodeGenCXX/ms-integer-static-data-members.cpp
+++ b/test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -26,7 +26,7 @@ const int S::x = 5;
 
 
 // Inline initialization.
-// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4
+// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, comdat $"\01?x@S@@2HB", align 4
 
 // Out-of-line initialization.
 // CHECK-OUTOFLINE: @"\01?x@S@@2HB" = constant i32 5, align 4
diff --git a/test/CodeGenCXX/split-stacks.cpp b/test/CodeGenCXX/split-stacks.cpp
index 3e12034..138d441 100644
--- a/test/CodeGenCXX/split-stacks.cpp
+++ b/test/CodeGenCXX/split-stacks.cpp
@@ -18,7 +18,7 @@ int nosplit() {
 
 // CHECK-SEGSTK: define i32 @_Z3foov() [[SS:#[0-9]+]] {
 // CHECK-SEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
-// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {{.*}} {
 // CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
 // CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
 // CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
@@ -27,7 +27,7 @@ int nosplit() {
 
 // CHECK-NOSEGSTK: define i32 @_Z3foov() [[NSS0:#[0-9]+]] {
 // CHECK-NOSEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
-// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]]  {{.*}} {
 // CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
 // CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
 // CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} }
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index a9debe3..f03c0c8 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -7,10 +7,8 @@
 // CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
 
-// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
-// CHECK-NOT: comdat
-// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
-// CHECK-NOT: comdat
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat $_ZZ2h2vE1i
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat $_ZGVZ2h2vE1i
 
 struct A {
   A();
@@ -37,8 +35,7 @@ void h() {
   static const int i = a();
 }
 
-// CHECK: define linkonce_odr void @_Z2h2v()
-// CHECK-NOT: comdat
+// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat $_Z2h2v
 inline void h2() {
   static int i = a();
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to