Index: lib/Linker/LinkModules.cpp
===================================================================
--- lib/Linker/LinkModules.cpp
+++ lib/Linker/LinkModules.cpp
@@ -478,6 +478,28 @@
   GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, const GlobalValue *SGV,
                                     const GlobalValue *DGV = nullptr);
 
+  /// Given a global in the source module, return the global in the
+  /// destination module that is being linked to, if any.
+  GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
+    // If the source has no name it can't link.  If it has local linkage,
+    // there is no name match-up going on.
+    if (!SrcGV->hasName() || SrcGV->hasLocalLinkage())
+      return nullptr;
+
+    // Otherwise see if we have a match in the destination module's symtab.
+    GlobalValue *DGV = DstM->getNamedValue(SrcGV->getName());
+    if (!DGV)
+      return nullptr;
+
+    // If we found a global with the same name in the dest module, but it has
+    // internal linkage, we are really not doing any linkage here.
+    if (DGV->hasLocalLinkage())
+      return nullptr;
+
+    // Otherwise, we do in fact link to the destination global.
+    return DGV;
+  }
+
   /// Check if we should promote the given local value to global scope.
   bool doPromoteLocalToGlobal(const GlobalValue *SGV);
 
@@ -512,28 +534,6 @@
   // Keep track of the global value members of each comdat in source.
   DenseMap<const Comdat *, std::vector<GlobalValue *>> ComdatMembers;
 
-  /// Given a global in the source module, return the global in the
-  /// destination module that is being linked to, if any.
-  GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
-    // If the source has no name it can't link.  If it has local linkage,
-    // there is no name match-up going on.
-    if (!SrcGV->hasName() || SrcGV->hasLocalLinkage())
-      return nullptr;
-
-    // Otherwise see if we have a match in the destination module's symtab.
-    GlobalValue *DGV = DstM->getNamedValue(SrcGV->getName());
-    if (!DGV)
-      return nullptr;
-
-    // If we found a global with the same name in the dest module, but it has
-    // internal linkage, we are really not doing any linkage here.
-    if (DGV->hasLocalLinkage())
-      return nullptr;
-
-    // Otherwise, we do in fact link to the destination global.
-    return DGV;
-  }
-
   void computeTypeMapping();
 
   void upgradeMismatchedGlobalArray(StringRef Name);
@@ -552,6 +552,11 @@
   void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
   bool linkGlobalValueBody(GlobalValue &Src);
 
+  /// Functions to update linked symbols after lazy linking complete
+  /// when importing.
+  void stripDeclsFromComdats();
+  void convertInvalidAliasesToDeclarations();
+
   /// Functions that take care of cloning a specific global value type
   /// into the destination module.
   GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap,
@@ -564,10 +569,18 @@
   bool isPerformingImport() { return ImportFunction != nullptr; }
   bool isModuleExporting() { return HasExportedFunctions; }
 
+  /// Return true if \p SGV is either the function being imported or in its
+  /// same comdat group.
+  bool mustImport(const GlobalValue *SGV);
+
   /// If we are importing from the source module, checks if we should
   /// import SGV as a definition, otherwise import as a declaration.
   bool doImportAsDefinition(const GlobalValue *SGV);
 
+  /// If we are importing from the source module, checks if a global value
+  /// that is to be linked from source should be lazy linked on reference.
+  bool doImportLazily(const GlobalValue *SGV);
+
   /// Get the name for SGV that should be used in the linked destination
   /// module. Specifically, this handles the case where we need to rename
   /// a local that is being promoted to global scope.
@@ -648,33 +661,60 @@
   return false;
 }
 
+bool ModuleLinker::mustImport(const GlobalValue *SGV) {
+  assert(isPerformingImport());
+  if (auto *F = dyn_cast<Function>(SGV))
+    if (F == ImportFunction)
+      return true;
+  const Comdat *C = ImportFunction->getComdat();
+  // Ensure we import the whole comdat group.
+  return C && SGV->getComdat() == C;
+}
+
+// Called once we decide to link a global value, and decides whether to
+// link as a definition or declaration.
 bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
   if (!isPerformingImport())
     return false;
-  auto *GA = dyn_cast<GlobalAlias>(SGV);
-  if (GA) {
-    if (GA->hasWeakAnyLinkage())
-      return false;
+  // WeakAny global values are imported as ExternalWeak declarations
+  // (see comments in ModuleLinker::getLinkage).
+  if (SGV->hasWeakAnyLinkage())
+    return false;
+  // Otherwise, the linkage changes described in ModuleLinker::getLinkage
+  // ensure the correct behavior (e.g. global variables with external linkage
+  // are transformed to available_externally definitions, which are ultimately
+  // turned into declarations after the EliminateAvailableExternally pass).
+  if (auto *GA = dyn_cast<GlobalAlias>(SGV))
     return doImportAsDefinition(GA->getBaseObject());
-  }
   // Always import GlobalVariable definitions, except for the special
-  // case of WeakAny which are imported as ExternalWeak declarations
-  // (see comments in ModuleLinker::getLinkage). The linkage changes
-  // described in ModuleLinker::getLinkage ensure the correct behavior (e.g.
-  // global variables with external linkage are transformed to
-  // available_externally definitions, which are ultimately turned into
-  // declarations after the EliminateAvailableExternally pass).
-  if (dyn_cast<GlobalVariable>(SGV) && !SGV->isDeclaration() &&
-      !SGV->hasWeakAnyLinkage())
+  // case of WeakAny handled above.
+  if (dyn_cast<GlobalVariable>(SGV) && !SGV->isDeclaration())
     return true;
-  // Only import the function requested for importing.
+  // Import definitions for the function requested for importing, as well
+  // as any linked functions in comdat groups. If this is in the same comdat
+  // group as the imported function, it will be greedily linked, otherwise
+  // it will be lazy linked on reference. If we decided to link from source
+  // due to the comdat selection process, we need to ensure we get the entire
+  // comdat group.
   auto *SF = dyn_cast<Function>(SGV);
-  if (SF && SF == ImportFunction)
+  if (SF && (mustImport(SF) || SF->getComdat()))
     return true;
   // Otherwise no.
   return false;
 }
 
+// We import global values lazily upon reference unless this is the function
+// to import or anything in the same comdat group.
+bool ModuleLinker::doImportLazily(const GlobalValue *SGV) {
+  if (!isPerformingImport())
+    return false;
+  if (auto *GA = dyn_cast<GlobalAlias>(SGV))
+    return !mustImport(GA->getBaseObject());
+  // If this is the function requested for importing, or a GV in the
+  // same comdat group, we import greedily.
+  return !mustImport(SGV);
+}
+
 bool ModuleLinker::doPromoteLocalToGlobal(const GlobalValue *SGV) {
   assert(SGV->hasLocalLinkage());
   // Both the imported references and the original local variable must
@@ -838,30 +878,6 @@
 /// Set up prototypes for any aliases that come over from the source module.
 GlobalValue *ModuleLinker::copyGlobalAliasProto(TypeMapTy &TypeMap,
                                                 const GlobalAlias *SGA) {
-  // If we are importing and encounter a weak_any alias, or an alias to
-  // an object being imported as a declaration, we must import the alias
-  // as a declaration as well, which involves converting it to a non-alias.
-  // See comments in ModuleLinker::getLinkage for why we cannot import
-  // weak_any defintions.
-  if (isPerformingImport() && !doImportAsDefinition(SGA)) {
-    // Need to convert to declaration. All aliases must be definitions.
-    const GlobalValue *GVal = SGA->getBaseObject();
-    GlobalValue *NewGV;
-    if (auto *GVar = dyn_cast<GlobalVariable>(GVal))
-      NewGV = copyGlobalVariableProto(TypeMap, GVar);
-    else {
-      auto *F = dyn_cast<Function>(GVal);
-      assert(F);
-      NewGV = copyFunctionProto(TypeMap, F);
-    }
-    // Set the linkage to External or ExternalWeak (see comments in
-    // ModuleLinker::getLinkage for why WeakAny is converted to ExternalWeak).
-    if (SGA->hasWeakAnyLinkage())
-      NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
-    else
-      NewGV->setLinkage(GlobalValue::ExternalLinkage);
-    return NewGV;
-  }
   // If there is no linkage to be performed or we're linking from the source,
   // bring over SGA.
   auto *Ty = TypeMap.get(SGA->getValueType());
@@ -909,17 +925,27 @@
   if (ModLinker->doneLinkingBodies())
     return nullptr;
 
-  GlobalValue *DGV = ModLinker->copyGlobalValueProto(TypeMap, SGV);
+  GlobalValue *DGV = ModLinker->getLinkedToGlobal(SGV);
+  GlobalValue *NewGV = ModLinker->copyGlobalValueProto(TypeMap, SGV);
 
   if (Comdat *SC = SGV->getComdat()) {
-    if (auto *DGO = dyn_cast<GlobalObject>(DGV)) {
+    if (auto *DGO = dyn_cast<GlobalObject>(NewGV)) {
       Comdat *DC = DstM->getOrInsertComdat(SC->getName());
       DGO->setComdat(DC);
     }
   }
 
   LazilyLinkGlobalValues.push_back(SGV);
-  return DGV;
+
+  // In some cases (function importing) we lazily link the selected source
+  // copy even if there was already a copy in the dest module (e.g. comdats).
+  // Ensure we replace the dest copy. The caller will enter NewGV into the
+  // ValueMap for SGV.
+  if (DGV && NewGV != DGV) {
+    DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType()));
+    DGV->eraseFromParent();
+  }
+  return NewGV;
 }
 
 bool ModuleLinker::getComdatLeader(Module *M, StringRef ComdatName,
@@ -1419,13 +1445,28 @@
   } else {
     // If the GV is to be lazily linked, don't create it just yet.
     // The ValueMaterializerTy will deal with creating it if it's used.
-    if (!DGV && !shouldOverrideFromSrc() && SGV != ImportFunction &&
+    if (!DGV && !shouldOverrideFromSrc() && !doImportLazily(SGV) &&
         (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
          SGV->hasAvailableExternallyLinkage())) {
       DoNotLinkFromSource.insert(SGV);
       return false;
     }
 
+    // In the case of ThinLTO function importing, we can lazy link most symbols,
+    // linking them in only if they are referenced by other imported functions.
+    // The exception is the function to import, or anything in its comdat group.
+    // It is particularly important to lazy link values in other comdat groups,
+    // since we need to link from source definitions for the full comdat group
+    // (the comdat selection logic selected the source copy if we reached here).
+    // This is handled by linkGlobalValueBody. Also, mark anything we will not
+    // import as a definition as DoNotLinkFromSource so that only the
+    // declaration is linked (lazily).
+    if (isPerformingImport() &&
+        (doImportLazily(SGV) || !doImportAsDefinition(SGV))) {
+      DoNotLinkFromSource.insert(SGV);
+      return false;
+    }
+
     // When we only want to link in unresolved dependencies, blacklist
     // the symbol unless unless DestM has a matching declaration (DGV).
     if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) {
@@ -1434,9 +1475,6 @@
     }
 
     NewGV = copyGlobalValueProto(TypeMap, SGV, DGV);
-
-    if (isPerformingImport() && !doImportAsDefinition(SGV))
-      DoNotLinkFromSource.insert(SGV);
   }
 
   NewGV->setUnnamedAddr(HasUnnamedAddr);
@@ -1618,6 +1656,98 @@
   return false;
 }
 
+/// Remove any imported declarations from comdats, which may not contain
+/// declarations. For ThinLTO we may import comdat members as declarations if
+/// nothing else in the comdat group is imported as a definition, but it is
+/// referenced by an imported function (requiring the declaration). We may also
+/// import as available_externally defs, which are declarations for the linker
+/// and may not be in comdats either.
+void ModuleLinker::stripDeclsFromComdats() {
+#ifndef NDEBUG
+  SmallPtrSet<const Comdat *, 16> StrippedComdats;
+#endif
+  for (GlobalVariable &SGV : SrcM->globals()) {
+    GlobalValue *DGV = DstM->getNamedValue(getName(&SGV));
+    auto *GO = dyn_cast_or_null<GlobalObject>(DGV);
+    if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
+#ifndef NDEBUG
+      StrippedComdats.insert(GO->getComdat());
+#endif
+      GO->setComdat(nullptr);
+    }
+  }
+  for (Function &SF : *SrcM) {
+    GlobalValue *DGV = DstM->getNamedValue(getName(&SF));
+    auto *GO = dyn_cast_or_null<GlobalObject>(DGV);
+    if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
+#ifndef NDEBUG
+      StrippedComdats.insert(GO->getComdat());
+#endif
+      GO->setComdat(nullptr);
+    }
+  }
+  for (GlobalAlias &SGA : SrcM->aliases()) {
+    // Look for aliases that were turned into declarations.
+    GlobalValue *DGV = DstM->getNamedValue(getName(&SGA));
+    auto *GO = dyn_cast_or_null<GlobalObject>(DGV);
+    if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
+#ifndef NDEBUG
+      StrippedComdats.insert(GO->getComdat());
+#endif
+      GO->setComdat(nullptr);
+    }
+  }
+#ifndef NDEBUG
+  for (GlobalVariable &DGV : DstM->globals())
+    assert(!StrippedComdats.count(DGV.getComdat()) &&
+           "Found remaining member of stripped comdat");
+  for (Function &DF : *DstM)
+    assert(!StrippedComdats.count(DF.getComdat()) &&
+           "Found remaining member of stripped comdat");
+  for (GlobalAlias &DGA : DstM->aliases())
+    assert(!StrippedComdats.count(DGA.getComdat()) &&
+           "Found remaining member of stripped comdat");
+#endif
+}
+
+/// For ThinLTO we won't know for sure whether an aliasee definition is
+/// imported until after lazy linking is complete. If not, then
+/// we need to convert aliases to declarations.
+void ModuleLinker::convertInvalidAliasesToDeclarations() {
+  for (GlobalAlias &SGA : SrcM->aliases()) {
+    GlobalValue *DGV = DstM->getNamedValue(getName(&SGA));
+    auto *DGA = dyn_cast_or_null<GlobalAlias>(DGV);
+    // Check if this source alias has a dest copy.
+    if (!DGA)
+      continue;
+    // Look for aliases to null or to declarations.
+    Constant *Aliasee = DGA->getAliasee();
+    if (Aliasee && !DGA->getBaseObject()->isDeclaration())
+      continue;
+
+    // Convert alias to non-alias declaration.
+    const GlobalValue *GVal = SGA.getBaseObject();
+    GlobalValue *NewGV;
+    if (auto *GVar = dyn_cast<GlobalVariable>(GVal))
+      NewGV = copyGlobalVariableProto(TypeMap, GVar);
+    else {
+      auto *F = dyn_cast<Function>(GVal);
+      assert(F);
+      NewGV = copyFunctionProto(TypeMap, F);
+    }
+    // Set the linkage to External or ExternalWeak (see comments in
+    // ModuleLinker::getLinkage for why WeakAny is converted to ExternalWeak).
+    if (SGA.hasWeakAnyLinkage())
+      NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
+    else
+      NewGV->setLinkage(GlobalValue::ExternalLinkage);
+    copyGVAttributes(NewGV, &SGA);
+    setVisibility(NewGV, &SGA, DGA);
+    DGA->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGA->getType()));
+    DGA->eraseFromParent();
+  }
+}
+
 /// Insert all of the named MDNodes in Src into the Dest module.
 void ModuleLinker::linkNamedMDNodes() {
   const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
@@ -1956,6 +2086,12 @@
   // metadata linking from creating new references.
   DoneLinkingBodies = true;
 
+  // Now that we are done lazy linking, any imported aliases that don't
+  // have an associated imported aliasee definition must be converted
+  // to declarations.
+  if (isPerformingImport())
+    convertInvalidAliasesToDeclarations();
+
   // Remap all of the named MDNodes in Src into the DstM module. We do this
   // after linking GlobalValues so that MDNodes that reference GlobalValues
   // are properly remapped.
@@ -1965,6 +2101,9 @@
   if (linkModuleFlagsMetadata())
     return true;
 
+  if (isPerformingImport())
+    stripDeclsFromComdats();
+
   return false;
 }
 
Index: test/Linker/Inputs/funcimport_comdat.ll
===================================================================
--- /dev/null
+++ test/Linker/Inputs/funcimport_comdat.ll
@@ -0,0 +1,4 @@
+define i32 @main() #0 {
+entry:
+  ret i32 0
+}
Index: test/Linker/Inputs/funcimport_comdat2.ll
===================================================================
--- /dev/null
+++ test/Linker/Inputs/funcimport_comdat2.ll
@@ -0,0 +1,38 @@
+declare void @ref_comdat1(...)
+declare void @ref_comdat2(...)
+declare void @ref_linkoncecomdat1(...)
+declare void @ref_linkoncecomdat2(...)
+
+$linkoncecomdat1 = comdat largest
+@linkoncecomdat1 = linkonce global i64 1, comdat($linkoncecomdat1)
+define linkonce void @linkoncecomdat1_func() comdat($linkoncecomdat1) {
+  ret void
+}
+
+$linkoncecomdat2 = comdat largest
+@linkoncecomdat2 = linkonce global i32 2, comdat($linkoncecomdat2)
+@linkoncecomdat2b = linkonce global i32 2, comdat($linkoncecomdat2)
+define linkonce void @linkoncecomdat2_func() comdat($linkoncecomdat2) {
+  ret void
+}
+
+$comdat1 = comdat largest
+@comdat1 = global i64 1, comdat($comdat1)
+define void @comdat1_func() comdat($comdat1) {
+  ret void
+}
+
+$comdat2 = comdat largest
+@comdat2 = global i32 2, comdat($comdat2)
+define void @comdat2_func() comdat($comdat2) {
+  ret void
+}
+
+define i32 @main() #0 {
+entry:
+  call void (...) @ref_comdat1()
+  call void (...) @ref_comdat2()
+  call void (...) @ref_linkoncecomdat1()
+  call void (...) @ref_linkoncecomdat2()
+  ret i32 0
+}
Index: test/Linker/Inputs/funcimport_comdat3.ll
===================================================================
--- /dev/null
+++ test/Linker/Inputs/funcimport_comdat3.ll
@@ -0,0 +1,7 @@
+define i32 @main() #0 {
+entry:
+  call void (...) @globalfunc()
+  ret i32 0
+}
+
+declare void @globalfunc(...)
Index: test/Linker/funcimport.ll
===================================================================
--- test/Linker/funcimport.ll
+++ test/Linker/funcimport.ll
@@ -12,25 +12,18 @@
 ; EXPORTSTATIC-DAG: define hidden i32 @staticfunc.llvm.1
 ; EXPORTSTATIC-DAG: define hidden void @staticfunc2.llvm.1
 
-; Ensure that both weak alias to an imported function and strong alias to a
-; non-imported function are correctly turned into declarations.
-; Also ensures that alias to a linkonce function is turned into a declaration
-; and that the associated linkonce function is not in the output, as it is
-; lazily linked and never referenced/materialized.
+; Ensures that an unreferenced linkonce function and its alias are not
+; in the output, as they are lazily linked and never referenced/materialized.
 ; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1
 ; IMPORTGLOB1-DAG: define available_externally void @globalfunc1
-; IMPORTGLOB1-DAG: declare void @globalfunc2
-; IMPORTGLOB1-DAG: declare extern_weak void @weakalias
-; IMPORTGLOB1-DAG: declare void @analias
-; IMPORTGLOB1-DAG: declare void @linkoncealias
+; IMPORTGLOB1-NOT: @linkoncealias
 ; IMPORTGLOB1-NOT: @linkoncefunc
 
-; Ensure that weak alias to a non-imported function is correctly
+; Ensure that a referenced weak alias to a non-imported function is correctly
 ; turned into a declaration, but that strong alias to an imported function
 ; is imported as alias.
 ; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2
 ; IMPORTGLOB2-DAG: @analias = alias void (...), bitcast (void ()* @globalfunc2
-; IMPORTGLOB2-DAG: declare void @globalfunc1
 ; IMPORTGLOB2-DAG: define available_externally void @globalfunc2
 ; IMPORTGLOB2-DAG: declare extern_weak void @weakalias
 
@@ -85,7 +78,6 @@
 ; reference should turned into an external_weak declaration.
 ; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC
 ; IMPORTWEAKFUNC-DAG: Ignoring import request for weak-any function weakfunc
-; IMPORTWEAKFUNC-DAG: @weakvar = extern_weak global i32, align 4
 ; IMPORTWEAKFUNC-DAG: declare extern_weak void @weakfunc
 ; IMPORTWEAKFUNC-DAG: define available_externally void @callweakfunc
 
@@ -106,6 +98,7 @@
 
 define void @globalfunc2() #0 {
 entry:
+  call void (...) @weakalias()
   ret void
 }
 
Index: test/Linker/funcimport_comdat.ll
===================================================================
--- /dev/null
+++ test/Linker/funcimport_comdat.ll
@@ -0,0 +1,28 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: llvm-as -function-summary %s -o %t.bc
+; RUN: llvm-as -function-summary %p/Inputs/funcimport_comdat.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Ensure linking of comdat containing external linkage global and function
+; removes the imported available_externally defs from comdat.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat1_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT
+; IMPORTCOMDAT-NOT: $comdat1 = comdat any
+; IMPORTCOMDAT-NOT: comdat($comdat1)
+
+; Ensure linking of comdat containing internal linkage function with alias
+; removes the imported and promoted available_externally defs from comdat.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat2_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT2
+; IMPORTCOMDAT2-NOT: $comdat2 = comdat any
+; IMPORTCOMDAT2-NOT: comdat($comdat2)
+
+$comdat1 = comdat any
+@comdat1_glob = global i32 0, comdat($comdat1)
+define void @comdat1_func1() comdat($comdat1) {
+  ret void
+}
+
+$comdat2 = comdat any
+@comdat2_alias = alias void (), void ()* @comdat2_func1
+define internal void @comdat2_func1() comdat($comdat2) {
+  ret void
+}
Index: test/Linker/funcimport_comdat2.ll
===================================================================
--- /dev/null
+++ test/Linker/funcimport_comdat2.ll
@@ -0,0 +1,95 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: llvm-as -function-summary %s -o %t.bc
+; RUN: llvm-as -function-summary %p/Inputs/funcimport_comdat2.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Ensure we link from source the larger version of a comdat containing linkonce
+; values.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=ref_linkoncecomdat1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDATREFLOSRC
+; IMPORTCOMDATREFLOSRC: @linkoncecomdat1 = linkonce global i64 1, comdat
+; IMPORTCOMDATREFLOSRC-DAG: define linkonce void @linkoncecomdat1_func() comdat($linkoncecomdat1)
+; IMPORTCOMDATREFLOSRC-NEXT: ret void
+; IMPORTCOMDATREFLOSRC-NOT: @linkoncecomdat1_unselectedgroupvar
+; IMPORTCOMDATREFLOSRC-NOT: @linkoncecomdat1_unselectedgroupfunc
+
+; Ensure we link from dest the larger version of a comdat containing linkonce
+; values, including an unreferenced variable that is not the comdat leader.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=ref_linkoncecomdat2:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDATREFLODEST
+; IMPORTCOMDATREFLODEST: @linkoncecomdat2 = linkonce global i64 1, comdat
+; IMPORTCOMDATREFLODEST-DAG: @linkoncecomdat2b = linkonce global i64 1, comdat($linkoncecomdat2)
+; IMPORTCOMDATREFLODEST-DAG: define linkonce void @linkoncecomdat2_func() comdat($linkoncecomdat2)
+; IMPORTCOMDATREFLODEST-NEXT: load i64, i64* @linkoncecomdat2, align 4
+
+; Ensure we link from source the larger version of a comdat containing external
+; values.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=ref_comdat1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDATREFSRC
+; IMPORTCOMDATREFSRC: @comdat1 = global i64 1, comdat
+; IMPORTCOMDATREFSRC-DAG: define void @comdat1_func() comdat($comdat1)
+; IMPORTCOMDATREFSRC-NEXT: ret void
+; IMPORTCOMDATREFSRC-NOT: @comdat1_unselectedgroupvar
+; IMPORTCOMDATREFSRC-NOT: @comdat1_unselectedgroupfunc
+
+; Ensure we link from dest the larger version of a comdat containing external
+; values, which are then removed from the comdat as they are
+; available_externally.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=ref_comdat2:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDATREFDEST
+; IMPORTCOMDATREFDEST: @comdat2 = available_externally global i64 1
+; IMPORTCOMDATREFDEST-DAG: define available_externally void @comdat2_func() {
+; IMPORTCOMDATREFDEST-NEXT: %1 = load i64, i64* @comdat2, align 4
+
+$linkoncecomdat1 = comdat largest
+@linkoncecomdat1 = linkonce global i32 2, comdat($linkoncecomdat1)
+@linkoncecomdat1_unselectedgroupvar = linkonce global i32 2, comdat($linkoncecomdat1)
+define linkonce void @linkoncecomdat1_func() comdat($linkoncecomdat1) {
+  load i32, i32* @linkoncecomdat1, align 4
+  ret void
+}
+define linkonce void @linkoncecomdat1_unselectedgroupfunc() comdat($linkoncecomdat1) {
+  ret void
+}
+define void @ref_linkoncecomdat1() {
+  load i32, i32* @linkoncecomdat1, align 4
+  call void @linkoncecomdat1_func()
+  ret void
+}
+
+$linkoncecomdat2 = comdat largest
+@linkoncecomdat2 = linkonce global i64 1, comdat($linkoncecomdat2)
+@linkoncecomdat2b = linkonce global i64 1, comdat($linkoncecomdat2)
+define linkonce void @linkoncecomdat2_func() comdat($linkoncecomdat2) {
+  load i64, i64* @linkoncecomdat2, align 4
+  ret void
+}
+define void @ref_linkoncecomdat2() {
+  load i64, i64* @linkoncecomdat2, align 4
+  call void @linkoncecomdat2_func()
+  ret void
+}
+
+$comdat1 = comdat largest
+@comdat1 = global i32 2, comdat($comdat1)
+@comdat1_unselectedgroupvar = global i32 2, comdat($comdat1)
+define void @comdat1_func() comdat($comdat1) {
+  load i32, i32* @comdat1, align 4
+  ret void
+}
+define void @comdat1_unselectedgroupfunc() comdat($comdat1) {
+  ret void
+}
+define void @ref_comdat1() {
+  load i32, i32* @comdat1, align 4
+  call void @comdat1_func()
+  ret void
+}
+
+$comdat2 = comdat largest
+@comdat2 = global i64 1, comdat($comdat2)
+define void @comdat2_func() comdat($comdat2) {
+  load i64, i64* @comdat2, align 4
+  ret void
+}
+define void @ref_comdat2() {
+  load i64, i64* @comdat2, align 4
+  call void @comdat2_func()
+  ret void
+}
Index: test/Linker/funcimport_comdat3.ll
===================================================================
--- /dev/null
+++ test/Linker/funcimport_comdat3.ll
@@ -0,0 +1,41 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: llvm-as -function-summary %s -o %t.bc
+; RUN: llvm-as -function-summary %p/Inputs/funcimport_comdat3.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Ensure linking of linkonce functions and alias in a comdat works.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=linkoncecomdatfunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTLINKONCECOMDAT
+; IMPORTLINKONCECOMDAT: $linkoncecomdatfunc = comdat any
+; IMPORTLINKONCECOMDAT: @linkoncecomdatalias = alias void (...), bitcast (void ()* @linkoncecomdatfunc
+; IMPORTLINKONCECOMDAT: define linkonce_odr void @linkoncecomdatfunc() comdat
+
+; Ensure linking of linkonce functions and alias in a comdat works
+; when not imported first.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc:%t.bc -import=ref_linkoncecomdat:%t.bc -S | FileCheck %s --check-prefix=IMPORTLINKONCECOMDAT2
+; IMPORTLINKONCECOMDAT2: $linkoncecomdatfunc = comdat any
+; IMPORTLINKONCECOMDAT2: @linkoncecomdatalias = alias void (...), bitcast (void ()* @linkoncecomdatfunc
+; IMPORTLINKONCECOMDAT2: define linkonce_odr void @linkoncecomdatfunc() comdat
+
+; Ensure an unreferenced linkonce function and its alias are not in the output
+; when its reference is not imported, as it is lazily linked.
+; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB
+; IMPORTGLOB-NOT: linkoncecomdatalias
+; IMPORTGLOB-NOT: linkoncecomdatfunc
+
+@linkoncecomdatalias = alias void (...), bitcast (void ()* @linkoncecomdatfunc to void (...)*)
+$linkoncecomdatfunc = comdat any
+define linkonce_odr void @linkoncecomdatfunc() comdat {
+entry:
+  ret void
+}
+
+define void @ref_linkoncecomdat() {
+  call void @linkoncecomdatfunc()
+  ret void
+}
+
+define void @globalfunc() {
+entry:
+  call void @ref_linkoncecomdat()
+  ret void
+}