diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -29,12 +29,19 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include "llvm/TargetParser/Triple.h" #include + using namespace llvm; +static cl::opt + DisableAutoUpgrade("disable-auto-upgrade", + cl::desc("Assume that input bitcode needs no upgrading, " + "skipping any auto-upgrading")); + static void rename(GlobalValue *GV) { GV->setName(GV->getName() + ".old"); } // Upgrade the declarations of the SSE4.1 ptest intrinsics whose arguments have @@ -1173,6 +1180,9 @@ } bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { + if (DisableAutoUpgrade) + return false; + NewFn = nullptr; bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); assert(F != NewFn && "Intrinsic function upgraded to the same function"); @@ -1186,6 +1196,9 @@ } GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) { + if (DisableAutoUpgrade) + return nullptr; + if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" || GV->getName() == "llvm.global_dtors")) || !GV->hasInitializer()) @@ -1968,6 +1981,9 @@ /// Upgrade comment in call to inline asm that represents an objc retain release /// marker. void llvm::UpgradeInlineAsmString(std::string *AsmStr) { + if (DisableAutoUpgrade) + return; + size_t Pos; if (AsmStr->find("mov\tfp") == 0 && AsmStr->find("objc_retainAutoreleaseReturnValue") != std::string::npos && @@ -2073,6 +2089,9 @@ /// Upgrade a call to an old intrinsic. All argument and return casting must be /// provided to seamlessly integrate with existing context. void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { + if (DisableAutoUpgrade) + return; + // Note dyn_cast to Function is not quite the same as getCalledFunction, which // checks the callee's function type matches. It's likely we need to handle // type changes here. @@ -4374,6 +4393,9 @@ } void llvm::UpgradeCallsToIntrinsic(Function *F) { + if (DisableAutoUpgrade) + return; + assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); // Check if this function should be upgraded and get the replacement function @@ -4392,6 +4414,9 @@ } MDNode *llvm::UpgradeTBAANode(MDNode &MD) { + if (DisableAutoUpgrade) + return &MD; + // Check if the tag uses struct-path aware TBAA format. if (isa(MD.getOperand(0)) && MD.getNumOperands() >= 3) return &MD; @@ -4415,6 +4440,9 @@ Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, Instruction *&Temp) { + if (DisableAutoUpgrade) + return nullptr; + if (Opc != Instruction::BitCast) return nullptr; @@ -4436,6 +4464,9 @@ } Constant *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { + if (DisableAutoUpgrade) + return nullptr; + if (Opc != Instruction::BitCast) return nullptr; @@ -4458,6 +4489,9 @@ /// Check the debug info version number, if it is out-dated, drop the debug /// info. Return true if module is modified. bool llvm::UpgradeDebugInfo(Module &M) { + if (DisableAutoUpgrade) + return false; + unsigned Version = getDebugMetadataVersionFromModule(M); if (Version == DEBUG_METADATA_VERSION) { bool BrokenDebugInfo = false; @@ -4508,6 +4542,9 @@ } void llvm::UpgradeARCRuntime(Module &M) { + if (DisableAutoUpgrade) + return; + // This lambda converts normal function calls to ARC runtime functions to // intrinsic calls. auto UpgradeToIntrinsic = [&](const char *OldFunc, @@ -4629,6 +4666,9 @@ } bool llvm::UpgradeModuleFlags(Module &M) { + if (DisableAutoUpgrade) + return false; + NamedMDNode *ModFlags = M.getModuleFlagsMetadata(); if (!ModFlags) return false; @@ -4763,6 +4803,9 @@ } void llvm::UpgradeSectionAttributes(Module &M) { + if (DisableAutoUpgrade) + return; + auto TrimSpaces = [](StringRef Section) -> std::string { SmallVector Components; Section.split(Components, ','); @@ -4820,6 +4863,9 @@ } // namespace void llvm::UpgradeFunctionAttributes(Function &F) { + if (DisableAutoUpgrade) + return; + // If a function definition doesn't have the strictfp attribute, // convert any callsite strictfp attributes to nobuiltin. if (!F.isDeclaration() && !F.hasFnAttribute(Attribute::StrictFP)) { @@ -4880,6 +4926,9 @@ } MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) { + if (DisableAutoUpgrade) + return &N; + auto *T = dyn_cast(&N); if (!T) return &N; @@ -4896,6 +4945,9 @@ } std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { + if (DisableAutoUpgrade) + return DL.str(); + Triple T(TT); // For AMDGPU we uprgrade older DataLayouts to include the default globals // address space of 1. @@ -4939,6 +4991,9 @@ } void llvm::UpgradeAttributes(AttrBuilder &B) { + if (DisableAutoUpgrade) + return; + StringRef FramePointer; Attribute A = B.getAttribute("no-frame-pointer-elim"); if (A.isValid()) { @@ -4966,6 +5021,8 @@ } void llvm::UpgradeOperandBundles(std::vector &Bundles) { + if (DisableAutoUpgrade) + return; // clang.arc.attachedcall bundles are now required to have an operand. // If they don't, it's okay to drop them entirely: when there is an operand, diff --git a/llvm/test/LTO/X86/strip-debug-info.ll b/llvm/test/LTO/X86/strip-debug-info.ll --- a/llvm/test/LTO/X86/strip-debug-info.ll +++ b/llvm/test/LTO/X86/strip-debug-info.ll @@ -24,10 +24,18 @@ ; RUN: -exported-symbol foo -exported-symbol _foo \ ; RUN: %t-stripped.bc -disable-verify 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN +; ---- Thin LTO (optimize, don't strip imported file) +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t-stripped.bc %t2.bc +; RUN: llvm-lto -thinlto -thinlto-action=import -disable-auto-upgrade \ +; RUN: -thinlto-index=%t.index.bc \ +; RUN: -exported-symbol foo -exported-symbol _foo \ +; RUN: %t-stripped.bc -disable-verify 2>&1 | \ +; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-NO-WARN ; CHECK-WARN: warning{{.*}} ignoring invalid debug info ; CHECK-WARN-NOT: Broken module found ; CHECK: foo +; CHECK-NO-WARN-NOT: ignoring invalid debug info target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12"