summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LangRef.rst30
-rw-r--r--include/llvm/IR/GlobalAlias.h21
-rw-r--r--include/llvm/IR/GlobalObject.h4
-rw-r--r--include/llvm/IR/GlobalValue.h10
-rw-r--r--lib/AsmParser/LLParser.cpp59
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp35
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp10
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp15
-rw-r--r--lib/IR/AsmWriter.cpp8
-rw-r--r--lib/IR/Core.cpp2
-rw-r--r--lib/IR/Globals.cpp45
-rw-r--r--lib/IR/Value.cpp25
-rw-r--r--lib/IR/Verifier.cpp63
-rw-r--r--lib/LTO/LTOModule.cpp7
-rw-r--r--lib/Linker/LinkModules.cpp42
-rw-r--r--lib/Target/NVPTX/NVPTXAsmPrinter.cpp2
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp22
-rw-r--r--lib/Transforms/Utils/CloneModule.cpp2
-rw-r--r--test/Assembler/addrspacecast-alias.ll4
-rw-r--r--test/Assembler/alias-addrspace.ll6
-rw-r--r--test/Assembler/alias-to-alias.ll5
-rw-r--r--test/Assembler/alias-to-alias2.ll7
-rw-r--r--test/Assembler/alias-type.ll6
-rw-r--r--test/Bitcode/old-aliases.ll8
-rw-r--r--test/CodeGen/ARM/aliases.ll2
-rw-r--r--test/CodeGen/X86/aliases.ll15
-rw-r--r--test/CodeGen/X86/dllexport-x86_64.ll2
-rw-r--r--test/Feature/alias2.ll22
-rw-r--r--test/Feature/aliases.ll4
-rw-r--r--test/Linker/Inputs/PR8300.b.ll2
-rw-r--r--test/Linker/Inputs/alias.ll2
-rw-r--r--test/Linker/Inputs/cycle.ll2
-rw-r--r--test/Linker/alias.ll6
-rw-r--r--test/Linker/cycle.ll7
-rw-r--r--test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll8
-rw-r--r--test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll2
-rw-r--r--test/Transforms/GlobalOpt/alias-resolve.ll4
-rw-r--r--test/Transforms/InstCombine/bitcast-alias-function.ll24
-rw-r--r--test/Verifier/alias.ll15
-rw-r--r--test/Verifier/bitcast-alias-address-space.ll10
-rw-r--r--tools/llvm-nm/llvm-nm.cpp8
-rw-r--r--unittests/IR/ConstantsTest.cpp10
42 files changed, 267 insertions, 316 deletions
diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index 650012e7f9..d76fc0d3af 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
@@ -679,11 +679,15 @@ Syntax::
Aliases
-------
-Aliases act as "second name" for the aliasee value (which can be either
-function, global variable, another alias or bitcast of global value).
+Aliases, unlike function or variables, don't create any new data. They
+are just a new symbol and metadata for an existing position.
+
+Aliases have a name and an aliasee that is either a global value or a
+constant expression.
+
Aliases may have an optional :ref:`linkage type <linkage>`, an optional
-:ref:`visibility style <visibility>`, and an optional :ref:`DLL storage class
-<dllstorageclass>`.
+:ref:`visibility style <visibility>`, an optional :ref:`DLL storage class
+<dllstorageclass>` and an optional :ref:`tls model <tls_model>`.
Syntax::
@@ -691,17 +695,23 @@ Syntax::
The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
-might not correctly handle dropping a weak symbol that is aliased by a non-weak
-alias.
+might not correctly handle dropping a weak symbol that is aliased.
Alias that are not ``unnamed_addr`` are guaranteed to have the same address as
the aliasee.
-The aliasee must be a definition.
+Since aliases are only a second name, some restrictions apply, of which
+some can only be checked when producing an object file:
+
+* The expression defining the aliasee must be computable at assembly
+ time. Since it is just a name, no relocations can be used.
+
+* No alias in the expression can be weak as the possibility of the
+ intermediate alias being overridden cannot be represented in an
+ object file.
-Aliases are not allowed to point to aliases with linkages that can be
-overridden. Since they are only a second name, the possibility of the
-intermediate alias being overridden cannot be represented in an object file.
+* No global value in the expression can be a declaration, since that
+ would require a relocation, which is not possible.
.. _namedmetadatastructure:
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index d9f0b4a89b..a77d1630f4 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -34,7 +34,7 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
void setParent(Module *parent);
GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
- const Twine &Name, GlobalObject *Aliasee, Module *Parent);
+ const Twine &Name, Constant *Aliasee, Module *Parent);
public:
// allocate space for exactly one operand
@@ -46,7 +46,7 @@ public:
/// the end of the specified module's alias list.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee, Module *Parent);
+ Constant *Aliasee, Module *Parent);
// Without the Aliasee.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
@@ -56,14 +56,14 @@ public:
// The module is taken from the Aliasee.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee);
+ GlobalValue *Aliasee);
// Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee);
+ GlobalValue *Aliasee);
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
- static GlobalAlias *create(const Twine &Name, GlobalObject *Aliasee);
+ static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -78,14 +78,13 @@ public:
///
void eraseFromParent() override;
- /// set/getAliasee - These methods retrive and set alias target.
- void setAliasee(GlobalObject *GO);
- const GlobalObject *getAliasee() const {
+ /// These methods retrive and set alias target.
+ void setAliasee(Constant *Aliasee);
+ const Constant *getAliasee() const {
return const_cast<GlobalAlias *>(this)->getAliasee();
}
-
- GlobalObject *getAliasee() {
- return cast_or_null<GlobalObject>(getOperand(0));
+ Constant *getAliasee() {
+ return getOperand(0);
}
static bool isValidLinkage(LinkageTypes L) {
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 3bc8b8531d..74cc18eeb1 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -40,8 +40,8 @@ public:
}
void setAlignment(unsigned Align);
- bool hasSection() const { return !getSection().empty(); }
- const std::string &getSection() const { return Section; }
+ bool hasSection() const { return !StringRef(getSection()).empty(); }
+ const char *getSection() const { return Section.c_str(); }
void setSection(StringRef S);
void copyAttributesFrom(const GlobalValue *Src) override;
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 04c97a01d6..5e99886a5f 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -146,8 +146,14 @@ public:
}
void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
- bool hasSection() const { return !getSection().empty(); }
- const std::string &getSection() const;
+ bool hasSection() const { return !StringRef(getSection()).empty(); }
+ // It is unfortunate that we have to use "char *" in here since this is
+ // always non NULL, but:
+ // * The C API expects a null terminated string, so we cannot use StringRef.
+ // * The C API expects us to own it, so we cannot use a std:string.
+ // * For GlobalAliases we can fail to find the section and we have to
+ // return "", so we cannot use a "const std::string &".
+ const char *getSection() const;
/// Global values are always pointers.
inline PointerType *getType() const {
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index f0efa9414d..dc151f2bf9 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -674,44 +674,30 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
return Error(LinkageLoc,
"symbol with local linkage must have default visibility");
- bool HasAddrSpace = Lex.getKind() == lltok::kw_addrspace;
- unsigned AddrSpace;
- LocTy AddrSpaceLoc = Lex.getLoc();
- if (ParseOptionalAddrSpace(AddrSpace))
- return true;
-
- LocTy TyLoc = Lex.getLoc();
- Type *Ty = nullptr;
- if (ParseType(Ty))
- return true;
-
- bool DifferentType = EatIfPresent(lltok::comma);
- if (HasAddrSpace && !DifferentType)
- return Error(AddrSpaceLoc, "A type is required if addrspace is given");
-
- Type *AliaseeType = nullptr;
- if (DifferentType) {
- if (ParseType(AliaseeType))
+ Constant *Aliasee;
+ LocTy AliaseeLoc = Lex.getLoc();
+ if (Lex.getKind() != lltok::kw_bitcast &&
+ Lex.getKind() != lltok::kw_getelementptr &&
+ Lex.getKind() != lltok::kw_addrspacecast &&
+ Lex.getKind() != lltok::kw_inttoptr) {
+ if (ParseGlobalTypeAndValue(Aliasee))
return true;
} else {
- AliaseeType = Ty;
- auto *PTy = dyn_cast<PointerType>(Ty);
- if (!PTy)
- return Error(TyLoc, "An alias must have pointer type");
- Ty = PTy->getElementType();
- AddrSpace = PTy->getAddressSpace();
+ // The bitcast dest type is not present, it is implied by the dest type.
+ ValID ID;
+ if (ParseValID(ID))
+ return true;
+ if (ID.Kind != ValID::t_Constant)
+ return Error(AliaseeLoc, "invalid aliasee");
+ Aliasee = ID.ConstantVal;
}
- LocTy AliaseeLoc = Lex.getLoc();
- Constant *C;
- if (ParseGlobalValue(AliaseeType, C))
- return true;
-
- auto *Aliasee = dyn_cast<GlobalObject>(C);
- if (!Aliasee)
- return Error(AliaseeLoc, "Alias must point to function or variable");
-
- assert(Aliasee->getType()->isPointerTy());
+ Type *AliaseeType = Aliasee->getType();
+ auto *PTy = dyn_cast<PointerType>(AliaseeType);
+ if (!PTy)
+ return Error(AliaseeLoc, "An alias must have pointer type");
+ Type *Ty = PTy->getElementType();
+ unsigned AddrSpace = PTy->getAddressSpace();
// Okay, create the alias but do not insert it into the module yet.
std::unique_ptr<GlobalAlias> GA(
@@ -739,11 +725,6 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
// If they agree, just RAUW the old value with the alias and remove the
// forward ref info.
- for (auto *User : Val->users()) {
- if (auto *GA = dyn_cast<GlobalAlias>(User))
- return Error(NameLoc, "Alias is pointed by alias " + GA->getName());
- }
-
Val->replaceAllUsesWith(GA.get());
Val->eraseFromParent();
ForwardRefVals.erase(I);
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 3d4ae84dbd..322879b566 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1094,28 +1094,6 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
return 1ULL << 63;
}
-// FIXME: Delete this in LLVM 4.0 and just assert that the aliasee is a
-// GlobalObject.
-static GlobalObject &
-getGlobalObjectInExpr(const DenseMap<GlobalAlias *, Constant *> &Map,
- Constant &C) {
- auto *GO = dyn_cast<GlobalObject>(&C);
- if (GO)
- return *GO;
-
- auto *GA = dyn_cast<GlobalAlias>(&C);
- if (GA)
- return getGlobalObjectInExpr(Map, *Map.find(GA)->second);
-
- auto &CE = cast<ConstantExpr>(C);
- assert(CE.getOpcode() == Instruction::BitCast ||
- CE.getOpcode() == Instruction::GetElementPtr ||
- CE.getOpcode() == Instruction::AddrSpaceCast);
- if (CE.getOpcode() == Instruction::GetElementPtr)
- assert(cast<GEPOperator>(CE).hasAllZeroIndices());
- return getGlobalObjectInExpr(Map, *CE.getOperand(0));
-}
-
/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
/// values and aliases that we can.
error_code BitcodeReader::ResolveGlobalAndAliasInits() {
@@ -1141,30 +1119,19 @@ error_code BitcodeReader::ResolveGlobalAndAliasInits() {
GlobalInitWorklist.pop_back();
}
- // FIXME: Delete this in LLVM 4.0
- // Older versions of llvm could write an alias pointing to another. We cannot
- // construct those aliases, so we first collect an alias to aliasee expression
- // and then compute the actual aliasee.
- DenseMap<GlobalAlias *, Constant *> AliasInit;
-
while (!AliasInitWorklist.empty()) {
unsigned ValID = AliasInitWorklist.back().second;
if (ValID >= ValueList.size()) {
AliasInits.push_back(AliasInitWorklist.back());
} else {
if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- AliasInit.insert(std::make_pair(AliasInitWorklist.back().first, C));
+ AliasInitWorklist.back().first->setAliasee(C);
else
return Error(ExpectedConstant);
}
AliasInitWorklist.pop_back();
}
- for (auto &Pair : AliasInit) {
- auto &GO = getGlobalObjectInExpr(AliasInit, *Pair.second);
- Pair.first->setAliasee(&GO);
- }
-
while (!FunctionPrefixWorklist.empty()) {
unsigned ValID = FunctionPrefixWorklist.back().second;
if (ValID >= ValueList.size()) {
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 7de9c6d616..6c6d0dae9e 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -870,6 +870,8 @@ void AsmPrinter::EmitFunctionBody() {
OutStreamer.AddBlankLine();
}
+static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP);
+
bool AsmPrinter::doFinalization(Module &M) {
// Emit global variables.
for (const auto &G : M.globals())
@@ -932,10 +934,6 @@ bool AsmPrinter::doFinalization(Module &M) {
for (const auto &Alias : M.aliases()) {
MCSymbol *Name = getSymbol(&Alias);
- const GlobalValue *GV = Alias.getAliasee();
- assert(!GV->isDeclaration());
- MCSymbol *Target = getSymbol(GV);
-
if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective())
OutStreamer.EmitSymbolAttribute(Name, MCSA_Global);
else if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
@@ -947,7 +945,7 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit the directives as assignments aka .set:
OutStreamer.EmitAssignment(Name,
- MCSymbolRefExpr::Create(Target, OutContext));
+ lowerConstant(Alias.getAliasee(), *this));
}
}
@@ -1248,7 +1246,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
}
// Ignore debug and non-emitted data. This handles llvm.compiler.used.
- if (GV->getSection() == "llvm.metadata" ||
+ if (StringRef(GV->getSection()) == "llvm.metadata" ||
GV->hasAvailableExternallyLinkage())
return true;
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index cd7a500f51..f1c3bb274e 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -32,6 +32,7 @@
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Support/Debug.h"
@@ -684,13 +685,23 @@ void *JITResolver::JITCompilerFn(void *Stub) {
//===----------------------------------------------------------------------===//
// JITEmitter code.
//
+
+static GlobalObject *getSimpleAliasee(Constant *C) {
+ C = cast<Constant>(C->stripPointerCasts());
+ return dyn_cast<GlobalObject>(C);
+}
+
void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
bool MayNeedFarStub) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return TheJIT->getOrEmitGlobalVariable(GV);
- if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
- return TheJIT->getPointerToGlobal(GA->getAliasee());
+ if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
+ // We can only handle simple cases.
+ if (GlobalValue *GV = getSimpleAliasee(GA->getAliasee()))
+ return TheJIT->getPointerToGlobal(GV);
+ return nullptr;
+ }
// If we have already compiled the function, return a pointer to its body.
Function *F = cast<Function>(V);
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index 8aee77ac07..14467137aa 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -1494,16 +1494,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
PrintLinkage(GA->getLinkage(), Out);
- PointerType *Ty = GA->getType();
const Constant *Aliasee = GA->getAliasee();
- if (!Aliasee || Ty != Aliasee->getType()) {
- if (unsigned AddressSpace = Ty->getAddressSpace())
- Out << "addrspace(" << AddressSpace << ") ";
- TypePrinter.print(Ty->getElementType(), Out);
- Out << ", ";
- }
if (!Aliasee) {
+ TypePrinter.print(GA->getType(), Out);
Out << " <<NULL ALIASEE>>";
} else {
writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp
index 27ce503e1c..aa373f602a 100644
--- a/lib/IR/Core.cpp
+++ b/lib/IR/Core.cpp
@@ -1286,7 +1286,7 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) {
}
const char *LLVMGetSection(LLVMValueRef Global) {
- return unwrap<GlobalValue>(Global)->getSection().c_str();
+ return unwrap<GlobalValue>(Global)->getSection();
}
void LLVMSetSection(LLVMValueRef Global, const char *Section) {
diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp
index 344a08d8f3..d5723c226a 100644
--- a/lib/IR/Globals.cpp
+++ b/lib/IR/Globals.cpp
@@ -20,6 +20,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LeakDetector.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -58,10 +59,22 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
setDLLStorageClass(Src->getDLLStorageClass());
}
-unsigned GlobalValue::getAlignment() const {
- if (auto *GA = dyn_cast<GlobalAlias>(this))
- return GA->getAliasee()->getAlignment();
+const GlobalObject *getBaseObject(const Constant &C) {
+ // FIXME: We should probably return a base + offset pair for non-zero GEPs.
+ return dyn_cast<GlobalObject>(C.stripPointerCasts());
+}
+unsigned GlobalValue::getAlignment() const {
+ if (auto *GA = dyn_cast<GlobalAlias>(this)) {
+ // In general we cannot compute this at the IR level, but we try.
+ if (const GlobalObject *GO = getBaseObject(*GA->getAliasee()))
+ return GO->getAlignment();
+
+ // FIXME: we should also be able to handle:
+ // Alias = Global + Offset
+ // Alias = Absolute
+ return 0;
+ }
return cast<GlobalObject>(this)->getAlignment();
}
@@ -80,9 +93,13 @@ void GlobalObject::copyAttributesFrom(const GlobalValue *Src) {
setSection(GV->getSection());
}
-const std::string &GlobalValue::getSection() const {
- if (auto *GA = dyn_cast<GlobalAlias>(this))
- return GA->getAliasee()->getSection();
+const char *GlobalValue::getSection() const {
+ if (auto *GA = dyn_cast<GlobalAlias>(this)) {
+ // In general we cannot compute this at the IR level, but we try.
+ if (const GlobalObject *GO = getBaseObject(*GA->getAliasee()))
+ return GO->getSection();
+ return "";
+ }
return cast<GlobalObject>(this)->getSection();
}
@@ -216,7 +233,7 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
//===----------------------------------------------------------------------===//
GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
- const Twine &Name, GlobalObject *Aliasee,
+ const Twine &Name, Constant *Aliasee,
Module *ParentModule)
: GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal,
&Op<0>(), 1, Link, Name) {
@@ -229,7 +246,7 @@ GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
LinkageTypes Link, const Twine &Name,
- GlobalObject *Aliasee, Module *ParentModule) {
+ Constant *Aliasee, Module *ParentModule) {
return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule);
}
@@ -241,18 +258,18 @@ GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee) {
+ GlobalValue *Aliasee) {
return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent());
}
GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name,
- GlobalObject *Aliasee) {
+ GlobalValue *Aliasee) {
PointerType *PTy = Aliasee->getType();
return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name,
Aliasee);
}
-GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalObject *Aliasee) {
+GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) {
return create(Aliasee->getLinkage(), Name, Aliasee);
}
@@ -272,4 +289,8 @@ void GlobalAlias::eraseFromParent() {
getParent()->getAliasList().erase(this);
}
-void GlobalAlias::setAliasee(GlobalObject *Aliasee) { setOperand(0, Aliasee); }
+void GlobalAlias::setAliasee(Constant *Aliasee) {
+ assert(!Aliasee || Aliasee->getType() == getType() &&
+ "Alias and aliasee types should match!");
+ setOperand(0, Aliasee);
+}
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index d734e4ea81..cc599745d5 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -301,27 +301,6 @@ void Value::takeName(Value *V) {
ST->reinsertValue(this);
}
-static GlobalObject &findReplacementForAliasUse(Value &C) {
- if (auto *GO = dyn_cast<GlobalObject>(&C))
- return *GO;
- if (auto *GA = dyn_cast<GlobalAlias>(&C))
- return *GA->getAliasee();
- auto *CE = cast<ConstantExpr>(&C);
- assert(CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::GetElementPtr ||
- CE->getOpcode() == Instruction::AddrSpaceCast);
- if (CE->getOpcode() == Instruction::GetElementPtr)
- assert(cast<GEPOperator>(CE)->hasAllZeroIndices());
- return findReplacementForAliasUse(*CE->getOperand(0));
-}
-
-static void replaceAliasUseWith(Use &U, Value *New) {
- GlobalObject &Replacement = findReplacementForAliasUse(*New);
- assert(&cast<GlobalObject>(*U) != &Replacement &&
- "replaceAliasUseWith cannot form an alias cycle");
- U.set(&Replacement);
-}
-
#ifndef NDEBUG
static bool contains(SmallPtrSet<ConstantExpr *, 4> &Cache, ConstantExpr *Expr,
Constant *C) {
@@ -373,10 +352,6 @@ void Value::replaceAllUsesWith(Value *New) {
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
// constant because they are uniqued.
if (auto *C = dyn_cast<Constant>(U.getUser())) {
- if (isa<GlobalAlias>(C)) {
- replaceAliasUseWith(U, New);
- continue;
- }
if (!isa<GlobalValue>(C)) {
C->replaceUsesOfWithOnConstant(this, New, &U);
continue;
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index bcc38c1ad5..1719cb2759 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -241,6 +241,9 @@ private:
void visitGlobalValue(const GlobalValue &GV);
void visitGlobalVariable(const GlobalVariable &GV);
void visitGlobalAlias(const GlobalAlias &GA);
+ void visitAliaseeSubExpr(const GlobalAlias &A, const Constant &C);
+ void visitAliaseeSubExpr(SmallPtrSet<const GlobalAlias *, 4> &Visited,
+ const GlobalAlias &A, const Constant &C);
void visitNamedMDNode(const NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F);
void visitModuleIdents(const Module &M);
@@ -474,36 +477,52 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
visitGlobalValue(GV);
}
+void Verifier::visitAliaseeSubExpr(const GlobalAlias &GA, const Constant &C) {
+ SmallPtrSet<const GlobalAlias*, 4> Visited;
+ Visited.insert(&GA);
+ visitAliaseeSubExpr(Visited, GA, C);
+}
+
+void Verifier::visitAliaseeSubExpr(SmallPtrSet<const GlobalAlias *, 4> &Visited,
+ const GlobalAlias &GA, const Constant &C) {
+ if (const auto *GV = dyn_cast<GlobalValue>(&C)) {
+ Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA);
+
+ if (const auto *GA2 = dyn_cast<GlobalAlias>(GV)) {
+ Assert1(Visited.insert(GA2), "Aliases cannot form a cycle", &GA);
+
+ Assert1(!GA2->mayBeOverridden(), "Alias cannot point to a weak alias",
+ &GA);
+ }
+ }
+
+ if (const auto *CE = dyn_cast<ConstantExpr>(&C))
+ VerifyConstantExprBitcastType(CE);
+
+ for (const Use &U : C.operands()) {
+ Value *V = &*U;
+ if (const auto *GA2 = dyn_cast<GlobalAlias>(V))
+ visitAliaseeSubExpr(Visited, GA, *GA2->getAliasee());
+ else if (const auto *C2 = dyn_cast<Constant>(V))
+ visitAliaseeSubExpr(Visited, GA, *C2);
+ }
+}
+
void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
Assert1(!GA.getName().empty(),
"Alias name cannot be empty!", &GA);
Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()),
"Alias should have external or external weak linkage!", &GA);
- Assert1(GA.getAliasee(),
- "Aliasee cannot be NULL!", &GA);
- Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
-
const Constant *Aliasee = GA.getAliasee();
- const GlobalValue *GV = dyn_cast<GlobalValue>(Aliasee);
-
- if (!GV) {
- const ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee);
- if (CE && (CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::AddrSpaceCast ||
- CE->getOpcode() == Instruction::GetElementPtr))
- GV = dyn_cast<GlobalValue>(CE->getOperand(0));
+ Assert1(Aliasee, "Aliasee cannot be NULL!", &GA);
+ Assert1(GA.getType() == Aliasee->getType(),
+ "Alias and aliasee types should match!", &GA);
+ Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
- Assert1(GV, "Aliasee should be either GlobalValue, bitcast or "
- "addrspacecast of GlobalValue",
- &GA);
+ Assert1(isa<GlobalValue>(Aliasee) || isa<ConstantExpr>(Aliasee),
+ "Aliasee should be either GlobalValue or ConstantExpr", &GA);
- VerifyConstantExprBitcastType(CE);
- }
- Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA);
- if (const GlobalAlias *GAAliasee = dyn_cast<GlobalAlias>(GV)) {
- Assert1(!GAAliasee->mayBeOverridden(), "Alias cannot point to a weak alias",
- &GA);
- }
+ visitAliaseeSubExpr(GA, *Aliasee);
visitGlobalValue(GA);
}
diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp
index d117514265..f7f6a3c4b8 100644
--- a/lib/LTO/LTOModule.cpp
+++ b/lib/LTO/LTOModule.cpp
@@ -334,21 +334,22 @@ void LTOModule::addDefinedDataSymbol(const GlobalValue *v) {
// from the ObjC data structures generated by the front end.
// special case if this data blob is an ObjC class definition
- if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) {
+ std::string Section = v->getSection();
+ if (Section.compare(0, 15, "__OBJC,__class,") == 0) {
if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
addObjCClass(gv);
}
}
// special case if this data blob is an ObjC category definition
- else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) {
+ else if (Section.compare(0, 18, "__OBJC,__category,") == 0) {
if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
addObjCCategory(gv);
}
}
// special case if this data blob is the list of referenced classes
- else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) {
+ else if (Section.compare(0, 18, "__OBJC,__cls_refs,") == 0) {
if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) {
addObjCClassRef(gv);
}
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 45f2d4e03a..ad8e01dc1b 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -389,8 +389,6 @@ namespace {
/// actually need, but this allows us to reuse the ValueMapper code.
ValueToValueMapTy ValueMap;
- std::vector<std::pair<GlobalValue *, GlobalAlias *>> ReplaceWithAlias;
-
struct AppendingVarInfo {
GlobalVariable *NewGV; // New aggregate global in dest module.
Constant *DstInit; // Old initializer from dest module.
@@ -723,7 +721,7 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
return emitError(
"Appending variables with different unnamed_addr need to be linked!");
- if (DstGV->getSection() != SrcGV->getSection())
+ if (StringRef(DstGV->getSection()) != SrcGV->getSection())
return emitError(
"Appending variables with different section name need to be linked!");
@@ -929,8 +927,11 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
if (NewVisibility)
NewDA->setVisibility(*NewVisibility);
- if (DGV)
- ReplaceWithAlias.push_back(std::make_pair(DGV, NewDA));
+ if (DGV) {
+ // Any uses of DGV need to change to NewDA, with cast.
+ DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));
+ DGV->eraseFromParent();
+ }
ValueMap[SGA] = NewDA;
return false;
@@ -1016,19 +1017,6 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) {
}
-static GlobalObject &getGlobalObjectInExpr(Constant &C) {
- auto *GO = dyn_cast<GlobalObject>(&C);
- if (GO)
- return *GO;
- auto *GA = dyn_cast<GlobalAlias>(&C);
- if (GA)
- return *GA->getAliasee();
- auto &CE = cast<ConstantExpr>(C);
- assert(CE.getOpcode() == Instruction::BitCast ||
- CE.getOpcode() == Instruction::AddrSpaceCast);
- return getGlobalObjectInExpr(*CE.getOperand(0));
-}
-
/// linkAliasBodies - Insert all of the aliases in Src into the Dest module.
void ModuleLinker::linkAliasBodies() {
for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end();
@@ -1039,25 +1027,9 @@ void ModuleLinker::linkAliasBodies() {
GlobalAlias *DA = cast<GlobalAlias>(ValueMap[I]);
Constant *Val =
MapValue(Aliasee, ValueMap, RF_None, &TypeMap, &ValMaterializer);
- DA->setAliasee(&getGlobalObjectInExpr(*Val));
+ DA->setAliasee(Val);
}
}
-
- // Any uses of DGV need to change to NewDA, with cast.
- for (auto &Pair : ReplaceWithAlias) {
- GlobalValue *DGV = Pair.first;
- GlobalAlias *NewDA = Pair.second;
-
- for (auto *User : DGV->users()) {
- if (auto *GA = dyn_cast<GlobalAlias>(User)) {
- if (GA == NewDA)
- report_fatal_error("Linking these modules creates an alias cycle.");
- }
- }
-
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));
- DGV->eraseFromParent();
- }
}
/// linkNamedMDNodes - Insert all of the named MDNodes in Src into the Dest
diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 4ec575ff34..e6cbf64359 100644
--- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -1356,7 +1356,7 @@ void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar,
// Skip meta data
if (GVar->hasSection()) {
- if (GVar->getSection() == "llvm.metadata")
+ if (GVar->getSection() == StringRef("llvm.metadata"))
return;
}
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 9d78586495..e9db2a8fa4 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -273,18 +273,16 @@ SDValue XCoreTargetLowering::getGlobalAddressWrapper(SDValue GA,
SelectionDAG &DAG) const {
// FIXME there is no actual debug info here
SDLoc dl(GA);
- const GlobalValue *UnderlyingGV = GV;
- // If GV is an alias then use the aliasee to determine the wrapper type
- if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
- UnderlyingGV = GA->getAliasee();
- if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) {
- if ((GVar->isConstant() && GV->hasLocalLinkage()) ||
- (GVar->hasSection() &&
- StringRef(GVar->getSection()).startswith(".cp.")))
- return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
- return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
- }
- return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
+
+ if (GV->getType()->getElementType()->isFunctionTy())
+ return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
+
+ const auto *GVar = dyn_cast<GlobalVariable>(GV);
+ if ((GV->hasSection() && StringRef(GV->getSection()).startswith(".cp.")) ||
+ (GVar && GVar->isConstant() && GV->hasLocalLinkage()))
+ return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
+
+ return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
}
static bool IsSmallObject(const GlobalValue *GV, const XCoreTargetLowering &XTL) {
diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp
index eb67db1f85..3f75b3e677 100644
--- a/lib/Transforms/Utils/CloneModule.cpp
+++ b/lib/Transforms/Utils/CloneModule.cpp
@@ -107,7 +107,7 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
I != E; ++I) {
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
- if (const GlobalObject *C = I->getAliasee())
+ if (const Constant *C = I->getAliasee())
GA->setAliasee(cast<GlobalObject>(MapValue(C, VMap)));
}
diff --git a/test/Assembler/addrspacecast-alias.ll b/test/Assembler/addrspacecast-alias.ll
index 052a1414ea..7d00ac4f8f 100644
--- a/test/Assembler/addrspacecast-alias.ll
+++ b/test/Assembler/addrspacecast-alias.ll
@@ -3,5 +3,5 @@
; Test that global aliases are allowed to be constant addrspacecast
@i = internal addrspace(1) global i8 42
-@ia = alias internal addrspace(2) i8 addrspace(3)*, i8 addrspace(1)* @i
-; CHECK: @ia = alias internal addrspace(2) i8 addrspace(3)*, i8 addrspace(1)* @i
+@ia = alias internal addrspacecast (i8 addrspace(1)* @i to i8 addrspace(2)* addrspace(3)*)
+; CHECK: @ia = alias internal addrspacecast (i8 addrspace(1)* @i to i8 addrspace(2)* addrspace(3)*)
diff --git a/test/Assembler/alias-addrspace.ll b/test/Assembler/alias-addrspace.ll
deleted file mode 100644
index 6d378e45fa..0000000000
--- a/test/Assembler/alias-addrspace.ll
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: not llvm-as %s 2>&1 | FileCheck %s
-
-@foo = global i32 42
-@bar = alias internal addrspace(1) i32* @foo
-
-CHECK: error: A type is required if addrspace is given
diff --git a/test/Assembler/alias-to-alias.ll b/test/Assembler/alias-to-alias.ll
deleted file mode 100644
index 1ea99bbb69..0000000000
--- a/test/Assembler/alias-to-alias.ll
+++ /dev/null
@@ -1,5 +0,0 @@
-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
-; CHECK: Alias must point to function or variable
-
-@b1 = alias i32* @c1
-@c1 = alias i32* @b1
diff --git a/test/Assembler/alias-to-alias2.ll b/test/Assembler/alias-to-alias2.ll
deleted file mode 100644
index a8a0196f43..0000000000
--- a/test/Assembler/alias-to-alias2.ll
+++ /dev/null
@@ -1,7 +0,0 @@
-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
-; CHECK: error: Alias is pointed by alias b1
-
-@g = global i32 42
-
-@b1 = alias i32* @c1
-@c1 = alias i32* @g
diff --git a/test/Assembler/alias-type.ll b/test/Assembler/alias-type.ll
deleted file mode 100644
index ead3e95243..0000000000
--- a/test/Assembler/alias-type.ll
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: not llvm-as %s 2>&1 | FileCheck %s
-
-@foo = global i32 42
-@bar = alias i32 @foo
-
-CHECK: error: An alias must have pointer type
diff --git a/test/Bitcode/old-aliases.ll b/test/Bitcode/old-aliases.ll
index 4ef47c03dd..7a0eea2f3f 100644
--- a/test/Bitcode/old-aliases.ll
+++ b/test/Bitcode/old-aliases.ll
@@ -10,13 +10,13 @@
; CHECK: @v2 = global [1 x i32] zeroinitializer
@v3 = alias bitcast (i32* @v1 to i16*)
-; CHECK: @v3 = alias i16, i32* @v1
+; CHECK: @v3 = alias bitcast (i32* @v1 to i16*)
@v4 = alias getelementptr ([1 x i32]* @v2, i32 0, i32 0)
-; CHECK: @v4 = alias i32, [1 x i32]* @v2
+; CHECK: @v4 = alias getelementptr inbounds ([1 x i32]* @v2, i32 0, i32 0)
@v5 = alias i32 addrspace(2)* addrspacecast (i32 addrspace(0)* @v1 to i32 addrspace(2)*)
-; CHECK: @v5 = alias addrspace(2) i32, i32* @v1
+; CHECK: @v5 = alias addrspacecast (i32* @v1 to i32 addrspace(2)*)
@v6 = alias i16* @v3
-; CHECK: @v6 = alias i16, i32* @v1
+; CHECK: @v6 = alias i16* @v3
diff --git a/test/CodeGen/ARM/aliases.ll b/test/CodeGen/ARM/aliases.ll
index 4de305b93b..f55ae10b24 100644
--- a/test/CodeGen/ARM/aliases.ll
+++ b/test/CodeGen/ARM/aliases.ll
@@ -29,7 +29,7 @@ define i32 @foo_f() {
@bar_i = alias internal i32* @bar
-@A = alias i64, i32* @bar
+@A = alias bitcast (i32* @bar to i64*)
define i32 @test() {
entry:
diff --git a/test/CodeGen/X86/aliases.ll b/test/CodeGen/X86/aliases.ll
index d207880d66..bf55644de4 100644
--- a/test/CodeGen/X86/aliases.ll
+++ b/test/CodeGen/X86/aliases.ll
@@ -38,7 +38,7 @@ define i32 @foo_f() {
@bar_i = alias internal i32* @bar
; CHECK-DAG: .globl A
-@A = alias i64, i32* @bar
+@A = alias bitcast (i32* @bar to i64*)
; CHECK-DAG: .globl bar_h
; CHECK-DAG: .hidden bar_h
@@ -48,6 +48,19 @@ define i32 @foo_f() {
; CHECK-DAG: .protected bar_p
@bar_p = protected alias i32* @bar
+; CHECK-DAG: test2 = bar+4
+@test2 = alias getelementptr(i32 *@bar, i32 1)
+
+; CHECK-DAG: test3 = 42
+@test3 = alias inttoptr(i32 42 to i32*)
+
+; CHECK-DAG: test4 = bar
+@test4 = alias inttoptr(i64 ptrtoint (i32* @bar to i64) to i32*)
+
+; CHECK-DAG: test5 = test2-bar
+@test5 = alias inttoptr(i32 sub (i32 ptrtoint (i32* @test2 to i32),
+ i32 ptrtoint (i32* @bar to i32)) to i32*)
+
; CHECK-DAG: .globl test
define i32 @test() {
entry:
diff --git a/test/CodeGen/X86/dllexport-x86_64.ll b/test/CodeGen/X86/dllexport-x86_64.ll
index f4dec4ff59..0d5afa1b13 100644
--- a/test/CodeGen/X86/dllexport-x86_64.ll
+++ b/test/CodeGen/X86/dllexport-x86_64.ll
@@ -73,7 +73,7 @@ define weak_odr dllexport void @weak1() {
@weak_alias = dllexport alias weak_odr void()* @f1
@blob = global [6 x i8] c"\B8*\00\00\00\C3", section ".text", align 16
-@blob_alias = dllexport alias i32 (), [6 x i8]* @blob
+@blob_alias = dllexport alias bitcast ([6 x i8]* @blob to i32 ()*)
; CHECK: .section .drectve
; WIN32: " /EXPORT:Var1,DATA"
diff --git a/test/Feature/alias2.ll b/test/Feature/alias2.ll
index bc542ffd77..73c874f2b9 100644
--- a/test/Feature/alias2.ll
+++ b/test/Feature/alias2.ll
@@ -6,17 +6,23 @@
@v2 = global [1 x i32] zeroinitializer
; CHECK: @v2 = global [1 x i32] zeroinitializer
-@a1 = alias i16, i32* @v1
-; CHECK: @a1 = alias i16, i32* @v1
+@v3 = global [2 x i16] zeroinitializer
+; CHECK: @v3 = global [2 x i16] zeroinitializer
-@a2 = alias i32, [1 x i32]* @v2
-; CHECK: @a2 = alias i32, [1 x i32]* @v2
+@a1 = alias bitcast (i32* @v1 to i16*)
+; CHECK: @a1 = alias bitcast (i32* @v1 to i16*)
-@a3 = alias addrspace(2) i32, i32* @v1
-; CHECK: @a3 = alias addrspace(2) i32, i32* @v1
+@a2 = alias bitcast([1 x i32]* @v2 to i32*)
+; CHECK: @a2 = alias getelementptr inbounds ([1 x i32]* @v2, i32 0, i32 0)
-@a4 = alias i16, i32* @v1
-; CHECK: @a4 = alias i16, i32* @v1
+@a3 = alias addrspacecast (i32* @v1 to i32 addrspace(2)*)
+; CHECK: @a3 = alias addrspacecast (i32* @v1 to i32 addrspace(2)*)
+
+@a4 = alias bitcast (i32* @v1 to i16*)
+; CHECK: @a4 = alias bitcast (i32* @v1 to i16*)
@a5 = thread_local(localdynamic) alias i32* @v1
; CHECK: @a5 = thread_local(localdynamic) alias i32* @v1
+
+@a6 = alias getelementptr ([2 x i16]* @v3, i32 1, i32 1)
+; CHECK: @a6 = alias getelementptr ([2 x i16]* @v3, i32 1, i32 1)
diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll
index b2ce82a838..7fe9d0b374 100644
--- a/test/Feature/aliases.ll
+++ b/test/Feature/aliases.ll
@@ -7,6 +7,7 @@
@bar = global i32 0
@foo1 = alias i32* @bar
@foo2 = alias i32* @bar
+@foo3 = alias i32* @foo2
%FunTy = type i32()
@@ -14,10 +15,11 @@ define i32 @foo_f() {
ret i32 0
}
@bar_f = alias weak_odr %FunTy* @foo_f
+@bar_ff = alias i32()* @bar_f
@bar_i = alias internal i32* @bar
-@A = alias i64, i32* @bar
+@A = alias bitcast (i32* @bar to i64*)
define i32 @test() {
entry:
diff --git a/test/Linker/Inputs/PR8300.b.ll b/test/Linker/Inputs/PR8300.b.ll
index 362d309a19..9e538f5d28 100644
--- a/test/Linker/Inputs/PR8300.b.ll
+++ b/test/Linker/Inputs/PR8300.b.ll
@@ -1,7 +1,7 @@
%foo = type { [8 x i8] }
%bar = type { [9 x i8] }
-@zed = alias void (%foo*), void (%bar*)* @xyz
+@zed = alias bitcast (void (%bar*)* @xyz to void (%foo*)*)
define void @xyz(%bar* %this) {
entry:
diff --git a/test/Linker/Inputs/alias.ll b/test/Linker/Inputs/alias.ll
index b869cae71e..f379476e76 100644
--- a/test/Linker/Inputs/alias.ll
+++ b/test/Linker/Inputs/alias.ll
@@ -1,3 +1,3 @@
@zed = global i32 42
@foo = alias i32* @zed
-@foo2 = alias i16, i32* @zed
+@foo2 = alias bitcast (i32* @zed to i16*)
diff --git a/test/Linker/Inputs/cycle.ll b/test/Linker/Inputs/cycle.ll
deleted file mode 100644
index d0eddb6e7c..0000000000
--- a/test/Linker/Inputs/cycle.ll
+++ /dev/null
@@ -1,2 +0,0 @@
-@foo = alias i32* @bar
-@bar = weak global i32 0
diff --git a/test/Linker/alias.ll b/test/Linker/alias.ll
index 5809a15082..bce51ad983 100644
--- a/test/Linker/alias.ll
+++ b/test/Linker/alias.ll
@@ -5,12 +5,12 @@
; CHECK-DAG: @foo = alias i32* @zed
@bar = alias i32* @foo
-; CHECK-DAG: @bar = alias i32* @zed
+; CHECK-DAG: @bar = alias i32* @foo
@foo2 = weak global i32 0
-; CHECK-DAG: @foo2 = alias i16, i32* @zed
+; CHECK-DAG: @foo2 = alias bitcast (i32* @zed to i16*)
@bar2 = alias i32* @foo2
-; CHECK-DAG: @bar2 = alias i32* @zed
+; CHECK-DAG: @bar2 = alias bitcast (i16* @foo2 to i32*)
; CHECK-DAG: @zed = global i32 42
diff --git a/test/Linker/cycle.ll b/test/Linker/cycle.ll
deleted file mode 100644
index 7d9ad2d9d6..0000000000
--- a/test/Linker/cycle.ll
+++ /dev/null
@@ -1,7 +0,0 @@
-; RUN: not llvm-link %s %S/Inputs/cycle.ll 2>&1 | FileCheck %s
-; RUN: not llvm-link %S/Inputs/cycle.ll %s 2>&1 | FileCheck %s
-
-; CHECK: Linking these modules creates an alias cycle
-
-@foo = weak global i32 0
-@bar = alias i32* @foo
diff --git a/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll b/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
index 4b967997ce..0bdced5114 100644
--- a/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
+++ b/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
@@ -11,8 +11,8 @@
@L1 = alias i32* @A
; CHECK: @L1 = alias i32* @A
-@L2 = alias internal i32* @A
-; DEAD-NOT: @L2
+@L2 = alias internal i32* @L1
+; CHECK: @L2 = alias internal i32* @L1
-@L3 = alias i32* @A
-; CHECK: @L3 = alias i32* @A
+@L3 = alias i32* @L2
+; CHECK: @L3 = alias i32* @L2
diff --git a/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll b/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
index 03d6ee4f8a..d6a565ad10 100644
--- a/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
+++ b/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
@@ -2,7 +2,7 @@
@g = global i32 0
-@a = alias i8, i32* @g
+@a = alias bitcast (i32* @g to i8*)
define void @f() {
%tmp = load i8* @a
diff --git a/test/Transforms/GlobalOpt/alias-resolve.ll b/test/Transforms/GlobalOpt/alias-resolve.ll
index bd07b31b23..2d5a956d14 100644
--- a/test/Transforms/GlobalOpt/alias-resolve.ll
+++ b/test/Transforms/GlobalOpt/alias-resolve.ll
@@ -1,9 +1,9 @@
; RUN: opt < %s -globalopt -S | FileCheck %s
-@foo1 = alias void ()* @bar2
+@foo1 = alias void ()* @foo2
; CHECK: @foo1 = alias void ()* @bar2
-@foo2 = alias void()* @bar2
+@foo2 = alias void()* @bar1
; CHECK: @foo2 = alias void ()* @bar2
@bar1 = alias void ()* @bar2
diff --git a/test/Transforms/InstCombine/bitcast-alias-function.ll b/test/Transforms/InstCombine/bitcast-alias-function.ll
index 284960b113..a6b56f94ff 100644
--- a/test/Transforms/InstCombine/bitcast-alias-function.ll
+++ b/test/Transforms/InstCombine/bitcast-alias-function.ll
@@ -6,46 +6,46 @@ target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16
; Cases that should be bitcast
; Test cast between scalars with same bit sizes
-@alias_i32_to_f32 = alias float (float), i32 (i32)* @func_i32
+@alias_i32_to_f32 = alias bitcast (i32 (i32)* @func_i32 to float (float)*)
; Test cast between vectors with same number of elements and bit sizes
-@alias_v2i32_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i32> (<2 x i32>)* @func_v2i32
+@alias_v2i32_to_v2f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*)
; Test cast from vector to scalar with same number of bits
-@alias_v2f32_to_i64 = alias <2 x float> (<2 x float>), i64 (i64)* @func_i64
+@alias_v2f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*)
; Test cast from scalar to vector with same number of bits
-@alias_i64_to_v2f32 = alias i64 (i64), <2 x float> (<2 x float>)* @func_v2f32
+@alias_i64_to_v2f32 = alias bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*)
; Test cast between vectors of pointers
-@alias_v2i32p_to_v2i64p = alias <2 x i64*> (<2 x i64*>), <2 x i32*> (<2 x i32*>)* @func_v2i32p
+@alias_v2i32p_to_v2i64p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*)
; Cases that should be invalid and unchanged
; Test cast between scalars with different bit sizes
-@alias_i64_to_f32 = alias float (float), i64 (i64)* @func_i64
+@alias_i64_to_f32 = alias bitcast (i64 (i64)* @func_i64 to float (float)*)
; Test cast between vectors with different bit sizes but the
; same number of elements
-@alias_v2i64_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i64> (<2 x i64>)* @func_v2i64
+@alias_v2i64_to_v2f32 = alias bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)
; Test cast between vectors with same number of bits and different
; numbers of elements
-@alias_v2i32_to_v4f32 = alias <4 x float> (<4 x float>), <2 x i32> (<2 x i32>)* @func_v2i32
+@alias_v2i32_to_v4f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)
; Test cast between scalar and vector with different number of bits
-@alias_i64_to_v4f32 = alias i64 (i64), <4 x float> (<4 x float>)* @func_v4f32
+@alias_i64_to_v4f32 = alias bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)
; Test cast between vector and scalar with different number of bits
-@alias_v4f32_to_i64 = alias <4 x float> (<4 x float>), i64 (i64)* @func_i64
+@alias_v4f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)
; Test cast from scalar to vector of pointers with same number of bits
; We don't know the pointer size at this point, so this can't be done
-@alias_i64_to_v2i32p = alias i64 (i64), <2 x i32*> (<2 x i32*>)* @func_v2i32p
+@alias_i64_to_v2i32p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)
; Test cast between vector of pointers and scalar with different number of bits
-@alias_v4i32p_to_i64 = alias <4 x i32*> (<4 x i32*>), i64 (i64)* @func_i64
+@alias_v4i32p_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)
diff --git a/test/Verifier/alias.ll b/test/Verifier/alias.ll
index e3636bc701..ff02a37bab 100644
--- a/test/Verifier/alias.ll
+++ b/test/Verifier/alias.ll
@@ -10,3 +10,18 @@ declare void @f()
@ga = alias i32* @g
; CHECK: Alias must point to a definition
; CHECK-NEXT: @ga
+
+
+@test2_a = alias i32* @test2_b
+@test2_b = alias i32* @test2_a
+; CHECK: Aliases cannot form a cycle
+; CHECK-NEXT: i32* @test2_a
+; CHECK-NEXT: Aliases cannot form a cycle
+; CHECK-NEXT: i32* @test2_b
+
+
+@test3_a = global i32 42
+@test3_b = alias weak i32* @test3_a
+@test3_c = alias i32* @test3_b
+; CHECK: Alias cannot point to a weak alias
+; CHECK-NEXT: i32* @test3_c
diff --git a/test/Verifier/bitcast-alias-address-space.ll b/test/Verifier/bitcast-alias-address-space.ll
new file mode 100644
index 0000000000..d9794d9e33
--- /dev/null
+++ b/test/Verifier/bitcast-alias-address-space.ll
@@ -0,0 +1,10 @@
+; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
+
+; CHECK: error: invalid cast opcode for cast from 'i32 addrspace(2)*' to 'i32 addrspace(1)*'
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+
+@data = addrspace(2) global i32 27
+
+@illegal_alias_data = alias bitcast (i32 addrspace(2)* @data to i32 addrspace(1)*)
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index d1cfefe6a3..476b49486a 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -415,15 +415,11 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
}
static char getSymbolNMTypeChar(const GlobalValue &GV) {
- if (isa<Function>(GV))
+ if (GV.getType()->getElementType()->isFunctionTy())
return 't';
// FIXME: should we print 'b'? At the IR level we cannot be sure if this
// will be in bss or not, but we could approximate.
- if (isa<GlobalVariable>(GV))
- return 'd';
- const GlobalAlias *GA = cast<GlobalAlias>(&GV);
- const GlobalValue *AliasedGV = GA->getAliasee();
- return getSymbolNMTypeChar(*AliasedGV);
+ return 'd';
}
static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) {
diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index c11729c08f..0cd8549982 100644
--- a/unittests/IR/ConstantsTest.cpp
+++ b/unittests/IR/ConstantsTest.cpp
@@ -269,16 +269,6 @@ TEST(ConstantsTest, ReplaceWithConstantTest) {
"this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");
}
-TEST(ConstantsTest, ReplaceInAliasTest) {
- std::unique_ptr<Module> M(new Module("MyModule", getGlobalContext()));
-
- Type *Int32Ty = Type::getInt32Ty(getGlobalContext());
- auto *Global = cast<GlobalObject>(M->getOrInsertGlobal("dummy", Int32Ty));
- auto *GA = GlobalAlias::create(GlobalValue::ExternalLinkage, "alias", Global);
- EXPECT_DEATH(Global->replaceAllUsesWith(GA),
- "replaceAliasUseWith cannot form an alias cycle");
-}
-
#endif
#endif