Index: lib/Analysis/ModuleSummaryAnalysis.cpp =================================================================== --- lib/Analysis/ModuleSummaryAnalysis.cpp +++ lib/Analysis/ModuleSummaryAnalysis.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Pass.h" @@ -119,10 +120,10 @@ const Module *M, std::function Ftor) : Index(llvm::make_unique()), M(M) { - // We cannot currently promote or rename anything that is in llvm.used, - // since any such value may have a use that won't see the new name. - // Specifically, any uses within inline assembly are not visible to the - // compiler. Prevent importing of any modules containing these uses by + // We cannot currently promote or rename anything used in inline assembly, + // which are not visible to the compiler. Detect a possible case by looking + // for a llvm.used local value, in conjunction with an inline assembly call + // in the module. Prevent importing of any modules containing these uses by // suppressing generation of the index. This also prevents importing // into this module, which is also necessary to avoid needing to rename // in case of a name clash between a local in this module and an imported @@ -139,10 +140,17 @@ // with a reference could be exported). SmallPtrSet Used; collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false); + bool LocalIsUsed = false; for (GlobalValue *V : Used) { - if (V->hasLocalLinkage()) - return; + if ((LocalIsUsed |= V->hasLocalLinkage())) + break; } + if (LocalIsUsed) + for (auto &F : *M) + for (auto &I : instructions(F)) + if (const CallInst *CallI = dyn_cast(&I)) + if (CallI->isInlineAsm()) + return; // Compute summaries for all functions defined in module, and save in the // index. Index: lib/Transforms/Utils/FunctionImportUtils.cpp =================================================================== --- lib/Transforms/Utils/FunctionImportUtils.cpp +++ lib/Transforms/Utils/FunctionImportUtils.cpp @@ -13,6 +13,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/FunctionImportUtils.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Instructions.h" using namespace llvm; /// Checks if we should import SGV as a definition, otherwise import as a @@ -211,25 +213,31 @@ } void FunctionImportGlobalProcessing::processGlobalsForThinLTO() { - // We cannot currently promote or rename anything that is in llvm.used, - // since any such value may have a use that won't see the new name. - // Specifically, any uses within inline assembly are not visible to the - // compiler. Prevent changing any such values on the exporting side, + // We cannot currently promote or rename anything used in inline assembly, + // which are not visible to the compiler. Detect a possible case by looking + // for a llvm.used local value, in conjunction with an inline assembly call + // in the module. Prevent changing any such values on the exporting side, // since we would already have guarded against an import from this module by // suppressing its index generation. See comments on what is required // in order to implement a finer grained solution in // ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder(). SmallPtrSet Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); + bool LocalIsUsed = false; for (GlobalValue *V : Used) { - if (!V->hasLocalLinkage()) - continue; // We would have blocked importing from this module by suppressing index // generation. - assert(!isPerformingImport() && + assert((!V->hasLocalLinkage() || !isPerformingImport()) && "Should have blocked importing from module with local used"); - return; + if ((LocalIsUsed |= V->hasLocalLinkage())) + break; } + if (LocalIsUsed) + for (auto &F : M) + for (auto &I : instructions(F)) + if (const CallInst *CallI = dyn_cast(&I)) + if (CallI->isInlineAsm()) + return; for (GlobalVariable &GV : M.globals()) processGlobalForThinLTO(GV);