From 20e25d0be204a896c3eee91b1643097043e6b5d1 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 7 Sep 2019 11:21:41 +0000 Subject: [PATCH 1/3] Vendor import of llvm release_90 branch r371301: https://llvm.org/svn/llvm-project/llvm/branches/release_90@371301 --- .../Vectorize/LoopVectorizationLegality.h | 4 +-- .../SelectionDAG/SelectionDAGBuilder.cpp | 2 +- lib/Target/PowerPC/PPCAsmPrinter.cpp | 6 ++-- lib/Target/SystemZ/SystemZInstrInfo.cpp | 18 +++++++----- lib/Target/SystemZ/SystemZInstrInfo.h | 22 ++++++++++---- lib/Target/SystemZ/SystemZLongBranch.cpp | 2 +- .../SystemZ/SystemZMachineScheduler.cpp | 4 +-- lib/Target/X86/X86ISelLowering.cpp | 29 +++++++++++++++---- .../Vectorize/LoopVectorizationLegality.cpp | 1 + 9 files changed, 62 insertions(+), 26 deletions(-) diff --git a/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h index b144006e2628..d7c1c2738ffe 100644 --- a/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h +++ b/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h @@ -452,8 +452,8 @@ class LoopVectorizationLegality { /// Holds the widest induction type encountered. Type *WidestIndTy = nullptr; - /// Allowed outside users. This holds the induction and reduction - /// vars which can be accessed from outside the loop. + /// Allowed outside users. This holds the variables that can be accessed from + /// outside the loop. SmallPtrSet AllowedExit; /// Can we assume the absence of NaNs. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 3c02c36a7d26..4120a401b696 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1810,7 +1810,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) { // offsets to its parts don't wrap either. SDValue Ptr = DAG.getObjectPtrOffset(getCurSDLoc(), RetPtr, Offsets[i]); - SDValue Val = RetOp.getValue(i); + SDValue Val = RetOp.getValue(RetOp.getResNo() + i); if (MemVTs[i] != ValueVTs[i]) Val = DAG.getPtrExtOrTrunc(Val, getCurSDLoc(), MemVTs[i]); Chains[i] = DAG.getStore(Chain, getCurSDLoc(), Val, diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index bd87ce06b4fb..269b84b4e8d8 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -866,8 +866,10 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *Exp = - MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, - OutContext); + MCSymbolRefExpr::create(MOSymbol, + isPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO + : MCSymbolRefExpr::VK_PPC_GOT_TPREL, + OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 57c1cf4ec70a..8df19286965b 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -468,7 +468,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, // Can't handle indirect branches. SystemZII::Branch Branch(getBranchInfo(*I)); - if (!Branch.Target->isMBB()) + if (!Branch.hasMBBTarget()) return true; // Punt on compound branches. @@ -478,7 +478,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, if (Branch.CCMask == SystemZ::CCMASK_ANY) { // Handle unconditional branches. if (!AllowModify) { - TBB = Branch.Target->getMBB(); + TBB = Branch.getMBBTarget(); continue; } @@ -490,7 +490,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, FBB = nullptr; // Delete the JMP if it's equivalent to a fall-through. - if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { + if (MBB.isLayoutSuccessor(Branch.getMBBTarget())) { TBB = nullptr; I->eraseFromParent(); I = MBB.end(); @@ -498,7 +498,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, } // TBB is used to indicate the unconditinal destination. - TBB = Branch.Target->getMBB(); + TBB = Branch.getMBBTarget(); continue; } @@ -506,7 +506,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, if (Cond.empty()) { // FIXME: add X86-style branch swap FBB = TBB; - TBB = Branch.Target->getMBB(); + TBB = Branch.getMBBTarget(); Cond.push_back(MachineOperand::CreateImm(Branch.CCValid)); Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); continue; @@ -517,7 +517,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, // Only handle the case where all conditional branches branch to the same // destination. - if (TBB != Branch.Target->getMBB()) + if (TBB != Branch.getMBBTarget()) return true; // If the conditions are the same, we can leave them alone. @@ -547,7 +547,7 @@ unsigned SystemZInstrInfo::removeBranch(MachineBasicBlock &MBB, continue; if (!I->isBranch()) break; - if (!getBranchInfo(*I).Target->isMBB()) + if (!getBranchInfo(*I).hasMBBTarget()) break; // Remove the branch. I->eraseFromParent(); @@ -1545,6 +1545,10 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const { return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP, MI.getOperand(2).getImm(), &MI.getOperand(3)); + case SystemZ::INLINEASM_BR: + // Don't try to analyze asm goto, so pass nullptr as branch target argument. + return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr); + default: llvm_unreachable("Unrecognized branch opcode"); } diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 2edde175542e..134ed38a41aa 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -100,11 +100,18 @@ enum BranchType { // An instruction that decrements a 64-bit register and branches if // the result is nonzero. - BranchCTG + BranchCTG, + + // An instruction representing an asm goto statement. + AsmGoto }; // Information about a branch instruction. -struct Branch { +class Branch { + // The target of the branch. In case of INLINEASM_BR, this is nullptr. + const MachineOperand *Target; + +public: // The type of the branch. BranchType Type; @@ -114,12 +121,15 @@ struct Branch { // CCMASK_ is set if the branch should be taken when CC == N. unsigned CCMask; - // The target of the branch. - const MachineOperand *Target; - Branch(BranchType type, unsigned ccValid, unsigned ccMask, const MachineOperand *target) - : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {} + : Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {} + + bool isIndirect() { return Target != nullptr && Target->isReg(); } + bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); } + MachineBasicBlock *getMBBTarget() { + return hasMBBTarget() ? Target->getMBB() : nullptr; + } }; // Kinds of fused compares in compare-and-* instructions. Together with type diff --git a/lib/Target/SystemZ/SystemZLongBranch.cpp b/lib/Target/SystemZ/SystemZLongBranch.cpp index 95d7e22dec32..dcaf629d240a 100644 --- a/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -257,7 +257,7 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) { } Terminator.Branch = &MI; Terminator.TargetBlock = - TII->getBranchInfo(MI).Target->getMBB()->getNumber(); + TII->getBranchInfo(MI).getMBBTarget()->getNumber(); } return Terminator; } diff --git a/lib/Target/SystemZ/SystemZMachineScheduler.cpp b/lib/Target/SystemZ/SystemZMachineScheduler.cpp index 0becfaa1d49c..eb9745f71b7d 100644 --- a/lib/Target/SystemZ/SystemZMachineScheduler.cpp +++ b/lib/Target/SystemZ/SystemZMachineScheduler.cpp @@ -108,8 +108,8 @@ void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) { I != SinglePredMBB->end(); I++) { LLVM_DEBUG(dbgs() << "** Emitting incoming branch: "; I->dump();); bool TakenBranch = (I->isBranch() && - (TII->getBranchInfo(*I).Target->isReg() || // Relative branch - TII->getBranchInfo(*I).Target->getMBB() == MBB)); + (TII->getBranchInfo(*I).isIndirect() || + TII->getBranchInfo(*I).getMBBTarget() == MBB)); HazardRec->emitInstruction(&*I, TakenBranch); if (TakenBranch) break; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index eecf34902ddc..87ff5a719fca 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -33594,7 +33594,7 @@ static SDValue combineShuffleOfConcatUndef(SDNode *N, SelectionDAG &DAG, } /// Eliminate a redundant shuffle of a horizontal math op. -static SDValue foldShuffleOfHorizOp(SDNode *N) { +static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) { unsigned Opcode = N->getOpcode(); if (Opcode != X86ISD::MOVDDUP && Opcode != X86ISD::VBROADCAST) if (Opcode != ISD::VECTOR_SHUFFLE || !N->getOperand(1).isUndef()) @@ -33625,6 +33625,25 @@ static SDValue foldShuffleOfHorizOp(SDNode *N) { HOp.getOperand(0) != HOp.getOperand(1)) return SDValue(); + // The shuffle that we are eliminating may have allowed the horizontal op to + // have an undemanded (undefined) operand. Duplicate the other (defined) + // operand to ensure that the results are defined across all lanes without the + // shuffle. + auto updateHOp = [](SDValue HorizOp, SelectionDAG &DAG) { + SDValue X; + if (HorizOp.getOperand(0).isUndef()) { + assert(!HorizOp.getOperand(1).isUndef() && "Not expecting foldable h-op"); + X = HorizOp.getOperand(1); + } else if (HorizOp.getOperand(1).isUndef()) { + assert(!HorizOp.getOperand(0).isUndef() && "Not expecting foldable h-op"); + X = HorizOp.getOperand(0); + } else { + return HorizOp; + } + return DAG.getNode(HorizOp.getOpcode(), SDLoc(HorizOp), + HorizOp.getValueType(), X, X); + }; + // When the operands of a horizontal math op are identical, the low half of // the result is the same as the high half. If a target shuffle is also // replicating low and high halves, we don't need the shuffle. @@ -33635,7 +33654,7 @@ static SDValue foldShuffleOfHorizOp(SDNode *N) { assert((HOp.getValueType() == MVT::v2f64 || HOp.getValueType() == MVT::v4f64) && HOp.getValueType() == VT && "Unexpected type for h-op"); - return HOp; + return updateHOp(HOp, DAG); } return SDValue(); } @@ -33649,14 +33668,14 @@ static SDValue foldShuffleOfHorizOp(SDNode *N) { (isTargetShuffleEquivalent(Mask, {0, 0}) || isTargetShuffleEquivalent(Mask, {0, 1, 0, 1}) || isTargetShuffleEquivalent(Mask, {0, 1, 2, 3, 0, 1, 2, 3}))) - return HOp; + return updateHOp(HOp, DAG); if (HOp.getValueSizeInBits() == 256 && (isTargetShuffleEquivalent(Mask, {0, 0, 2, 2}) || isTargetShuffleEquivalent(Mask, {0, 1, 0, 1, 4, 5, 4, 5}) || isTargetShuffleEquivalent( Mask, {0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11}))) - return HOp; + return updateHOp(HOp, DAG); return SDValue(); } @@ -33710,7 +33729,7 @@ static SDValue combineShuffle(SDNode *N, SelectionDAG &DAG, if (SDValue AddSub = combineShuffleToAddSubOrFMAddSub(N, Subtarget, DAG)) return AddSub; - if (SDValue HAddSub = foldShuffleOfHorizOp(N)) + if (SDValue HAddSub = foldShuffleOfHorizOp(N, DAG)) return HAddSub; } diff --git a/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp index 6ef8dc2d3cd7..138f18e49c92 100644 --- a/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp +++ b/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp @@ -631,6 +631,7 @@ bool LoopVectorizationLegality::canVectorizeInstrs() { // Unsafe cyclic dependencies with header phis are identified during // legalization for reduction, induction and first order // recurrences. + AllowedExit.insert(&I); continue; } From 668007a2dec842f36eef4b27bb4b18dff3111855 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 7 Sep 2019 11:21:48 +0000 Subject: [PATCH 2/3] Vendor import of clang release_90 branch r371301: https://llvm.org/svn/llvm-project/cfe/branches/release_90@371301 --- include/clang/Basic/DiagnosticDriverKinds.td | 2 -- lib/AST/ASTContext.cpp | 23 +++++++++++++--- lib/Driver/Driver.cpp | 24 ++++++++++------- lib/Driver/ToolChains/Clang.cpp | 26 ++++++++++++------- .../Checkers/EnumCastOutOfRangeChecker.cpp | 16 ++++++++++++ 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index eab453ee20ec..12f1a7f6c488 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -91,8 +91,6 @@ def err_no_external_assembler : Error< "there is no external assembler that can be used on this platform">; def err_drv_unable_to_remove_file : Error< "unable to remove file: %0">; -def err_drv_unable_to_set_working_directory : Error < - "unable to set working directory: %0">; def err_drv_command_failure : Error< "unable to execute command: %0">; def err_drv_invalid_darwin_version : Error< diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 468c7f47657d..93bdaafc2ac6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -9814,10 +9814,25 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, return StrongLinkage; case TSK_ExplicitSpecialization: - return Context.getTargetInfo().getCXXABI().isMicrosoft() && - VD->isStaticDataMember() - ? GVA_StrongODR - : StrongLinkage; + if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { + // If this is a fully specialized constexpr variable template, pretend it + // was marked inline. MSVC 14.21.27702 headers define _Is_integral in a + // header this way, and we don't want to emit non-discardable definitions + // of these variables in every TU that includes . This + // behavior is non-conforming, since another TU could use an extern + // template declaration for this variable, but for constexpr variables, + // it's unlikely for a user to want to do that. This behavior can be + // removed if the headers change to explicitly mark such variable template + // specializations inline. + if (isa(VD) && VD->isConstexpr()) + return GVA_DiscardableODR; + + // Use ODR linkage for static data members of fully specialized templates + // to prevent duplicate definition errors with MSVC. + if (VD->isStaticDataMember()) + return GVA_StrongODR; + } + return StrongLinkage; case TSK_ExplicitInstantiationDefinition: return GVA_StrongODR; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 396ddf4dd816..a9a273529b46 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -133,7 +133,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, // Provide a sane fallback if no VFS is specified. if (!this->VFS) - this->VFS = llvm::vfs::createPhysicalFileSystem().release(); + this->VFS = llvm::vfs::getRealFileSystem(); Name = llvm::sys::path::filename(ClangExecutable); Dir = llvm::sys::path::parent_path(ClangExecutable); @@ -1010,11 +1010,6 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { } } - // Check for working directory option before accessing any files - if (Arg *WD = Args.getLastArg(options::OPT_working_directory)) - if (VFS->setCurrentWorkingDirectory(WD->getValue())) - Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue(); - // FIXME: This stuff needs to go into the Compilation, not the driver. bool CCCPrintPhases; @@ -1995,11 +1990,20 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, if (Value == "-") return true; - if (getVFS().exists(Value)) + SmallString<64> Path(Value); + if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) { + if (!llvm::sys::path::is_absolute(Path)) { + SmallString<64> Directory(WorkDir->getValue()); + llvm::sys::path::append(Directory, Value); + Path.assign(Directory); + } + } + + if (getVFS().exists(Path)) return true; if (IsCLMode()) { - if (!llvm::sys::path::is_absolute(Twine(Value)) && + if (!llvm::sys::path::is_absolute(Twine(Path)) && llvm::sys::Process::FindInEnvPath("LIB", Value)) return true; @@ -2025,12 +2029,12 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, if (getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) <= 1) { Diag(clang::diag::err_drv_no_such_file_with_suggestion) - << Value << Nearest; + << Path << Nearest; return false; } } - Diag(clang::diag::err_drv_no_such_file) << Value; + Diag(clang::diag::err_drv_no_such_file) << Path; return false; } diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 2508178423bf..dd461a1976d9 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -603,15 +603,16 @@ static bool shouldUseLeafFramePointer(const ArgList &Args, } /// Add a CC1 option to specify the debug compilation directory. -static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs, - const llvm::vfs::FileSystem &VFS) { +static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { if (Arg *A = Args.getLastArg(options::OPT_fdebug_compilation_dir)) { CmdArgs.push_back("-fdebug-compilation-dir"); CmdArgs.push_back(A->getValue()); - } else if (llvm::ErrorOr CWD = - VFS.getCurrentWorkingDirectory()) { - CmdArgs.push_back("-fdebug-compilation-dir"); - CmdArgs.push_back(Args.MakeArgString(*CWD)); + } else { + SmallString<128> cwd; + if (!llvm::sys::fs::current_path(cwd)) { + CmdArgs.push_back("-fdebug-compilation-dir"); + CmdArgs.push_back(Args.MakeArgString(cwd)); + } } } @@ -877,8 +878,13 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, else OutputFilename = llvm::sys::path::filename(Output.getBaseInput()); SmallString<128> CoverageFilename = OutputFilename; - if (llvm::sys::path::is_relative(CoverageFilename)) - (void)D.getVFS().makeAbsolute(CoverageFilename); + if (llvm::sys::path::is_relative(CoverageFilename)) { + SmallString<128> Pwd; + if (!llvm::sys::fs::current_path(Pwd)) { + llvm::sys::path::append(Pwd, CoverageFilename); + CoverageFilename.swap(Pwd); + } + } llvm::sys::path::replace_extension(CoverageFilename, "gcno"); CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); @@ -4365,7 +4371,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-autolink"); // Add in -fdebug-compilation-dir if necessary. - addDebugCompDirArg(Args, CmdArgs, D.getVFS()); + addDebugCompDirArg(Args, CmdArgs); addDebugPrefixMapArg(D, Args, CmdArgs); @@ -6092,7 +6098,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo : codegenoptions::NoDebugInfo); // Add the -fdebug-compilation-dir flag if needed. - addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS()); + addDebugCompDirArg(Args, CmdArgs); addDebugPrefixMapArg(getToolChain().getDriver(), Args, CmdArgs); diff --git a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index 736d80ef9ec7..a6539098c89a 100644 --- a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -91,6 +91,22 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C) const { void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE, CheckerContext &C) const { + + // Only perform enum range check on casts where such checks are valid. For + // all other cast kinds (where enum range checks are unnecessary or invalid), + // just return immediately. TODO: The set of casts whitelisted for enum + // range checking may be incomplete. Better to add a missing cast kind to + // enable a missing check than to generate false negatives and have to remove + // those later. + switch (CE->getCastKind()) { + case CK_IntegralCast: + break; + + default: + return; + break; + } + // Get the value of the expression to cast. const llvm::Optional ValueToCast = C.getSVal(CE->getSubExpr()).getAs(); From f5136486a6f241c762d251d39865f5b92d4caf86 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 7 Sep 2019 11:22:03 +0000 Subject: [PATCH 3/3] Vendor import of lld release_90 branch r371301: https://llvm.org/svn/llvm-project/lld/branches/release_90@371301 --- ELF/Writer.cpp | 26 +++--- docs/ReleaseNotes.rst | 195 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 183 insertions(+), 38 deletions(-) diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index b8c8891648a4..10b171e8c0d7 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -2230,25 +2230,27 @@ template void Writer::fixSectionAlignments() { // same with its virtual address modulo the page size, so that the loader can // load executables without any address adjustment. static uint64_t computeFileOffset(OutputSection *os, uint64_t off) { - // File offsets are not significant for .bss sections. By convention, we keep - // section offsets monotonically increasing rather than setting to zero. - if (os->type == SHT_NOBITS) - return off; + // The first section in a PT_LOAD has to have congruent offset and address + // module the page size. + if (os->ptLoad && os->ptLoad->firstSec == os) { + uint64_t alignment = + std::max(os->ptLoad->p_align, config->maxPageSize); + return alignTo(off, alignment, os->addr); + } + + // File offsets are not significant for .bss sections other than the first one + // in a PT_LOAD. By convention, we keep section offsets monotonically + // increasing rather than setting to zero. + if (os->type == SHT_NOBITS) + return off; // If the section is not in a PT_LOAD, we just have to align it. if (!os->ptLoad) return alignTo(off, os->alignment); - // The first section in a PT_LOAD has to have congruent offset and address - // module the page size. - OutputSection *first = os->ptLoad->firstSec; - if (os == first) { - uint64_t alignment = std::max(os->alignment, config->maxPageSize); - return alignTo(off, alignment, os->addr); - } - // If two sections share the same PT_LOAD the file offset is calculated // using this formula: Off2 = Off1 + (VA2 - VA1). + OutputSection *first = os->ptLoad->firstSec; return first->offset + os->addr - first->addr; } diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index ce61cc0d4d74..df00e31bf971 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -8,10 +8,12 @@ lld 9.0.0 Release Notes Introduction ============ -This document contains the release notes for the lld linker, release 9.0.0. -Here we describe the status of lld, including major improvements -from the previous release. All lld releases may be downloaded -from the `LLVM releases web site `_. +lld is a high-performance linker that supports ELF (Unix), COFF +(Windows), Mach-O (macOS), MinGW and WebAssembly. lld is +command-line-compatible with GNU linkers and Microsoft link.exe and is +significantly faster than the system default linkers. + +lld 9 has lots of feature improvements and bug fixes. Non-comprehensive list of changes in this release ================================================= @@ -22,52 +24,187 @@ ELF Improvements * ld.lld now has typo suggestions for flags: ``$ ld.lld --call-shared`` now prints ``unknown argument '--call-shared', did you mean '--call_shared'``. + (`r361518 `_) + +* ``--allow-shlib-undefined`` and ``--no-allow-shlib-undefined`` + options are added. ``--no-allow-shlib-undefined`` is the default for + executables. + (`r352826 `_) + +* ``-nmagic`` and ``-omagic`` options are fully supported. + (`r360593 `_) + +* Segment layout has changed. PT_GNU_RELRO, which was previously + placed in the middle of readable/writable PT_LOAD segments, is now + placed at the beginning of them. This change permits lld-produced + ELF files to be read correctly by GNU strip older than 2.31, which + has a bug to discard a PT_GNU_RELRO in the former layout. + +* ``-z common-page-size`` is supported. + (`r360593 `_) + +* Diagnostics messages have improved. A new flag ``--vs-diagnostics`` + alters the format of diagnostic output to enable source hyperlinks + in Microsoft Visual Studio IDE. + +* Linker script compatibility with GNU BFD linker has generally improved. + +* The clang ``--dependent-library`` form of autolinking is supported. + + This feature is added to implement the Windows-style autolinking for + Unix. On Unix, in order to use a library, you usually have to + include a header file provided by the library and then explicitly + link the library with the linker ``-l`` option. On Windows, header + files usually contain pragmas that list needed libraries. Compilers + copy that information to object files, so that linkers can + automatically link needed libraries. ``--dependent-library`` is + added for implementing that Windows semantics on Unix. + (`r360984 `_) + +* AArch64 BTI and PAC are supported. + (`r362793 `_) * lld now supports replacing ``JAL`` with ``JALX`` instructions in case - of MIPS - microMIPS cross-mode jumps. + of MIPS-microMIPS cross-mode jumps. + (`r354311 `_) * lld now creates LA25 thunks for MIPS R6 code. + (`r354312 `_) * Put MIPS-specific .reginfo, .MIPS.options, and .MIPS.abiflags sections into corresponding PT_MIPS_REGINFO, PT_MIPS_OPTIONS, and PT_MIPS_ABIFLAGS segments. +* The quality of RISC-V and PowerPC ports have greatly improved. Many + applications can now be linked by lld. PowerPC64 is now almost + production ready. + +* The Linux kernel for arm32_7, arm64, ppc64le and x86_64 can now be + linked by lld. + +* x86-64 TLSDESC is supported. + (`r361911 `_, + `r362078 `_) + +* DF_STATIC_TLS flag is set for i386 and x86-64 when needed. + (`r353293 `_, + `r353378 `_) + +* The experimental partitioning feature is added to allow a program to + be split into multiple pieces. + + The feature allows you to semi-automatically split a single program + into multiple ELF files called "partitions". Since all partitions + share the same memory address space and don't use PLT/GOT, split + programs run as fast as regular programs. + + With the mechanism, you can start a program only with a "main" + partition and load remaining partitions on-demand. For example, you + can split a web browser into a main partition and a PDF reader + sub-partition and load the PDF reader partition only when a user + tries to open a PDF file. + + See `the documentation `_ for more information. + +* If "-" is given as an output filename, lld writes the final result + to the standard output. Previously, it created a file "-" in the + current directory. + (`r351852 `_) + +* ``-z ifunc-noplt`` option is added to reduce IFunc function call + overhead in a freestanding environment such as the OS kernel. + + Functions resolved by the IFunc mechanism are usually dispatched via + PLT and thus slower than regular functions because of the cost of + indirection. With ``-z ifunc-noplt``, you can eliminate it by doing + text relocations at load-time. You need a special loader to utilize + this feature. This feature is added for the FreeBSD kernel but can + be used by any operating systems. + (`r360685 `_) + +* ``--undefined-glob`` option is added. The new option is an extension + to ``--undefined`` to take a glob pattern instead of a single symbol + name. + (`r363396 `_) + + COFF Improvements ----------------- * Like the ELF driver, lld-link now has typo suggestions for flags. + (`r361518 `_) -* lld-link now correctly reports duplicate symbol errors for obj files - that were compiled with /Gy. +* lld-link now correctly reports duplicate symbol errors for object + files that were compiled with ``/Gy``. + (`r352590 `_) -* lld-link now correctly reports duplicate symbol errors when several res - input files define resources with the same type, name, and language. - This can be demoted to a warning using ``/force:multipleres``. +* lld-link now correctly reports duplicate symbol errors when several + resource (.res) input files define resources with the same type, + name and language. This can be demoted to a warning using + ``/force:multipleres``. + (`r359829 `_) -* lld-link now rejects more than one resource obj input files, matching - link.exe. Previously, lld-link would silently ignore all but one. - If you hit this: Don't pass resource obj files to the linker, instead pass - res files to the linker directly. Don't put res files in static libraries, - pass them on the command line. +* lld-link now rejects more than one resource object input files, + matching link.exe. Previously, lld-link would silently ignore all + but one. If you hit this: Don't pass resource object files to the + linker, instead pass res files to the linker directly. Don't put + resource files in static libraries, pass them on the command line. + (`r359749 `_) * Having more than two ``/natvis:`` now works correctly; it used to not work for larger binaries before. + (`r327895 `_) * Undefined symbols are now printed only in demangled form. Pass ``/demangle:no`` to see raw symbol names instead. - -* The following flags have been added: ``/functionpadmin``, ``/swaprun:``, - ``/threads:no`` + (`r355878 `_) * Several speed and memory usage improvements. -* Range extension thunks are now created for ARM64, if needed - * lld-link now supports resource object files created by GNU windres and - MS cvtres, not only llvm-cvtres + MS cvtres, not only llvm-cvtres. * The generated thunks for delayimports now share the majority of code - among thunks, significantly reducing the overhead of using delayimport + among thunks, significantly reducing the overhead of using delayimport. + (`r365823 `_) + +* ``IMAGE_REL_ARM{,64}_REL32`` relocations are supported. + (`r352325 `_) + +* Range extension thunks for AArch64 are now supported, so lld can + create large executables for Windows/ARM64. + (`r352929 `_) + +* The following flags have been added: + ``/functionpadmin`` (`r354716 `_), + ``/swaprun:`` (`r359192 `_), + ``/threads:no`` (`r355029 `_), + ``/filealign`` (`r361634 `_) + +WebAssembly Improvements +------------------------ + +* Imports from custom module names are supported. + (`r352828 `_) + +* Symbols that are in llvm.used are now exported by default. + (`r353364 `_) + +* Initial support for PIC and dynamic linking has landed. + (`r357022 `_) + +* wasm-ld now add ``__start_``/``__stop_`` symbols for data sections. + (`r361236 `_) + +* wasm-ld now doesn't report an error on archives without a symbol index. + (`r364338 `_) + +* The following flags have been added: + ``--emit-relocs`` (`r361635 `_), + ``--wrap`` (`r361639 `_), + ``--trace`` and ``--trace-symbol`` + (`r353264 `_). + MinGW Improvements ------------------ @@ -77,12 +214,18 @@ MinGW Improvements DWARF exception handling with libgcc and gcc's crtend.o. * lld now also handles DWARF unwind info generated by GCC, when linking - with libgcc - -* Many more GNU ld options are now supported, which e.g. allows the lld - MinGW frontend to be called by GCC + with libgcc. * PDB output can be requested without manually specifying the PDB file name, with the new option ``-pdb=`` with an empty value to the option. (The old existing syntax ``-pdb `` was more cumbersome to use with an empty parameter value.) + +* ``--no-insert-timestamp`` option is added as an alias to ``/timestamp:0``. + (`r353145 `_) + +* Many more GNU ld options are now supported, which e.g. allows the lld + MinGW frontend to be called by GCC. + +* The following options are added: ``--exclude-all-symbols``, + ``--appcontainer``, ``--undefined``