Add all patches from base llvm/clang/lld/lldb 6.0 to devel/llvm60

This adds all the patches that were applied in the past to head, under
contrib/llvm.  After these, there only minimal diffs left between the
port sources and the base sources.

Most of these remaining diffs are due to #ifdef shortcuts in the base
sources, because we don't compile certain features in.  Other diffs are
because the port has applied a few changes that we don't have in base.

While here, use Makefile.LICENSE from the devel/llvm-devel port.

Approved by:	brooks (maintainer)
Reviewed by:	brooks
PR:		212343, 225128, 225471, 226388, 226658, 226872, 229050, 230444, 230604, 231355
MFH:		2018Q4
Differential Revision: https://reviews.freebsd.org/D17702
This commit is contained in:
Dimitry Andric 2018-10-26 21:20:02 +00:00
parent 133a6110fa
commit a702c15488
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=483054
24 changed files with 1835 additions and 5 deletions

View file

@ -2,7 +2,7 @@
PORTNAME= llvm
DISTVERSION= 6.0.1
PORTREVISION= 2
PORTREVISION= 3
CATEGORIES= devel lang
MASTER_SITES= http://${PRE_}releases.llvm.org/${LLVM_RELEASE}/${RCDIR}
PKGNAMESUFFIX= ${LLVM_SUFFIX}
@ -12,10 +12,7 @@ DISTFILES= ${PORTNAME}-${DISTVERSION}.src${EXTRACT_SUFX}
MAINTAINER= brooks@FreeBSD.org
COMMENT= LLVM and Clang
LICENSE= LLVM
LICENSE_NAME= LLVM Release License
LICENSE_FILE= ${WRKSRC}/LICENSE.TXT
LICENSE_PERMS= dist-mirror dist-sell pkg-mirror pkg-sell auto-accept
.include "${.CURDIR}/../llvm-devel/Makefile.LICENSE"
LLVM_RELEASE= ${DISTVERSION:C/rc.*//}
LLVM_MAJOR= ${LLVM_RELEASE:C/\.[0-9]$//}
@ -84,10 +81,12 @@ LIT_DESC= Install lit and FileCheck test tools
LIT_VARS= _USES_PYTHON=python:2.7
LLD_DESC= Install lld, the LLVM linker
LLD_DISTFILES= lld-${DISTVERSION}.src${EXTRACT_SUFX}
LLD_EXTRA_PATCHES= ${PATCHDIR}/lld
LLDB_BUILD_DEPENDS= swig3.0:devel/swig30 \
${PY_ENUM34}
LLDB_DESC= Install lldb, the LLVM debugger
LLDB_DISTFILES= lldb-${DISTVERSION}.src${EXTRACT_SUFX}
LLDB_EXTRA_PATCHES= ${PATCHDIR}/lldb
LLDB_IMPLIES= CLANG
LLDB_VARS= _USES_PYTHON=python:2.7
OPENMP_DESC= Install libomp, the LLVM OpenMP runtime library
@ -228,6 +227,7 @@ CLANG_PATTERN= (c-index-test|clang|scan-|Reporter.py|ScanView.py|scanview.css|so
SHEBANG_FILES+= tools/clang/tools/scan-view/bin/scan-view \
tools/clang/tools/clang-format/git-clang-format \
tools/clang/tools/clang-format/clang-format-diff.py
USES+= gnome
.endif
.if ${PORT_OPTIONS:MCOMPILER_RT}

View file

@ -0,0 +1,40 @@
r331066 | dim | 2018-03-16 19:04:13 +0100 (Fri, 16 Mar 2018) | 19 lines
Pull in r321999 from upstream clang trunk (by Ivan A. Kosarev):
[CodeGen] Fix TBAA info for accesses to members of base classes
Resolves:
Bug 35724 - regression (r315984): fatal error: error in backend:
Broken function found (Did not see access type in access path!)
https://bugs.llvm.org/show_bug.cgi?id=35724
Differential Revision: https://reviews.llvm.org/D41547
This fixes "Did not see access type in access path" fatal errors when
building the devel/gdb port (version 8.1).
Reported by: jbeich
PR: 226658
MFC after: 3 months
X-MFC-With: r327952
Index: tools/clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- tools/clang/lib/CodeGen/CGExpr.cpp (revision 331065)
+++ tools/clang/lib/CodeGen/CGExpr.cpp (revision 331066)
@@ -1034,8 +1034,12 @@ Address CodeGenFunction::EmitPointerWithAlignment(
// Derived-to-base conversions.
case CK_UncheckedDerivedToBase:
case CK_DerivedToBase: {
- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo,
- TBAAInfo);
+ // TODO: Support accesses to members of base classes in TBAA. For now, we
+ // conservatively pretend that the complete object is of the base class
+ // type.
+ if (TBAAInfo)
+ *TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
+ Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
return GetAddressOfBaseClass(Addr, Derived,
CE->path_begin(), CE->path_end(),

View file

@ -0,0 +1,42 @@
r336227 | dim | 2018-07-12 21:02:59 +0200 (Thu, 12 Jul 2018) | 27 lines
Pull in r336008 from upstream clang trunk:
Request init/fini array on FreeBSD 12 and later
Summary:
It seems a bad idea to change the default in the middle of a release
branch due to possible changes in global ctor / dtor ordering between
.ctors and .init_array. With FreeBSD 11.0's release imminent lets
change the default now for FreeBSD 12 (the current development
stream) and later.
FreeBSD rtld has supported .init_array / .fini_array for many years.
As of Jan 1 2017 all supported FreeBSD releases and branches will
have support.
Reviewers: dim, brooks, arichardson
Reviewed By: dim, brooks, arichardson
Subscribers: bsdjhb, krytarowski, emaste, cfe-commits
Differential Revision: https://reviews.llvm.org/D24867
Requested by: jhb
MFC after: 3 days
Index: tools/clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336226)
+++ tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336227)
@@ -2375,6 +2375,8 @@ void Generic_ELF::addClangTargetOptions(const ArgL
bool UseInitArrayDefault =
getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getArch() == llvm::Triple::aarch64_be ||
+ (getTriple().getOS() == llvm::Triple::FreeBSD &&
+ getTriple().getOSMajorVersion() >= 12) ||
(getTriple().getOS() == llvm::Triple::Linux &&
((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) ||
getTriple().isAndroid())) ||

View file

@ -0,0 +1,104 @@
r338697 | dim | 2018-09-15 23:22:50 +0200 (Sat, 15 Sep 2018) | 21 lines
Pull in r325478 from upstream clang trunk (by Ivan A. Kosarev):
[CodeGen] Initialize large arrays by copying from a global
Currently, clang compiles explicit initializers for array elements
into series of store instructions. For large arrays of built-in types
this results in bloated output code and significant amount of time
spent on the instruction selection phase. This patch fixes the issue
by initializing such arrays with global constants that store the
binary image of the initializer.
Differential Revision: https://reviews.llvm.org/D43181
This should fix a compiler hang (and excessive memory usage) while
building the science/rmg port.
Approved by: re (kib)
Reported by: yuri@tsoft.com
See also: https://bugs.llvm.org/show_bug.cgi?id=38798
MFC after: 3 days
Index: tools/clang/lib/CodeGen/CGExprAgg.cpp
===================================================================
--- tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338696)
+++ tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338697)
@@ -14,6 +14,7 @@
#include "CodeGenFunction.h"
#include "CGObjCRuntime.h"
#include "CodeGenModule.h"
+#include "ConstantEmitter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
@@ -85,7 +86,7 @@ class AggExprEmitter : public StmtVisitor<AggExprE
void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
- QualType elementType, InitListExpr *E);
+ QualType ArrayQTy, InitListExpr *E);
AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
@@ -392,12 +393,15 @@ static bool isTrivialFiller(Expr *E) {
/// \brief Emit initialization of an array from an initializer list.
void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
- QualType elementType, InitListExpr *E) {
+ QualType ArrayQTy, InitListExpr *E) {
uint64_t NumInitElements = E->getNumInits();
uint64_t NumArrayElements = AType->getNumElements();
assert(NumInitElements <= NumArrayElements);
+ QualType elementType =
+ CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
+
// DestPtr is an array*. Construct an elementType* by drilling
// down a level.
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
@@ -409,6 +413,29 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr
CharUnits elementAlign =
DestPtr.getAlignment().alignmentOfArrayElement(elementSize);
+ // Consider initializing the array by copying from a global. For this to be
+ // more efficient than per-element initialization, the size of the elements
+ // with explicit initializers should be large enough.
+ if (NumInitElements * elementSize.getQuantity() > 16 &&
+ elementType.isTriviallyCopyableType(CGF.getContext())) {
+ CodeGen::CodeGenModule &CGM = CGF.CGM;
+ ConstantEmitter Emitter(CGM);
+ LangAS AS = ArrayQTy.getAddressSpace();
+ if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
+ auto GV = new llvm::GlobalVariable(
+ CGM.getModule(), C->getType(),
+ CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
+ llvm::GlobalValue::PrivateLinkage, C, "constinit",
+ /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal,
+ CGM.getContext().getTargetAddressSpace(AS));
+ Emitter.finalize(GV);
+ CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy);
+ GV->setAlignment(Align.getQuantity());
+ EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align));
+ return;
+ }
+ }
+
// Exception safety requires us to destroy all the
// already-constructed members if an initializer throws.
// For that, we'll need an EH cleanup.
@@ -1156,11 +1183,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExp
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
- QualType elementType =
- CGF.getContext().getAsArrayType(E->getType())->getElementType();
-
auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
- EmitArrayInit(Dest.getAddress(), AType, elementType, E);
+ EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
return;
}

View file

@ -0,0 +1,30 @@
r339019 | emaste | 2018-09-29 22:01:23 +0200 (Sat, 29 Sep 2018) | 15 lines
clang: allow ifunc resolvers to accept arguments
Previously Clang required ifunc resolution functions to take no
arguments, presumably because GCC documented ifunc resolvers as taking
no arguments. However, GCC accepts resolvers accepting arguments, and
our rtld passes CPU ID information (cpuid, hwcap, etc.) to ifunc
resolvers. Just remove the check from the in-tree compiler for our in-
tree compiler; a different (per-OS) approach may be required upstream.
Reported by: mjg
Approved by: re (rgrimes)
MFC after: 1 week
Relnotes: Yes
Sponsored by: The FreeBSD Foundation
Index: tools/clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339018)
+++ tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339019)
@@ -321,8 +321,6 @@ void CodeGenModule::checkAliases() {
assert(FTy);
if (!FTy->getReturnType()->isPointerTy())
Diags.Report(Location, diag::err_ifunc_resolver_return);
- if (FTy->getNumParams())
- Diags.Report(Location, diag::err_ifunc_resolver_params);
}
llvm::Constant *Aliasee = Alias->getIndirectSymbol();

View file

@ -0,0 +1,67 @@
r331731 | dim | 2018-03-29 15:55:23 +0200 (Thu, 29 Mar 2018) | 22 lines
Pull in r328738 from upstream lld trunk (by Rafael Espindola):
Strip @VER suffices from the LTO output.
This fixes pr36623.
The problem is that we have to parse versions out of names before LTO
so that LTO can use that information.
When we get the LTO produced .o files, we replace the previous symbols
with the LTO produced ones, but they still have @ in their names.
We could just trim the name directly, but calling parseSymbolVersion
to do it is simpler.
This is a follow-up to r331366, since we discovered that lld could
append version strings to symbols twice, when using Link Time
Optimization.
MFC after: 3 months
X-MFC-With: r327952
Index: tools/lld/ELF/InputFiles.cpp
===================================================================
--- tools/lld/ELF/InputFiles.cpp (revision 331730)
+++ tools/lld/ELF/InputFiles.cpp (revision 331731)
@@ -281,6 +281,10 @@ template <class ELFT> ArrayRef<Symbol *> ObjFile<E
return makeArrayRef(this->Symbols).slice(1, this->FirstNonLocal - 1);
}
+template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
+ return makeArrayRef(this->Symbols).slice(this->FirstNonLocal);
+}
+
template <class ELFT>
void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
// Read section and symbol tables.
Index: tools/lld/ELF/InputFiles.h
===================================================================
--- tools/lld/ELF/InputFiles.h (revision 331730)
+++ tools/lld/ELF/InputFiles.h (revision 331731)
@@ -167,6 +167,7 @@ template <class ELFT> class ObjFile : public ELFFi
static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
ArrayRef<Symbol *> getLocalSymbols();
+ ArrayRef<Symbol *> getGlobalSymbols();
ObjFile(MemoryBufferRef M, StringRef ArchiveName);
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
Index: tools/lld/ELF/SymbolTable.cpp
===================================================================
--- tools/lld/ELF/SymbolTable.cpp (revision 331730)
+++ tools/lld/ELF/SymbolTable.cpp (revision 331731)
@@ -130,7 +130,10 @@ template <class ELFT> void SymbolTable::addCombine
for (InputFile *File : LTO->compile()) {
DenseSet<CachedHashStringRef> DummyGroups;
- cast<ObjFile<ELFT>>(File)->parse(DummyGroups);
+ auto *Obj = cast<ObjFile<ELFT>>(File);
+ Obj->parse(DummyGroups);
+ for (Symbol *Sym : Obj->getGlobalSymbols())
+ Sym->parseSymbolVersion();
ObjectFiles.push_back(File);
}
}

View file

@ -0,0 +1,34 @@
r333401 | emaste | 2018-05-09 13:17:01 +0200 (Wed, 09 May 2018) | 19 lines
lld: Omit PT_NOTE for SHT_NOTE without SHF_ALLOC
A non-alloc note section should not have a PT_NOTE program header.
Found while linking ghc (Haskell compiler) with lld on FreeBSD. Haskell
emits a .debug-ghc-link-info note section (as the name suggests, it
contains link info) as a SHT_NOTE section without SHF_ALLOC set.
For this case ld.bfd does not emit a PT_NOTE segment for
.debug-ghc-link-info. lld previously emitted a PT_NOTE with p_vaddr = 0
and FreeBSD's rtld segfaulted when trying to parse a note at address 0.
LLVM PR: https://llvm.org/pr37361
LLVM review: https://reviews.llvm.org/D46623
PR: 226872
Reviewed by: dim
Sponsored by: The FreeBSD Foundation
Index: tools/lld/ELF/Writer.cpp
===================================================================
--- tools/lld/ELF/Writer.cpp (revision 333400)
+++ tools/lld/ELF/Writer.cpp (revision 333401)
@@ -1708,7 +1708,7 @@ template <class ELFT> std::vector<PhdrEntry *> Wri
// Create one PT_NOTE per a group of contiguous .note sections.
PhdrEntry *Note = nullptr;
for (OutputSection *Sec : OutputSections) {
- if (Sec->Type == SHT_NOTE) {
+ if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
if (!Note || Sec->LMAExpr)
Note = AddHdr(PT_NOTE, PF_R);
Note->add(Sec);

View file

@ -0,0 +1,52 @@
r336664 | emaste | 2018-07-24 13:35:22 +0200 (Tue, 24 Jul 2018) | 11 lines
lld: fix addends with partial linking
[ELF] Update addends in non-allocatable sections for REL targets when
creating a relocatable output.
LLVM PR: 37735
LLVM Differential Revision: https://reviews.llvm.org/D48929
PR: 225128
Obtained from: LLVM r336799 by Igor Kudrin
Index: tools/lld/ELF/InputSection.cpp
===================================================================
--- tools/lld/ELF/InputSection.cpp (revision 336663)
+++ tools/lld/ELF/InputSection.cpp (revision 336664)
@@ -686,6 +686,23 @@ void InputSection::relocateNonAlloc(uint8_t *Buf,
}
}
+// This is used when '-r' is given.
+// For REL targets, InputSection::copyRelocations() may store artificial
+// relocations aimed to update addends. They are handled in relocateAlloc()
+// for allocatable sections, and this function does the same for
+// non-allocatable sections, such as sections with debug information.
+static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
+ const unsigned Bits = Config->Is64 ? 64 : 32;
+
+ for (const Relocation &Rel : Sec->Relocations) {
+ // InputSection::copyRelocations() adds only R_ABS relocations.
+ assert(Rel.Expr == R_ABS);
+ uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
+ uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
+ Target->relocateOne(BufLoc, Rel.Type, TargetVA);
+ }
+}
+
template <class ELFT>
void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
if (Flags & SHF_ALLOC) {
@@ -694,7 +711,9 @@ void InputSectionBase::relocate(uint8_t *Buf, uint
}
auto *Sec = cast<InputSection>(this);
- if (Sec->AreRelocsRela)
+ if (Config->Relocatable)
+ relocateNonAllocForRelocatable(Sec, Buf);
+ else if (Sec->AreRelocsRela)
Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
else
Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());

View file

@ -0,0 +1,146 @@
r336972 | emaste | 2018-07-31 17:25:03 +0200 (Tue, 31 Jul 2018) | 37 lines
lld: [ELF][ARM] Implement support for Tag_ABI_VFP_args
The Tag_ABI_VFP_args build attribute controls the procedure call
standard used for floating point parameters on ARM. The values are:
0 - Base AAPCS (FP Parameters passed in Core (Integer) registers
1 - VFP AAPCS (FP Parameters passed in FP registers)
2 - Toolchain specific (Neither Base or VFP)
3 - Compatible with all (No use of floating point parameters)
If the Tag_ABI_VFP_args build attribute is missing it has an implicit
value of 0.
We use the attribute in two ways:
* Detect a clash in calling convention between Base, VFP and Toolchain.
we follow ld.bfd's lead and do not error if there is a clash between an
implicit Base AAPCS caused by a missing attribute. Many projects
including the hard-float (VFP AAPCS) version of glibc contain assembler
files that do not use floating point but do not have Tag_ABI_VFP_args.
* Set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD ELF header flag
for Base or VFP AAPCS respectively. This flag is used by some ELF
loaders.
References:
* Addenda to, and Errata in, the ABI for the ARM Architecture for
Tag_ABI_VFP_args
* Elf for the ARM Architecture for ELF header flags
Fixes LLVM PR36009
PR: 229050
Obtained from: llvm r338377 by Peter Smith
Index: tools/lld/ELF/Arch/ARM.cpp
===================================================================
--- tools/lld/ELF/Arch/ARM.cpp (revision 336971)
+++ tools/lld/ELF/Arch/ARM.cpp (revision 336972)
@@ -97,10 +97,19 @@ ARM::ARM() {
}
uint32_t ARM::calcEFlags() const {
+ // The ABIFloatType is used by loaders to detect the floating point calling
+ // convention.
+ uint32_t ABIFloatType = 0;
+ if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
+ Config->ARMVFPArgs == ARMVFPArgKind::Default)
+ ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
+ else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
+ ABIFloatType = EF_ARM_ABI_FLOAT_HARD;
+
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
// but we don't have any firm guarantees of conformance. Linux AArch64
// kernels (as of 2016) require an EABI version to be set.
- return EF_ARM_EABI_VER5;
+ return EF_ARM_EABI_VER5 | ABIFloatType;
}
RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
Index: tools/lld/ELF/Config.h
===================================================================
--- tools/lld/ELF/Config.h (revision 336971)
+++ tools/lld/ELF/Config.h (revision 336972)
@@ -54,6 +54,9 @@ enum class SortSectionPolicy { Default, None, Alig
// For --target2
enum class Target2Policy { Abs, Rel, GotRel };
+// For tracking ARM Float Argument PCS
+enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
+
struct SymbolVersion {
llvm::StringRef Name;
bool IsExternCpp;
@@ -169,6 +172,7 @@ struct Configuration {
StripPolicy Strip;
UnresolvedPolicy UnresolvedSymbols;
Target2Policy Target2;
+ ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
BuildIdKind BuildId = BuildIdKind::None;
ELFKind EKind = ELFNoneKind;
uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
Index: tools/lld/ELF/InputFiles.cpp
===================================================================
--- tools/lld/ELF/InputFiles.cpp (revision 336971)
+++ tools/lld/ELF/InputFiles.cpp (revision 336972)
@@ -441,6 +441,46 @@ void ObjFile<ELFT>::initializeSections(
}
}
+// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
+// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
+// the input objects have been compiled.
+static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
+ const InputFile *F) {
+ if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
+ // If an ABI tag isn't present then it is implicitly given the value of 0
+ // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
+ // including some in glibc that don't use FP args (and should have value 3)
+ // don't have the attribute so we do not consider an implicit value of 0
+ // as a clash.
+ return;
+
+ unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
+ ARMVFPArgKind Arg;
+ switch (VFPArgs) {
+ case ARMBuildAttrs::BaseAAPCS:
+ Arg = ARMVFPArgKind::Base;
+ break;
+ case ARMBuildAttrs::HardFPAAPCS:
+ Arg = ARMVFPArgKind::VFP;
+ break;
+ case ARMBuildAttrs::ToolChainFPPCS:
+ // Tool chain specific convention that conforms to neither AAPCS variant.
+ Arg = ARMVFPArgKind::ToolChain;
+ break;
+ case ARMBuildAttrs::CompatibleFPAAPCS:
+ // Object compatible with all conventions.
+ return;
+ default:
+ error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
+ return;
+ }
+ // Follow ld.bfd and error if there is a mix of calling conventions.
+ if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
+ error(toString(F) + ": incompatible Tag_ABI_VFP_args");
+ else
+ Config->ARMVFPArgs = Arg;
+}
+
// The ARM support in lld makes some use of instructions that are not available
// on all ARM architectures. Namely:
// - Use of BLX instruction for interworking between ARM and Thumb state.
@@ -520,6 +560,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSectio
ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
updateSupportedARMFeatures(Attributes);
+ updateARMVFPArgs(Attributes, this);
+
// FIXME: Retain the first attribute section we see. The eglibc ARM
// dynamic loaders require the presence of an attribute section for dlopen
// to work. In a full implementation we would merge all attribute sections.

View file

@ -0,0 +1,39 @@
r337282 | alc | 2018-08-04 04:30:51 +0200 (Sat, 04 Aug 2018) | 7 lines
Set the default image base on arm64 and i386 to a superpage-aligned
address.
Reviewed by: emaste, markj
Discussed with: dim
Differential Revision: https://reviews.freebsd.org/D16385
Index: tools/lld/ELF/Arch/AArch64.cpp
===================================================================
--- tools/lld/ELF/Arch/AArch64.cpp (revision 337281)
+++ tools/lld/ELF/Arch/AArch64.cpp (revision 337282)
@@ -66,6 +66,10 @@ AArch64::AArch64() {
PltHeaderSize = 32;
DefaultMaxPageSize = 65536;
+ // Align to the 2 MiB page size (known as a superpage or huge page).
+ // FreeBSD automatically promotes 2 MiB-aligned allocations.
+ DefaultImageBase = 0x200000;
+
// It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
// 1 of the tls structures and the tcb size is 16.
TcbSize = 16;
Index: tools/lld/ELF/Arch/X86.cpp
===================================================================
--- tools/lld/ELF/Arch/X86.cpp (revision 337281)
+++ tools/lld/ELF/Arch/X86.cpp (revision 337282)
@@ -61,6 +61,10 @@ X86::X86() {
PltHeaderSize = 16;
TlsGdRelaxSkip = 2;
TrapInstr = 0xcccccccc; // 0xcc = INT3
+
+ // Align to the non-PAE large page size (known as a superpage or huge page).
+ // FreeBSD automatically promotes large, superpage-aligned allocations.
+ DefaultImageBase = 0x400000;
}
static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }

View file

@ -0,0 +1,123 @@
r338251 | markj | 2018-08-23 16:58:19 +0200 (Thu, 23 Aug 2018) | 29 lines
Add an lld option to emit PC-relative relocations for ifunc calls.
The current kernel ifunc implementation creates a PLT entry for each
ifunc definition. ifunc calls therefore consist of a call to the
PLT entry followed by an indirect jump. The jump target is written
during boot when the kernel linker resolves R_[*]_IRELATIVE relocations.
This implementation is defined by requirements for userland code, where
text relocations are avoided. This requirement is not present for the
kernel, so the implementation has avoidable overhead (namely, an extra
indirect jump per call).
Address this for now by adding a special option to the static linker
to inhibit PLT creation for ifuncs. Instead, relocations to ifunc call
sites are passed through to the output file, so the kernel linker can
enumerate such call sites and apply PC-relative relocations directly
to the text section. Thus the overhead of an ifunc call becomes exactly
the same as that of an ordinary function call. This option is only for
use by the kernel and will not work for regular programs.
The final form of this optimization is up for debate; for now, this
change is simple and static enough to be acceptable as an interim
solution.
Reviewed by: emaste
Discussed with: arichardson, dim
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D16748
Index: tools/lld/ELF/Config.h
===================================================================
--- tools/lld/ELF/Config.h (revision 338250)
+++ tools/lld/ELF/Config.h (revision 338251)
@@ -155,6 +155,7 @@ struct Configuration {
bool ZCombreloc;
bool ZExecstack;
bool ZHazardplt;
+ bool ZIfuncnoplt;
bool ZNocopyreloc;
bool ZNodelete;
bool ZNodlopen;
Index: tools/lld/ELF/Driver.cpp
===================================================================
--- tools/lld/ELF/Driver.cpp (revision 338250)
+++ tools/lld/ELF/Driver.cpp (revision 338251)
@@ -669,6 +669,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &
Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
Config->ZExecstack = hasZOption(Args, "execstack");
Config->ZHazardplt = hasZOption(Args, "hazardplt");
+ Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
Config->ZNodelete = hasZOption(Args, "nodelete");
Config->ZNodlopen = hasZOption(Args, "nodlopen");
Index: tools/lld/ELF/Relocations.cpp
===================================================================
--- tools/lld/ELF/Relocations.cpp (revision 338250)
+++ tools/lld/ELF/Relocations.cpp (revision 338251)
@@ -374,6 +374,9 @@ static bool isStaticLinkTimeConstant(RelExpr E, Re
R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
return true;
+ if (Sym.isGnuIFunc() && Config->ZIfuncnoplt)
+ return false;
+
// These never do, except if the entire file is position dependent or if
// only the low bits are used.
if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
@@ -921,7 +924,9 @@ static void scanRelocs(InputSectionBase &Sec, Arra
// Strenghten or relax a PLT access.
//
// GNU ifunc symbols must be accessed via PLT because their addresses
- // are determined by runtime.
+ // are determined by runtime. If the -z ifunc-noplt option is specified,
+ // we permit the optimization of ifunc calls by omitting the PLT entry
+ // and preserving relocations at ifunc call sites.
//
// On the other hand, if we know that a PLT entry will be resolved within
// the same ELF module, we can skip PLT access and directly jump to the
@@ -929,7 +934,7 @@ static void scanRelocs(InputSectionBase &Sec, Arra
// all dynamic symbols that can be resolved within the executable will
// actually be resolved that way at runtime, because the main exectuable
// is always at the beginning of a search list. We can leverage that fact.
- if (Sym.isGnuIFunc())
+ if (Sym.isGnuIFunc() && !Config->ZIfuncnoplt)
Expr = toPlt(Expr);
else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
Expr =
@@ -1034,6 +1039,16 @@ static void scanRelocs(InputSectionBase &Sec, Arra
continue;
}
+ // Preserve relocations against ifuncs if we were asked to do so.
+ if (Sym.isGnuIFunc() && Config->ZIfuncnoplt) {
+ if (Config->IsRela)
+ InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, Addend});
+ else
+ // Preserve the existing addend.
+ InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, 0});
+ continue;
+ }
+
// If the output being produced is position independent, the final value
// is still not known. In that case we still need some help from the
// dynamic linker. We can however do better than just copying the incoming
Index: tools/lld/ELF/Writer.cpp
===================================================================
--- tools/lld/ELF/Writer.cpp (revision 338250)
+++ tools/lld/ELF/Writer.cpp (revision 338251)
@@ -1400,8 +1400,11 @@ template <class ELFT> void Writer<ELFT>::finalizeS
applySynthetic({InX::EhFrame},
[](SyntheticSection *SS) { SS->finalizeContents(); });
- for (Symbol *S : Symtab->getSymbols())
+ for (Symbol *S : Symtab->getSymbols()) {
S->IsPreemptible |= computeIsPreemptible(*S);
+ if (S->isGnuIFunc() && Config->ZIfuncnoplt)
+ S->ExportDynamic = true;
+ }
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.

View file

@ -0,0 +1,55 @@
r338682 | emaste | 2018-09-14 17:15:16 +0200 (Fri, 14 Sep 2018) | 16 lines
lld: add -z interpose support
-z interpose sets the DF_1_INTERPOSE flag, marking the object as an
interposer.
Committed upstream as LLVM r342239.
PR: 230604
Reported by: jbeich
Reviewed by: markj
Approved by: re (kib)
MFC after: 1 week
Relnotes: Yes
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D17172
Index: tools/lld/ELF/Config.h
===================================================================
--- tools/lld/ELF/Config.h (revision 338681)
+++ tools/lld/ELF/Config.h (revision 338682)
@@ -156,6 +156,7 @@ struct Configuration {
bool ZExecstack;
bool ZHazardplt;
bool ZIfuncnoplt;
+ bool ZInterpose;
bool ZNocopyreloc;
bool ZNodelete;
bool ZNodlopen;
Index: tools/lld/ELF/Driver.cpp
===================================================================
--- tools/lld/ELF/Driver.cpp (revision 338681)
+++ tools/lld/ELF/Driver.cpp (revision 338682)
@@ -670,6 +670,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &
Config->ZExecstack = hasZOption(Args, "execstack");
Config->ZHazardplt = hasZOption(Args, "hazardplt");
Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
+ Config->ZInterpose = hasZOption(Args, "interpose");
Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
Config->ZNodelete = hasZOption(Args, "nodelete");
Config->ZNodlopen = hasZOption(Args, "nodlopen");
Index: tools/lld/ELF/SyntheticSections.cpp
===================================================================
--- tools/lld/ELF/SyntheticSections.cpp (revision 338681)
+++ tools/lld/ELF/SyntheticSections.cpp (revision 338682)
@@ -1034,6 +1034,8 @@ template <class ELFT> void DynamicSection<ELFT>::f
uint32_t DtFlags1 = 0;
if (Config->Bsymbolic)
DtFlags |= DF_SYMBOLIC;
+ if (Config->ZInterpose)
+ DtFlags1 |= DF_1_INTERPOSE;
if (Config->ZNodelete)
DtFlags1 |= DF_1_NODELETE;
if (Config->ZNodlopen)

View file

@ -0,0 +1,39 @@
r339013 | dim | 2018-09-29 16:12:03 +0200 (Sat, 29 Sep 2018) | 24 lines
Pull in r329557 from upstream lld trunk (by George Rimar):
[ELF] - Allow LLD to produce file symbols.
This is for PR36716 and
this enables emitting STT_FILE symbols.
Output size affect is minor:
lld binary size changes from 52,883,408 to 52,949,400
clang binary size changes from 83,136,456 to 83,219,600
Differential revision: https://reviews.llvm.org/D45261
This fixes a regression in lld that made it stop emitting STT_FILE
symbols, which ctfmerge relies upon to uniquify function table entries
that reference STB_LOCAL symbols. Consequently, ctfmerge stopped
emitting entries for static functions into the function table, and
dtrace no longer gets type info for them.
Approved by: re (kib)
Reported by: markj
PR: 230444
MFC after: 3 days
Index: tools/lld/ELF/Writer.cpp
===================================================================
--- tools/lld/ELF/Writer.cpp (revision 339012)
+++ tools/lld/ELF/Writer.cpp (revision 339013)
@@ -487,7 +487,7 @@ template <class ELFT> void Writer<ELFT>::run() {
static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
const Symbol &B) {
- if (B.isFile() || B.isSection())
+ if (B.isSection())
return false;
// If sym references a section in a discarded group, don't keep it.

View file

@ -0,0 +1,37 @@
r339304 | emaste | 2018-10-11 15:19:17 +0200 (Thu, 11 Oct 2018) | 13 lines
lld: set sh_link and sh_info for .rela.plt sections
ELF spec says that for SHT_REL and SHT_RELA sh_link should reference the
associated string table and sh_info should reference the "section to
which the relocation applies." ELF Tool Chain's elfcopy / strip use
this (in part) to control whether or not the relocation entry is copied
to the output.
LLVM PR 37538 https://bugs.llvm.org/show_bug.cgi?id=37538
Approved by: re (kib)
Obtained from: llvm r344226 (backported for 6.0)
Index: tools/lld/ELF/SyntheticSections.cpp
===================================================================
--- tools/lld/ELF/SyntheticSections.cpp (revision 339303)
+++ tools/lld/ELF/SyntheticSections.cpp (revision 339304)
@@ -1213,11 +1213,13 @@ void RelocationBaseSection::addReloc(const Dynamic
void RelocationBaseSection::finalizeContents() {
// If all relocations are R_*_RELATIVE they don't refer to any
// dynamic symbol and we don't need a dynamic symbol table. If that
- // is the case, just use 0 as the link.
- Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0;
+ // is the case, just use the index of the regular symbol table section.
+ getParent()->Link = InX::DynSymTab ?
+ InX::DynSymTab->getParent()->SectionIndex :
+ InX::SymTab->getParent()->SectionIndex;
- // Set required output section properties.
- getParent()->Link = Link;
+ if (InX::RelaIplt == this || InX::RelaPlt == this)
+ getParent()->Info = InX::GotPlt->getParent()->SectionIndex;
}
template <class ELFT>

View file

@ -0,0 +1,38 @@
r332849 | emaste | 2018-04-21 02:34:46 +0200 (Sat, 21 Apr 2018) | 20 lines
lldb: propagate error to user if memory read fails
Previously, an attempt to read an unreadable access reported zeros:
(lldb) memory read -format hex -size 8 0
0x00000000: 0x0000000000000000 0x0000000000000000
0x00000010: 0x0000000000000000 0x0000000000000000
...
Now, if DoReadMemory encounters error then return 0 (bytes read) so we
report the error to the user:
(lldb) memory read -format hex -size 8 0
error: Bad address
LLVM PR: 37190
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Index: tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
===================================================================
--- tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 332848)
+++ tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 332849)
@@ -163,8 +163,10 @@ static size_t DoReadMemory(lldb::pid_t pid, lldb::
pi_desc.piod_addr = buf;
pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
error.SetErrorToErrno();
+ return 0;
+ }
return pi_desc.piod_len;
}

View file

@ -0,0 +1,22 @@
r332965 | emaste | 2018-04-24 21:26:58 +0200 (Tue, 24 Apr 2018) | 8 lines
lldb: remove assertion that target_arch is FreeBSD
The target is not necessarily a FreeBSD binary - for example, it may be
a Linux binary running under the linuxulator. Basic ptrace (live)
debugging already worked in this case, except for the assertion.
Sponsored by: Turing Robotic Industries Inc.
Index: tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
===================================================================
--- tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp (revision 332964)
+++ tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp (revision 332965)
@@ -169,7 +169,6 @@ lldb::RegisterContextSP FreeBSDThread::GetRegister
RegisterInfoInterface *reg_interface = NULL;
const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
- assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
reg_interface = new RegisterInfoPOSIX_arm64(target_arch);

View file

@ -0,0 +1,33 @@
r308867 | dim | 2016-11-19 22:05:17 +0100 (Sat, 19 Nov 2016) | 15 lines
Work around LLVM PR30879, which is about a bad interaction between X86
Call Frame Optimization on i386 and libunwind, by disallowing the
optimization for i386-freebsd12.
This should fix some instances of broken exception handling when frame
pointers are omitted, in particular some unittests run during the build
of editors/libreoffice.
This hack will be removed as soon as upstream has implemented a more
permanent fix for this problem.
Upstream PR: https://llvm.org/bugs/show_bug.cgi?id=30879
Reviewed by: emaste
PR: 212343
Index: lib/Target/X86/X86CallFrameOptimization.cpp
===================================================================
--- lib/Target/X86/X86CallFrameOptimization.cpp (revision 308866)
+++ lib/Target/X86/X86CallFrameOptimization.cpp (revision 308867)
@@ -125,6 +125,11 @@ bool X86CallFrameOptimization::isLegal(MachineFunc
if (NoX86CFOpt.getValue())
return false;
+ // Work around LLVM PR30879 (bad interaction between CFO and libunwind)
+ if (STI->isTargetFreeBSD() && STI->is32Bit() &&
+ STI->getTargetTriple().getOSMajorVersion() >= 12)
+ return false;
+
// We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset
// in the compact unwind encoding that Darwin uses. So, bail if there
// is a danger of that being generated.

View file

@ -0,0 +1,80 @@
r330686 | dim | 2018-03-09 10:21:22 +0100 (Fri, 09 Mar 2018) | 20 lines
Pull in r326882 from upstream llvm trunk (by Sjoerd Meijer):
[ARM] Fix for PR36577
Don't PerformSHLSimplify if the given node is used by a node that
also uses a constant because we may get stuck in an infinite combine
loop.
bugzilla: https://bugs.llvm.org/show_bug.cgi?id=36577
Patch by Sam Parker.
Differential Revision: https://reviews.llvm.org/D44097
This fixes a hang when compiling one particular file in java/openjdk8
for armv6 and armv7.
Reported by: swills
PR: 226388
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp (revision 330685)
+++ lib/Target/ARM/ARMISelLowering.cpp (revision 330686)
@@ -10201,7 +10201,14 @@ static SDValue PerformSHLSimplify(SDNode *N,
case ISD::XOR:
case ISD::SETCC:
case ARMISD::CMP:
- // Check that its not already using a shl.
+ // Check that the user isn't already using a constant because there
+ // aren't any instructions that support an immediate operand and a
+ // shifted operand.
+ if (isa<ConstantSDNode>(U->getOperand(0)) ||
+ isa<ConstantSDNode>(U->getOperand(1)))
+ return SDValue();
+
+ // Check that it's not already using a shift.
if (U->getOperand(0).getOpcode() == ISD::SHL ||
U->getOperand(1).getOpcode() == ISD::SHL)
return SDValue();
@@ -10223,8 +10230,6 @@ static SDValue PerformSHLSimplify(SDNode *N,
if (!C1ShlC2 || !C2)
return SDValue();
- DEBUG(dbgs() << "Trying to simplify shl: "; N->dump());
-
APInt C2Int = C2->getAPIntValue();
APInt C1Int = C1ShlC2->getAPIntValue();
@@ -10238,12 +10243,12 @@ static SDValue PerformSHLSimplify(SDNode *N,
C1Int.lshrInPlace(C2Int);
// The immediates are encoded as an 8-bit value that can be rotated.
- unsigned Zeros = C1Int.countLeadingZeros() + C1Int.countTrailingZeros();
- if (C1Int.getBitWidth() - Zeros > 8)
- return SDValue();
+ auto LargeImm = [](const APInt &Imm) {
+ unsigned Zeros = Imm.countLeadingZeros() + Imm.countTrailingZeros();
+ return Imm.getBitWidth() - Zeros > 8;
+ };
- Zeros = C2Int.countLeadingZeros() + C2Int.countTrailingZeros();
- if (C2Int.getBitWidth() - Zeros > 8)
+ if (LargeImm(C1Int) || LargeImm(C2Int))
return SDValue();
SelectionDAG &DAG = DCI.DAG;
@@ -10254,6 +10259,10 @@ static SDValue PerformSHLSimplify(SDNode *N,
// Shift left to compensate for the lshr of C1Int.
SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
+ DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump(); SHL.dump();
+ N->dump());
+ DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
+
DAG.ReplaceAllUsesWith(SDValue(N, 0), Res);
return SDValue(N, 0);
}

View file

@ -0,0 +1,88 @@
r331065 | dim | 2018-03-16 18:50:44 +0100 (Fri, 16 Mar 2018) | 17 lines
Pull in r327638 from upstream llvm trunk (by Matthew Simpson):
[ConstantFolding, InstSimplify] Handle more vector GEPs
This patch addresses some additional cases where the compiler crashes
upon encountering vector GEPs. This should fix PR36116.
Differential Revision: https://reviews.llvm.org/D44219
Reference: https://bugs.llvm.org/show_bug.cgi?id=36116
This fixes an assertion when building the emulators/snes9x port.
Reported by: jbeich
PR: 225471
MFC after: 3 months
X-MFC-With: r327952
Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp (revision 331064)
+++ lib/Analysis/InstructionSimplify.cpp (revision 331065)
@@ -3697,7 +3697,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRe
if (Ops.size() == 2) {
// getelementptr P, 0 -> P.
- if (match(Ops[1], m_Zero()))
+ if (match(Ops[1], m_Zero()) && Ops[0]->getType() == GEPTy)
return Ops[0];
Type *Ty = SrcTy;
@@ -3706,7 +3706,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRe
uint64_t C;
uint64_t TyAllocSize = Q.DL.getTypeAllocSize(Ty);
// getelementptr P, N -> P if P points to a type of zero size.
- if (TyAllocSize == 0)
+ if (TyAllocSize == 0 && Ops[0]->getType() == GEPTy)
return Ops[0];
// The following transforms are only safe if the ptrtoint cast
Index: lib/IR/ConstantFold.cpp
===================================================================
--- lib/IR/ConstantFold.cpp (revision 331064)
+++ lib/IR/ConstantFold.cpp (revision 331065)
@@ -2018,8 +2018,16 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Id
// If the first index is one and all the rest are zero, it's in bounds,
// by the one-past-the-end rule.
- if (!cast<ConstantInt>(Idxs[0])->isOne())
- return false;
+ if (auto *CI = dyn_cast<ConstantInt>(Idxs[0])) {
+ if (!CI->isOne())
+ return false;
+ } else {
+ auto *CV = cast<ConstantDataVector>(Idxs[0]);
+ CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
+ if (!CI || !CI->isOne())
+ return false;
+ }
+
for (unsigned i = 1, e = Idxs.size(); i != e; ++i)
if (!cast<Constant>(Idxs[i])->isNullValue())
return false;
@@ -2049,15 +2057,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *Po
ArrayRef<Value *> Idxs) {
if (Idxs.empty()) return C;
- if (isa<UndefValue>(C)) {
- Type *GEPTy = GetElementPtrInst::getGEPReturnType(
- C, makeArrayRef((Value * const *)Idxs.data(), Idxs.size()));
+ Type *GEPTy = GetElementPtrInst::getGEPReturnType(
+ C, makeArrayRef((Value *const *)Idxs.data(), Idxs.size()));
+
+ if (isa<UndefValue>(C))
return UndefValue::get(GEPTy);
- }
Constant *Idx0 = cast<Constant>(Idxs[0]);
if (Idxs.size() == 1 && (Idx0->isNullValue() || isa<UndefValue>(Idx0)))
- return C;
+ return GEPTy->isVectorTy() && !C->getType()->isVectorTy()
+ ? ConstantVector::getSplat(
+ cast<VectorType>(GEPTy)->getNumElements(), C)
+ : C;
if (C->isNullValue()) {
bool isNull = true;

View file

@ -0,0 +1,609 @@
r331366 | dim | 2018-03-22 19:58:34 +0100 (Thu, 22 Mar 2018) | 61 lines
Pull in r327101 from upstream llvm trunk (by Rafael Espindola):
Don't treat .symver as a regular alias definition.
This patch starts simplifying the handling of .symver.
For now it just moves the responsibility for creating an alias down to
the streamer. With that the asm streamer can pass a .symver unchanged,
which is nice since gas cannot parse "foo@bar = zed".
In a followup I hope to move the handling down to the writer so that
we don't need special hacks for avoiding breaking names with @@@ on
windows.
Pull in r327160 from upstream llvm trunk (by Rafael Espindola):
Delay creating an alias for @@@.
With this we only create an alias for @@@ once we know if it should
use @ or @@. This avoids last minutes renames and hacks to handle MS
names.
This only handles the ELF writer. LTO still has issues with @@@
aliases.
Pull in r327928 from upstream llvm trunk (by Vitaly Buka):
Object: Move attribute calculation into RecordStreamer. NFC
Summary: Preparation for D44274
Reviewers: pcc, espindola
Subscribers: hiraditya
Differential Revision: https://reviews.llvm.org/D44276
Pull in r327930 from upstream llvm trunk (by Vitaly Buka):
Object: Fix handling of @@@ in .symver directive
Summary:
name@@@nodename is going to be replaced with name@@nodename if symbols is
defined in the assembled file, or name@nodename if undefined.
https://sourceware.org/binutils/docs/as/Symver.html
Fixes PR36623
Reviewers: pcc, espindola
Subscribers: mehdi_amini, hiraditya
Differential Revision: https://reviews.llvm.org/D44274
Together, these changes fix handling of @@@ in .symver directives when
doing Link Time Optimization.
Reported by: Shawn Webb <shawn.webb@hardenedbsd.org>
MFC after: 3 months
X-MFC-With: r327952
Index: include/llvm/MC/MCAssembler.h
===================================================================
--- include/llvm/MC/MCAssembler.h (revision 331365)
+++ include/llvm/MC/MCAssembler.h (revision 331366)
@@ -206,6 +206,8 @@ class MCAssembler {
handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
public:
+ std::vector<std::pair<StringRef, const MCSymbol *>> Symvers;
+
/// Construct a new assembler instance.
//
// FIXME: How are we going to parameterize this? Two obvious options are stay
Index: include/llvm/MC/MCELFStreamer.h
===================================================================
--- include/llvm/MC/MCELFStreamer.h (revision 331365)
+++ include/llvm/MC/MCELFStreamer.h (revision 331366)
@@ -51,6 +51,8 @@ class MCELFStreamer : public MCObjectStreamer {
unsigned ByteAlignment) override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+ void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) override;
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
Index: include/llvm/MC/MCStreamer.h
===================================================================
--- include/llvm/MC/MCStreamer.h (revision 331365)
+++ include/llvm/MC/MCStreamer.h (revision 331366)
@@ -519,9 +519,10 @@ class MCStreamer {
///
/// This corresponds to an assembler statement such as:
/// .symver _start, foo@@SOME_VERSION
- /// \param Alias - The versioned alias (i.e. "foo@@SOME_VERSION")
+ /// \param AliasName - The versioned alias (i.e. "foo@@SOME_VERSION")
/// \param Aliasee - The aliased symbol (i.e. "_start")
- virtual void emitELFSymverDirective(MCSymbol *Alias, const MCSymbol *Aliasee);
+ virtual void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee);
/// \brief Emit a Linker Optimization Hint (LOH) directive.
/// \param Args - Arguments of the LOH.
Index: lib/MC/ELFObjectWriter.cpp
===================================================================
--- lib/MC/ELFObjectWriter.cpp (revision 331365)
+++ lib/MC/ELFObjectWriter.cpp (revision 331366)
@@ -128,8 +128,6 @@ class ELFObjectWriter : public MCObjectWriter {
/// @name Symbol Table Data
/// @{
- BumpPtrAllocator Alloc;
- StringSaver VersionSymSaver{Alloc};
StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
/// @}
@@ -391,27 +389,29 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
const MCAsmLayout &Layout) {
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
- for (const MCSymbol &A : Asm.symbols()) {
- const auto &Alias = cast<MCSymbolELF>(A);
- // Not an alias.
- if (!Alias.isVariable())
- continue;
- auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
- if (!Ref)
- continue;
- const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
-
- StringRef AliasName = Alias.getName();
+ for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
+ StringRef AliasName = P.first;
+ const auto &Symbol = cast<MCSymbolELF>(*P.second);
size_t Pos = AliasName.find('@');
- if (Pos == StringRef::npos)
- continue;
+ assert(Pos != StringRef::npos);
+ StringRef Prefix = AliasName.substr(0, Pos);
+ StringRef Rest = AliasName.substr(Pos);
+ StringRef Tail = Rest;
+ if (Rest.startswith("@@@"))
+ Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
+
+ auto *Alias =
+ cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
+ Asm.registerSymbol(*Alias);
+ const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
+ Alias->setVariableValue(Value);
+
// Aliases defined with .symvar copy the binding from the symbol they alias.
// This is the first place we are able to copy this information.
- Alias.setExternal(Symbol.isExternal());
- Alias.setBinding(Symbol.getBinding());
+ Alias->setExternal(Symbol.isExternal());
+ Alias->setBinding(Symbol.getBinding());
- StringRef Rest = AliasName.substr(Pos);
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
continue;
@@ -420,7 +420,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
!Rest.startswith("@@@"))
report_fatal_error("A @@ version cannot be undefined");
- Renames.insert(std::make_pair(&Symbol, &Alias));
+ Renames.insert(std::make_pair(&Symbol, Alias));
}
}
@@ -836,44 +836,7 @@ void ELFObjectWriter::computeSymbolTable(
HasLargeSectionIndex = true;
}
- // The @@@ in symbol version is replaced with @ in undefined symbols and @@
- // in defined ones.
- //
- // FIXME: All name handling should be done before we get to the writer,
- // including dealing with GNU-style version suffixes. Fixing this isn't
- // trivial.
- //
- // We thus have to be careful to not perform the symbol version replacement
- // blindly:
- //
- // The ELF format is used on Windows by the MCJIT engine. Thus, on
- // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
- // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
- // C++ name mangling can legally have "@@@" as a sub-string. In that case,
- // the EFLObjectWriter should not interpret the "@@@" sub-string as
- // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
- // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
- // "__imp_?" or "__imp_@?".
- //
- // It would have been interesting to perform the MS mangling prefix check
- // only when the target triple is of the form *-pc-windows-elf. But, it
- // seems that this information is not easily accessible from the
- // ELFObjectWriter.
StringRef Name = Symbol.getName();
- SmallString<32> Buf;
- if (!Name.startswith("?") && !Name.startswith("@?") &&
- !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
- // This symbol isn't following the MSVC C++ name mangling convention. We
- // can thus safely interpret the @@@ in symbol names as specifying symbol
- // versioning.
- size_t Pos = Name.find("@@@");
- if (Pos != StringRef::npos) {
- Buf += Name.substr(0, Pos);
- unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
- Buf += Name.substr(Pos + Skip);
- Name = VersionSymSaver.save(Buf.c_str());
- }
- }
// Sections have their own string table
if (Symbol.getType() != ELF::STT_SECTION) {
Index: lib/MC/MCAsmStreamer.cpp
===================================================================
--- lib/MC/MCAsmStreamer.cpp (revision 331365)
+++ lib/MC/MCAsmStreamer.cpp (revision 331366)
@@ -129,6 +129,9 @@ class MCAsmStreamer final : public MCStreamer {
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) override;
+
void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
@@ -411,6 +414,14 @@ void MCAsmStreamer::ChangeSection(MCSection *Secti
}
}
+void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {
+ OS << ".symver ";
+ Aliasee->print(OS, MAI);
+ OS << ", " << AliasName;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::EmitLabel(Symbol, Loc);
Index: lib/MC/MCELFStreamer.cpp
===================================================================
--- lib/MC/MCELFStreamer.cpp (revision 331365)
+++ lib/MC/MCELFStreamer.cpp (revision 331366)
@@ -337,6 +337,11 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol,
cast<MCSymbolELF>(Symbol)->setSize(Value);
}
+void MCELFStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {
+ getAssembler().Symvers.push_back({AliasName, Aliasee});
+}
+
void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
unsigned ByteAlignment) {
auto *Symbol = cast<MCSymbolELF>(S);
Index: lib/MC/MCParser/ELFAsmParser.cpp
===================================================================
--- lib/MC/MCParser/ELFAsmParser.cpp (revision 331365)
+++ lib/MC/MCParser/ELFAsmParser.cpp (revision 331366)
@@ -767,12 +767,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef,
if (AliasName.find('@') == StringRef::npos)
return TokError("expected a '@' in the name");
- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
- const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
-
- getStreamer().EmitAssignment(Alias, Value);
- getStreamer().emitELFSymverDirective(Alias, Sym);
+ getStreamer().emitELFSymverDirective(AliasName, Sym);
return false;
}
Index: lib/MC/MCStreamer.cpp
===================================================================
--- lib/MC/MCStreamer.cpp (revision 331365)
+++ lib/MC/MCStreamer.cpp (revision 331366)
@@ -925,7 +925,7 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {
llvm_unreachable("this directive only supported on COFF targets");
}
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
-void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
+void MCStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {}
void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
Index: lib/Object/ModuleSymbolTable.cpp
===================================================================
--- lib/Object/ModuleSymbolTable.cpp (revision 331365)
+++ lib/Object/ModuleSymbolTable.cpp (revision 331366)
@@ -24,7 +24,6 @@
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -69,81 +68,6 @@ void ModuleSymbolTable::addModule(Module *M) {
});
}
-// Ensure ELF .symver aliases get the same binding as the defined symbol
-// they alias with.
-static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
- if (Streamer.symverAliases().empty())
- return;
-
- // The name in the assembler will be mangled, but the name in the IR
- // might not, so we first compute a mapping from mangled name to GV.
- Mangler Mang;
- SmallString<64> MangledName;
- StringMap<const GlobalValue *> MangledNameMap;
- auto GetMangledName = [&](const GlobalValue &GV) {
- if (!GV.hasName())
- return;
-
- MangledName.clear();
- MangledName.reserve(GV.getName().size() + 1);
- Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
- MangledNameMap[MangledName] = &GV;
- };
- for (const Function &F : M)
- GetMangledName(F);
- for (const GlobalVariable &GV : M.globals())
- GetMangledName(GV);
- for (const GlobalAlias &GA : M.aliases())
- GetMangledName(GA);
-
- // Walk all the recorded .symver aliases, and set up the binding
- // for each alias.
- for (auto &Symver : Streamer.symverAliases()) {
- const MCSymbol *Aliasee = Symver.first;
- MCSymbolAttr Attr = MCSA_Invalid;
-
- // First check if the aliasee binding was recorded in the asm.
- RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
- switch (state) {
- case RecordStreamer::Global:
- case RecordStreamer::DefinedGlobal:
- Attr = MCSA_Global;
- break;
- case RecordStreamer::UndefinedWeak:
- case RecordStreamer::DefinedWeak:
- Attr = MCSA_Weak;
- break;
- default:
- break;
- }
-
- // If we don't have a symbol attribute from assembly, then check if
- // the aliasee was defined in the IR.
- if (Attr == MCSA_Invalid) {
- const auto *GV = M.getNamedValue(Aliasee->getName());
- if (!GV) {
- auto MI = MangledNameMap.find(Aliasee->getName());
- if (MI != MangledNameMap.end())
- GV = MI->second;
- else
- continue;
- }
- if (GV->hasExternalLinkage())
- Attr = MCSA_Global;
- else if (GV->hasLocalLinkage())
- Attr = MCSA_Local;
- else if (GV->isWeakForLinker())
- Attr = MCSA_Weak;
- }
- if (Attr == MCSA_Invalid)
- continue;
-
- // Set the detected binding on each alias with this aliasee.
- for (auto &Alias : Symver.second)
- Streamer.EmitSymbolAttribute(Alias, Attr);
- }
-}
-
void ModuleSymbolTable::CollectAsmSymbols(
const Module &M,
function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
@@ -176,7 +100,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
MCObjectFileInfo MOFI;
MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
- RecordStreamer Streamer(MCCtx);
+ RecordStreamer Streamer(MCCtx, M);
T->createNullTargetStreamer(Streamer);
std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
@@ -195,7 +119,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
if (Parser->Run(false))
return;
- handleSymverAliases(M, Streamer);
+ Streamer.flushSymverDirectives();
for (auto &KV : Streamer) {
StringRef Key = KV.first();
Index: lib/Object/RecordStreamer.cpp
===================================================================
--- lib/Object/RecordStreamer.cpp (revision 331365)
+++ lib/Object/RecordStreamer.cpp (revision 331366)
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
#include "RecordStreamer.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
using namespace llvm;
@@ -70,7 +73,8 @@ void RecordStreamer::markUsed(const MCSymbol &Symb
void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
-RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
+RecordStreamer::RecordStreamer(MCContext &Context, const Module &M)
+ : MCStreamer(Context), M(M) {}
RecordStreamer::const_iterator RecordStreamer::begin() {
return Symbols.begin();
@@ -112,7 +116,109 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Sy
markDefined(*Symbol);
}
-void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
+RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
+ auto SI = Symbols.find(Sym->getName());
+ if (SI == Symbols.end())
+ return NeverSeen;
+ return SI->second;
+}
+
+void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {
- SymverAliasMap[Aliasee].push_back(Alias);
+ SymverAliasMap[Aliasee].push_back(AliasName);
}
+
+void RecordStreamer::flushSymverDirectives() {
+ // Mapping from mangled name to GV.
+ StringMap<const GlobalValue *> MangledNameMap;
+ // The name in the assembler will be mangled, but the name in the IR
+ // might not, so we first compute a mapping from mangled name to GV.
+ Mangler Mang;
+ SmallString<64> MangledName;
+ for (const GlobalValue &GV : M.global_values()) {
+ if (!GV.hasName())
+ continue;
+ MangledName.clear();
+ MangledName.reserve(GV.getName().size() + 1);
+ Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
+ MangledNameMap[MangledName] = &GV;
+ }
+
+ // Walk all the recorded .symver aliases, and set up the binding
+ // for each alias.
+ for (auto &Symver : SymverAliasMap) {
+ const MCSymbol *Aliasee = Symver.first;
+ MCSymbolAttr Attr = MCSA_Invalid;
+ bool IsDefined = false;
+
+ // First check if the aliasee binding was recorded in the asm.
+ RecordStreamer::State state = getSymbolState(Aliasee);
+ switch (state) {
+ case RecordStreamer::Global:
+ case RecordStreamer::DefinedGlobal:
+ Attr = MCSA_Global;
+ break;
+ case RecordStreamer::UndefinedWeak:
+ case RecordStreamer::DefinedWeak:
+ Attr = MCSA_Weak;
+ break;
+ default:
+ break;
+ }
+
+ switch (state) {
+ case RecordStreamer::Defined:
+ case RecordStreamer::DefinedGlobal:
+ case RecordStreamer::DefinedWeak:
+ IsDefined = true;
+ break;
+ case RecordStreamer::NeverSeen:
+ case RecordStreamer::Global:
+ case RecordStreamer::Used:
+ case RecordStreamer::UndefinedWeak:
+ break;
+ }
+
+ if (Attr == MCSA_Invalid || !IsDefined) {
+ const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
+ if (!GV) {
+ auto MI = MangledNameMap.find(Aliasee->getName());
+ if (MI != MangledNameMap.end())
+ GV = MI->second;
+ }
+ if (GV) {
+ // If we don't have a symbol attribute from assembly, then check if
+ // the aliasee was defined in the IR.
+ if (Attr == MCSA_Invalid) {
+ if (GV->hasExternalLinkage())
+ Attr = MCSA_Global;
+ else if (GV->hasLocalLinkage())
+ Attr = MCSA_Local;
+ else if (GV->isWeakForLinker())
+ Attr = MCSA_Weak;
+ }
+ IsDefined = IsDefined || !GV->isDeclarationForLinker();
+ }
+ }
+
+ // Set the detected binding on each alias with this aliasee.
+ for (auto AliasName : Symver.second) {
+ std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
+ SmallString<128> NewName;
+ if (!Split.second.empty() && !Split.second.startswith("@")) {
+ // Special processing for "@@@" according
+ // https://sourceware.org/binutils/docs/as/Symver.html
+ const char *Separator = IsDefined ? "@@" : "@";
+ AliasName =
+ (Split.first + Separator + Split.second).toStringRef(NewName);
+ }
+ MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
+ // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
+ // converted into @ or @@.
+ const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
+ EmitAssignment(Alias, Value);
+ if (Attr != MCSA_Invalid)
+ EmitSymbolAttribute(Alias, Attr);
+ }
+ }
+}
Index: lib/Object/RecordStreamer.h
===================================================================
--- lib/Object/RecordStreamer.h (revision 331365)
+++ lib/Object/RecordStreamer.h (revision 331366)
@@ -20,6 +20,9 @@
namespace llvm {
+class GlobalValue;
+class Module;
+
class RecordStreamer : public MCStreamer {
public:
enum State { NeverSeen, Global, Defined, DefinedGlobal, DefinedWeak, Used,
@@ -26,12 +29,16 @@ class RecordStreamer : public MCStreamer {
UndefinedWeak};
private:
+ const Module &M;
StringMap<State> Symbols;
// Map of aliases created by .symver directives, saved so we can update
// their symbol binding after parsing complete. This maps from each
// aliasee to its list of aliases.
- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> SymverAliasMap;
+ DenseMap<const MCSymbol *, std::vector<StringRef>> SymverAliasMap;
+ /// Get the state recorded for the given symbol.
+ State getSymbolState(const MCSymbol *Sym);
+
void markDefined(const MCSymbol &Symbol);
void markGlobal(const MCSymbol &Symbol, MCSymbolAttr Attribute);
void markUsed(const MCSymbol &Symbol);
@@ -38,7 +45,7 @@ class RecordStreamer : public MCStreamer {
void visitUsedSymbol(const MCSymbol &Sym) override;
public:
- RecordStreamer(MCContext &Context);
+ RecordStreamer(MCContext &Context, const Module &M);
using const_iterator = StringMap<State>::const_iterator;
@@ -54,20 +61,11 @@ class RecordStreamer : public MCStreamer {
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
/// Record .symver aliases for later processing.
- void emitELFSymverDirective(MCSymbol *Alias,
+ void emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) override;
- /// Return the map of .symver aliasee to associated aliases.
- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() {
- return SymverAliasMap;
- }
-
- /// Get the state recorded for the given symbol.
- State getSymbolState(const MCSymbol *Sym) {
- auto SI = Symbols.find(Sym->getName());
- if (SI == Symbols.end())
- return NeverSeen;
- return SI->second;
- }
+ // Emit ELF .symver aliases and ensure they have the same binding as the
+ // defined symbol they alias with.
+ void flushSymverDirectives();
};
} // end namespace llvm

View file

@ -0,0 +1,32 @@
r336969 | emaste | 2018-07-31 16:12:09 +0200 (Tue, 31 Jul 2018) | 13 lines
llvm: [ELF][ARM] Add Arm ABI names for float ABI ELF Header flags
The ELF for the Arm architecture document defines, for EF_ARM_EABI_VER5
and above, the flags EF_ARM_ABI_FLOAT_HARD and EF_ARM_ABI_FLOAT_SOFT.
These have been defined to be compatible with the existing
EF_ARM_VFP_FLOAT and EF_ARM_SOFT_FLOAT used by gcc for
EF_ARM_EABI_UNKNOWN.
This patch adds the flags in addition to the existing ones so that any
code depending on the old names will still work.
Obtained from: llvm r338370 by Peter Smith
Index: include/llvm/BinaryFormat/ELF.h
===================================================================
--- include/llvm/BinaryFormat/ELF.h (revision 336968)
+++ include/llvm/BinaryFormat/ELF.h (revision 336969)
@@ -418,8 +418,10 @@ enum {
// ARM Specific e_flags
enum : unsigned {
- EF_ARM_SOFT_FLOAT = 0x00000200U,
- EF_ARM_VFP_FLOAT = 0x00000400U,
+ EF_ARM_SOFT_FLOAT = 0x00000200U, // Legacy pre EABI_VER5
+ EF_ARM_ABI_FLOAT_SOFT = 0x00000200U, // EABI_VER5
+ EF_ARM_VFP_FLOAT = 0x00000400U, // Legacy pre EABI_VER5
+ EF_ARM_ABI_FLOAT_HARD = 0x00000400U, // EABI_VER5
EF_ARM_EABI_UNKNOWN = 0x00000000U,
EF_ARM_EABI_VER1 = 0x01000000U,
EF_ARM_EABI_VER2 = 0x02000000U,

View file

@ -0,0 +1,24 @@
r336970 | emaste | 2018-07-31 16:14:41 +0200 (Tue, 31 Jul 2018) | 9 lines
llvm: [ARM] Complete enumeration values for Tag_ABI_VFP_args
The LLD implementation of Tag_ABI_VFP_args needs to check the rarely
seen values of 3 (toolchain specific) and 4 compatible with both Base
and VFP. Add the missing enumeration values so that LLD can refer to
them without having to use the raw numbers.
Obtained from: llvm r338373 by Peter Smith
Index: include/llvm/Support/ARMBuildAttributes.h
===================================================================
--- include/llvm/Support/ARMBuildAttributes.h (revision 336969)
+++ include/llvm/Support/ARMBuildAttributes.h (revision 336970)
@@ -213,6 +213,8 @@ enum {
// Tag_ABI_VFP_args, (=28), uleb128
BaseAAPCS = 0,
HardFPAAPCS = 1,
+ ToolChainFPPCS = 2,
+ CompatibleFPAAPCS = 3,
// Tag_FP_HP_extension, (=36), uleb128
AllowHPFP = 1, // Allow use of Half Precision FP

View file

@ -0,0 +1,64 @@
r337615 | dim | 2018-08-11 12:42:12 +0200 (Sat, 11 Aug 2018) | 43 lines
Pull in r338481 from upstream llvm trunk (by Chandler Carruth):
[x86] Fix a really subtle miscompile due to a somewhat glaring bug in
EFLAGS copy lowering.
If you have a branch of LLVM, you may want to cherrypick this. It is
extremely unlikely to hit this case empirically, but it will likely
manifest as an "impossible" branch being taken somewhere, and will be
... very hard to debug.
Hitting this requires complex conditions living across complex
control flow combined with some interesting memory (non-stack)
initialized with the results of a comparison. Also, because you have
to arrange for an EFLAGS copy to be in *just* the right place, almost
anything you do to the code will hide the bug. I was unable to reduce
anything remotely resembling a "good" test case from the place where
I hit it, and so instead I have constructed synthetic MIR testing
that directly exercises the bug in question (as well as the good
behavior for completeness).
The issue is that we would mistakenly assume any SETcc with a valid
condition and an initial operand that was a register and a virtual
register at that to be a register *defining* SETcc...
It isn't though....
This would in turn cause us to test some other bizarre register,
typically the base pointer of some memory. Now, testing this register
and using that to branch on doesn't make any sense. It even fails the
machine verifier (if you are running it) due to the wrong register
class. But it will make it through LLVM, assemble, and it *looks*
fine... But wow do you get a very unsual and surprising branch taken
in your actual code.
The fix is to actually check what kind of SETcc instruction we're
dealing with. Because there are a bunch of them, I just test the
may-store bit in the instruction. I've also added an assert for
sanity that ensure we are, in fact, *defining* the register operand.
=D
Noticed by: kib
MFC after: 1 week
Index: lib/Target/X86/X86FlagsCopyLowering.cpp
===================================================================
--- lib/Target/X86/X86FlagsCopyLowering.cpp (revision 337614)
+++ lib/Target/X86/X86FlagsCopyLowering.cpp (revision 337615)
@@ -608,9 +608,12 @@ X86FlagsCopyLoweringPass::collectCondsInRegs(Machi
for (MachineInstr &MI : llvm::reverse(
llvm::make_range(MBB.instr_begin(), CopyDefI.getIterator()))) {
X86::CondCode Cond = X86::getCondFromSETOpc(MI.getOpcode());
- if (Cond != X86::COND_INVALID && MI.getOperand(0).isReg() &&
- TRI->isVirtualRegister(MI.getOperand(0).getReg()))
+ if (Cond != X86::COND_INVALID && !MI.mayStore() && MI.getOperand(0).isReg() &&
+ TRI->isVirtualRegister(MI.getOperand(0).getReg())) {
+ assert(MI.getOperand(0).isDef() &&
+ "A non-storing SETcc should always define a register!");
CondRegs[Cond] = MI.getOperand(0).getReg();
+ }
// Stop scanning when we see the first definition of the EFLAGS as prior to
// this we would potentially capture the wrong flag state.

View file

@ -0,0 +1,32 @@
r338689 | dim | 2018-09-14 21:25:23 +0200 (Fri, 14 Sep 2018) | 12 lines
Pull in r335365 from upstream llvm trunk (by Krzysztof Parzyszek):
Initialize LiveRegs once in BranchFolder::mergeCommonTails
This should fix '(TRI && "LivePhysRegs is not initialized."' assertions
when building the lang/qt5-qml port in certain configurations.
Approved by: re (kib)
Reported by: Piotr Kubaj <pkubaj@anongoth.pl>
PR: 231355
MFC after: 3 days
Index: lib/CodeGen/BranchFolding.cpp
===================================================================
--- lib/CodeGen/BranchFolding.cpp (revision 338688)
+++ lib/CodeGen/BranchFolding.cpp (revision 338689)
@@ -884,11 +884,12 @@ void BranchFolder::mergeCommonTails(unsigned commo
if (UpdateLiveIns) {
LivePhysRegs NewLiveIns(*TRI);
computeLiveIns(NewLiveIns, *MBB);
+ LiveRegs.init(*TRI);
// The flag merging may lead to some register uses no longer using the
// <undef> flag, add IMPLICIT_DEFs in the predecessors as necessary.
for (MachineBasicBlock *Pred : MBB->predecessors()) {
- LiveRegs.init(*TRI);
+ LiveRegs.clear();
LiveRegs.addLiveOuts(*Pred);
MachineBasicBlock::iterator InsertBefore = Pred->getFirstTerminator();
for (unsigned Reg : NewLiveIns) {