summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/IR/GlobalAlias.h21
-rw-r--r--lib/AsmParser/LLParser.cpp63
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp35
-rw-r--r--lib/IR/AsmWriter.cpp8
-rw-r--r--lib/IR/Core.cpp2
-rw-r--r--lib/IR/Globals.cpp46
-rw-r--r--lib/IR/Value.cpp28
-rw-r--r--lib/IR/Verifier.cpp6
-rw-r--r--lib/Linker/LinkModules.cpp45
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp2
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp6
-rw-r--r--lib/Transforms/Utils/CloneModule.cpp4
-rw-r--r--test/Assembler/2009-04-25-AliasGEP.ll8
-rw-r--r--test/Assembler/addrspacecast-alias.ll5
-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.ll22
-rw-r--r--test/Bitcode/old-aliases.ll.bcbin0 -> 368 bytes
-rw-r--r--test/CodeGen/ARM/aliases.ll2
-rw-r--r--test/CodeGen/X86/aliases.ll2
-rw-r--r--test/CodeGen/X86/dllexport-x86_64.ll2
-rw-r--r--test/CodeGen/X86/dllexport.ll2
-rw-r--r--test/Feature/alias2.ll19
-rw-r--r--test/Feature/aliases.ll4
-rw-r--r--test/Linker/Inputs/PR8300.b.ll2
-rw-r--r--test/Linker/Inputs/alias.ll3
-rw-r--r--test/Linker/Inputs/cycle.ll2
-rw-r--r--test/Linker/alias.ll16
-rw-r--r--test/Linker/cycle.ll7
-rw-r--r--test/Other/extract-alias.ll6
-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/Transforms/Internalize/2009-01-05-InternalizeAliases.ll4
-rw-r--r--test/Verifier/aliasing-chain.ll6
-rw-r--r--test/Verifier/bitcast-alias-address-space.ll10
-rw-r--r--unittests/IR/ConstantsTest.cpp12
-rw-r--r--unittests/Transforms/Utils/SpecialCaseList.cpp2
41 files changed, 308 insertions, 156 deletions
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index da228471c9..4059891b96 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -41,7 +41,7 @@ public:
/// If a parent module is specified, the alias is automatically inserted into
/// the end of the specified module's alias list.
GlobalAlias(Type *Ty, LinkageTypes Linkage, const Twine &Name = "",
- Constant* Aliasee = nullptr, Module *Parent = nullptr,
+ GlobalObject *Aliasee = nullptr, Module *Parent = nullptr,
unsigned AddressSpace = 0);
/// Provide fast operand accessors
@@ -58,18 +58,19 @@ public:
void eraseFromParent() override;
/// set/getAliasee - These methods retrive and set alias target.
- void setAliasee(Constant *GV);
- const Constant *getAliasee() const {
- return getOperand(0);
+ void setAliasee(GlobalObject *GO);
+ const GlobalObject *getAliasee() const {
+ return const_cast<GlobalAlias *>(this)->getAliasee();
}
- Constant *getAliasee() {
- return getOperand(0);
+
+ GlobalObject *getAliasee() {
+ return cast_or_null<GlobalObject>(getOperand(0));
+ }
+
+ GlobalObject *getAliasedGlobal() {
+ return getAliasee();
}
- /// This method tries to ultimately resolve the alias by going through the
- /// aliasing chain and trying to find the very last global. Returns NULL if a
- /// cycle was found.
- GlobalObject *getAliasedGlobal();
const GlobalObject *getAliasedGlobal() const {
return const_cast<GlobalAlias *>(this)->getAliasedGlobal();
}
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index e5813f0d21..b457672d77 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -630,10 +630,11 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
/// ParseAlias:
/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
/// OptionalLinkage Aliasee
+/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
+/// OptionalLinkage OptionalAddrSpace Type, Aliasee
+///
/// Aliasee
/// ::= TypeAndValue
-/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
-/// ::= 'getelementptr' 'inbounds'? '(' ... ')'
///
/// Everything through DLL storage class has already been parsed.
///
@@ -655,28 +656,49 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
return Error(LinkageLoc,
"symbol with local linkage must have default visibility");
- Constant *Aliasee;
- LocTy AliaseeLoc = Lex.getLoc();
- if (Lex.getKind() != lltok::kw_bitcast &&
- Lex.getKind() != lltok::kw_getelementptr) {
- if (ParseGlobalTypeAndValue(Aliasee)) return true;
+ 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))
+ return true;
} else {
- // 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;
+ 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();
}
- if (!Aliasee->getType()->isPointerTy())
- return Error(AliaseeLoc, "alias must have pointer type");
+ 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());
// Okay, create the alias but do not insert it into the module yet.
- PointerType *PTy = cast<PointerType>(Aliasee->getType());
std::unique_ptr<GlobalAlias> GA(
- new GlobalAlias(PTy->getElementType(), (GlobalValue::LinkageTypes)Linkage,
- Name, Aliasee, nullptr, PTy->getAddressSpace()));
+ new GlobalAlias(Ty, (GlobalValue::LinkageTypes)Linkage, Name, Aliasee,
+ /*Parent*/ nullptr, AddrSpace));
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
@@ -698,6 +720,11 @@ 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 ea33578502..14546c0fe4 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1092,6 +1092,28 @@ 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() {
@@ -1117,19 +1139,30 @@ 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]))
- AliasInitWorklist.back().first->setAliasee(C);
+ AliasInit.insert(std::make_pair(AliasInitWorklist.back().first, 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/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index 3cbb1d1049..0fef0d0a18 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -1493,10 +1493,16 @@ 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 40c1c70257..100c9def18 100644
--- a/lib/IR/Core.cpp
+++ b/lib/IR/Core.cpp
@@ -1491,7 +1491,7 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
auto *PTy = cast<PointerType>(unwrap(Ty));
return wrap(new GlobalAlias(
PTy->getElementType(), GlobalValue::ExternalLinkage, Name,
- unwrap<Constant>(Aliasee), unwrap(M), PTy->getAddressSpace()));
+ unwrap<GlobalObject>(Aliasee), unwrap(M), PTy->getAddressSpace()));
}
/*--.. Operations on functions .............................................--*/
diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp
index 8e7478496f..d4fcf58e98 100644
--- a/lib/IR/Globals.cpp
+++ b/lib/IR/Globals.cpp
@@ -214,15 +214,11 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
//===----------------------------------------------------------------------===//
GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, const Twine &Name,
- Constant *Aliasee, Module *ParentModule,
+ GlobalObject *Aliasee, Module *ParentModule,
unsigned AddressSpace)
: GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal,
&Op<0>(), 1, Link, Name) {
LeakDetector::addGarbageObject(this);
-
- if (Aliasee)
- assert(Aliasee->getType() == getType() &&
- "Alias and aliasee types should match!");
Op<0>() = Aliasee;
if (ParentModule)
@@ -245,42 +241,4 @@ void GlobalAlias::eraseFromParent() {
getParent()->getAliasList().erase(this);
}
-void GlobalAlias::setAliasee(Constant *Aliasee) {
- assert((!Aliasee || Aliasee->getType() == getType()) &&
- "Alias and aliasee types should match!");
-
- setOperand(0, Aliasee);
-}
-
-static GlobalValue *getAliaseeGV(GlobalAlias *GA) {
- Constant *C = GA->getAliasee();
- assert(C && "Must alias something");
-
- if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
- return GV;
-
- ConstantExpr *CE = cast<ConstantExpr>(C);
- assert((CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::AddrSpaceCast ||
- CE->getOpcode() == Instruction::GetElementPtr) &&
- "Unsupported aliasee");
-
- return cast<GlobalValue>(CE->getOperand(0));
-}
-
-GlobalObject *GlobalAlias::getAliasedGlobal() {
- SmallPtrSet<GlobalValue*, 3> Visited;
-
- GlobalAlias *GA = this;
-
- for (;;) {
- GlobalValue *GV = getAliaseeGV(GA);
- if (!Visited.insert(GV))
- return nullptr;
-
- // Iterate over aliasing chain.
- GA = dyn_cast<GlobalAlias>(GV);
- if (!GA)
- return cast<GlobalObject>(GV);
- }
-}
+void GlobalAlias::setAliasee(GlobalObject *Aliasee) { setOperand(0, Aliasee); }
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index 9a79e43359..a3c0286200 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -301,6 +301,28 @@ 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);
+ auto *Old = &cast<GlobalObject>(*U);
+ assert(Old != &Replacement &&
+ "replaceAliasUseWith cannot form an alias cycle");
+ U.set(&Replacement);
+}
+
#ifndef NDEBUG
static bool contains(SmallPtrSet<ConstantExpr *, 4> &Cache, ConstantExpr *Expr,
Constant *C) {
@@ -351,7 +373,11 @@ void Value::replaceAllUsesWith(Value *New) {
Use &U = *UseList;
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
// constant because they are uniqued.
- if (Constant *C = dyn_cast<Constant>(U.getUser())) {
+ 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 ff9ca44f87..6ab5e58c4c 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -473,8 +473,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
"Alias should have external or external weak linkage!", &GA);
Assert1(GA.getAliasee(),
"Aliasee cannot be NULL!", &GA);
- Assert1(GA.getType() == GA.getAliasee()->getType(),
- "Alias and aliasee types should match!", &GA);
Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
const Constant *Aliasee = GA.getAliasee();
@@ -506,10 +504,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
&GA);
}
- const GlobalValue *AG = GA.getAliasedGlobal();
- Assert1(AG, "Aliasing chain should end with function or global variable",
- &GA);
-
visitGlobalValue(GA);
}
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 0507c5acc9..cf49d3fd55 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -389,6 +389,8 @@ 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.
@@ -920,18 +922,15 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
// If there is no linkage to be performed or we're linking from the source,
// bring over SGA.
auto *PTy = cast<PointerType>(TypeMap.get(SGA->getType()));
- GlobalAlias *NewDA =
+ auto *NewDA =
new GlobalAlias(PTy->getElementType(), SGA->getLinkage(), SGA->getName(),
/*aliasee*/ nullptr, DstM, PTy->getAddressSpace());
copyGVAttributes(NewDA, SGA);
if (NewVisibility)
NewDA->setVisibility(*NewVisibility);
- if (DGV) {
- // Any uses of DGV need to change to NewDA, with cast.
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));
- DGV->eraseFromParent();
- }
+ if (DGV)
+ ReplaceWithAlias.push_back(std::make_pair(DGV, NewDA));
ValueMap[SGA] = NewDA;
return false;
@@ -1017,6 +1016,19 @@ 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();
@@ -1025,10 +1037,27 @@ void ModuleLinker::linkAliasBodies() {
continue;
if (Constant *Aliasee = I->getAliasee()) {
GlobalAlias *DA = cast<GlobalAlias>(ValueMap[I]);
- DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None,
- &TypeMap, &ValMaterializer));
+ Constant *Val =
+ MapValue(Aliasee, ValueMap, RF_None, &TypeMap, &ValMaterializer);
+ DA->setAliasee(&getGlobalObjectInExpr(*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/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index a8471bacb4..ae80c43764 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2861,7 +2861,7 @@ bool GlobalOpt::OptimizeGlobalAliases(Module &M) {
if (!hasUsesToReplace(*J, Used, RenameTarget))
continue;
- J->replaceAllUsesWith(Aliasee);
+ J->replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee, J->getType()));
++NumAliasesResolved;
Changed = true;
diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp
index a8106e0c32..83d9a6f749 100644
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -1327,11 +1327,9 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
// Replace G with an alias to F and delete G.
void MergeFunctions::writeAlias(Function *F, Function *G) {
- Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType());
PointerType *PTy = G->getType();
- GlobalAlias *GA =
- new GlobalAlias(PTy->getElementType(), G->getLinkage(), "", BitcastF,
- G->getParent(), PTy->getAddressSpace());
+ auto *GA = new GlobalAlias(PTy->getElementType(), G->getLinkage(), "", F,
+ G->getParent(), PTy->getAddressSpace());
F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
GA->takeName(G);
GA->setVisibility(G->getVisibility());
diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp
index 1a3641452d..d4c4c1907a 100644
--- a/lib/Transforms/Utils/CloneModule.cpp
+++ b/lib/Transforms/Utils/CloneModule.cpp
@@ -107,8 +107,8 @@ 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 Constant *C = I->getAliasee())
- GA->setAliasee(MapValue(C, VMap));
+ if (const GlobalObject *C = I->getAliasee())
+ GA->setAliasee(cast<GlobalObject>(MapValue(C, VMap)));
}
// And named metadata....
diff --git a/test/Assembler/2009-04-25-AliasGEP.ll b/test/Assembler/2009-04-25-AliasGEP.ll
deleted file mode 100644
index 6d07208def..0000000000
--- a/test/Assembler/2009-04-25-AliasGEP.ll
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis
-; PR4066
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin9"
- %struct.i2c_device_id = type { }
-@w83l785ts_id = internal constant [0 x %struct.i2c_device_id] zeroinitializer, align 1 ; <[0 x %struct.i2c_device_id]*> [#uses=1]
-
-@__mod_i2c_device_table = alias getelementptr ([0 x %struct.i2c_device_id]* @w83l785ts_id, i32 0, i32 0) ; <%struct.i2c_device_id*> [#uses=0]
diff --git a/test/Assembler/addrspacecast-alias.ll b/test/Assembler/addrspacecast-alias.ll
index 6623a25d18..052a1414ea 100644
--- a/test/Assembler/addrspacecast-alias.ll
+++ b/test/Assembler/addrspacecast-alias.ll
@@ -1,6 +1,7 @@
-; RUN: llvm-as -disable-output %s
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; Test that global aliases are allowed to be constant addrspacecast
@i = internal addrspace(1) global i8 42
-@ia = alias internal i8 addrspace(2)* addrspacecast (i8 addrspace(1)* @i to i8 addrspace(2)*)
+@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
diff --git a/test/Assembler/alias-addrspace.ll b/test/Assembler/alias-addrspace.ll
new file mode 100644
index 0000000000..6d378e45fa
--- /dev/null
+++ b/test/Assembler/alias-addrspace.ll
@@ -0,0 +1,6 @@
+; 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
new file mode 100644
index 0000000000..1ea99bbb69
--- /dev/null
+++ b/test/Assembler/alias-to-alias.ll
@@ -0,0 +1,5 @@
+; 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
new file mode 100644
index 0000000000..a8a0196f43
--- /dev/null
+++ b/test/Assembler/alias-to-alias2.ll
@@ -0,0 +1,7 @@
+; 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
new file mode 100644
index 0000000000..ead3e95243
--- /dev/null
+++ b/test/Assembler/alias-type.ll
@@ -0,0 +1,6 @@
+; 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
new file mode 100644
index 0000000000..4ef47c03dd
--- /dev/null
+++ b/test/Bitcode/old-aliases.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-dis < %s.bc | FileCheck %s
+
+; old-aliases.bc consist of this file assembled with an old llvm-as (3.5 trunk)
+; from when aliases contained a ConstantExpr.
+
+@v1 = global i32 0
+; CHECK: @v1 = global i32 0
+
+@v2 = global [1 x i32] zeroinitializer
+; CHECK: @v2 = global [1 x i32] zeroinitializer
+
+@v3 = alias bitcast (i32* @v1 to i16*)
+; CHECK: @v3 = alias i16, i32* @v1
+
+@v4 = alias getelementptr ([1 x i32]* @v2, i32 0, i32 0)
+; CHECK: @v4 = alias i32, [1 x i32]* @v2
+
+@v5 = alias i32 addrspace(2)* addrspacecast (i32 addrspace(0)* @v1 to i32 addrspace(2)*)
+; CHECK: @v5 = alias addrspace(2) i32, i32* @v1
+
+@v6 = alias i16* @v3
+; CHECK: @v6 = alias i16, i32* @v1
diff --git a/test/Bitcode/old-aliases.ll.bc b/test/Bitcode/old-aliases.ll.bc
new file mode 100644
index 0000000000..1f157b2a04
--- /dev/null
+++ b/test/Bitcode/old-aliases.ll.bc
Binary files differ
diff --git a/test/CodeGen/ARM/aliases.ll b/test/CodeGen/ARM/aliases.ll
index f55ae10b24..4de305b93b 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 bitcast (i32* @bar to i64*)
+@A = alias i64, i32* @bar
define i32 @test() {
entry:
diff --git a/test/CodeGen/X86/aliases.ll b/test/CodeGen/X86/aliases.ll
index d0a262d390..8487c6082b 100644
--- a/test/CodeGen/X86/aliases.ll
+++ b/test/CodeGen/X86/aliases.ll
@@ -22,7 +22,7 @@ define i32 @foo_f() {
@bar_i = alias internal i32* @bar
; CHECK-DAG: .globl A
-@A = alias bitcast (i32* @bar to i64*)
+@A = alias i64, i32* @bar
; CHECK-DAG: .globl bar_h
; CHECK-DAG: .hidden bar_h
diff --git a/test/CodeGen/X86/dllexport-x86_64.ll b/test/CodeGen/X86/dllexport-x86_64.ll
index af0f85b00e..8bd882efee 100644
--- a/test/CodeGen/X86/dllexport-x86_64.ll
+++ b/test/CodeGen/X86/dllexport-x86_64.ll
@@ -66,7 +66,7 @@ define weak_odr dllexport void @weak1() {
; CHECK: .globl alias3
; CHECK: alias3 = notExported
-@alias3 = dllexport alias void()* @alias
+@alias3 = dllexport alias void()* @notExported
; CHECK: .weak weak_alias
; CHECK: weak_alias = f1
diff --git a/test/CodeGen/X86/dllexport.ll b/test/CodeGen/X86/dllexport.ll
index 6103a41211..b85df83e3e 100644
--- a/test/CodeGen/X86/dllexport.ll
+++ b/test/CodeGen/X86/dllexport.ll
@@ -85,7 +85,7 @@ define weak_odr dllexport void @weak1() {
; CHECK: .globl _alias3
; CHECK: _alias3 = _notExported
-@alias3 = dllexport alias void()* @alias
+@alias3 = dllexport alias void()* @notExported
; CHECK: .weak _weak_alias
; CHECK: _weak_alias = _f1
diff --git a/test/Feature/alias2.ll b/test/Feature/alias2.ll
new file mode 100644
index 0000000000..693ef7c9be
--- /dev/null
+++ b/test/Feature/alias2.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@v1 = global i32 0
+; CHECK: @v1 = global i32 0
+
+@v2 = global [1 x i32] zeroinitializer
+; CHECK: @v2 = global [1 x i32] zeroinitializer
+
+@v3 = alias i16, i32* @v1
+; CHECK: @v3 = alias i16, i32* @v1
+
+@v4 = alias i32, [1 x i32]* @v2
+; CHECK: @v4 = alias i32, [1 x i32]* @v2
+
+@v5 = alias addrspace(2) i32, i32* @v1
+; CHECK: @v5 = alias addrspace(2) i32, i32* @v1
+
+@v6 = alias i16, i32* @v1
+; CHECK: @v6 = alias i16, i32* @v1
diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll
index 7fe9d0b374..b2ce82a838 100644
--- a/test/Feature/aliases.ll
+++ b/test/Feature/aliases.ll
@@ -7,7 +7,6 @@
@bar = global i32 0
@foo1 = alias i32* @bar
@foo2 = alias i32* @bar
-@foo3 = alias i32* @foo2
%FunTy = type i32()
@@ -15,11 +14,10 @@ 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 bitcast (i32* @bar to i64*)
+@A = alias i64, i32* @bar
define i32 @test() {
entry:
diff --git a/test/Linker/Inputs/PR8300.b.ll b/test/Linker/Inputs/PR8300.b.ll
index 9e538f5d28..362d309a19 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 bitcast (void (%bar*)* @xyz to void (%foo*)*)
+@zed = alias void (%foo*), void (%bar*)* @xyz
define void @xyz(%bar* %this) {
entry:
diff --git a/test/Linker/Inputs/alias.ll b/test/Linker/Inputs/alias.ll
new file mode 100644
index 0000000000..b869cae71e
--- /dev/null
+++ b/test/Linker/Inputs/alias.ll
@@ -0,0 +1,3 @@
+@zed = global i32 42
+@foo = alias i32* @zed
+@foo2 = alias i16, i32* @zed
diff --git a/test/Linker/Inputs/cycle.ll b/test/Linker/Inputs/cycle.ll
new file mode 100644
index 0000000000..d0eddb6e7c
--- /dev/null
+++ b/test/Linker/Inputs/cycle.ll
@@ -0,0 +1,2 @@
+@foo = alias i32* @bar
+@bar = weak global i32 0
diff --git a/test/Linker/alias.ll b/test/Linker/alias.ll
new file mode 100644
index 0000000000..5809a15082
--- /dev/null
+++ b/test/Linker/alias.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-link %s %S/Inputs/alias.ll -S -o - | FileCheck %s
+; RUN: llvm-link %S/Inputs/alias.ll %s -S -o - | FileCheck %s
+
+@foo = weak global i32 0
+; CHECK-DAG: @foo = alias i32* @zed
+
+@bar = alias i32* @foo
+; CHECK-DAG: @bar = alias i32* @zed
+
+@foo2 = weak global i32 0
+; CHECK-DAG: @foo2 = alias i16, i32* @zed
+
+@bar2 = alias i32* @foo2
+; CHECK-DAG: @bar2 = alias i32* @zed
+
+; CHECK-DAG: @zed = global i32 42
diff --git a/test/Linker/cycle.ll b/test/Linker/cycle.ll
new file mode 100644
index 0000000000..7d9ad2d9d6
--- /dev/null
+++ b/test/Linker/cycle.ll
@@ -0,0 +1,7 @@
+; 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/Other/extract-alias.ll b/test/Other/extract-alias.ll
index d1e4af5456..dbc650ec69 100644
--- a/test/Other/extract-alias.ll
+++ b/test/Other/extract-alias.ll
@@ -14,7 +14,7 @@
; DELETE: @zed = global i32 0
; DELETE: @zeda0 = alias i32* @zed
; DELETE-NEXT: @a0foo = alias i32* ()* @foo
-; DELETE-NEXT: @a0a0bar = alias void ()* @a0bar
+; DELETE-NEXT: @a0a0bar = alias void ()* @bar
; DELETE-NEXT: @a0bar = alias void ()* @bar
; DELETE: declare i32* @foo()
; DELETE: define void @bar() {
@@ -25,7 +25,7 @@
; ALIAS: @zed = external global i32
; ALIAS: @zeda0 = alias i32* @zed
-; ALIASRE: @a0a0bar = alias void ()* @a0bar
+; ALIASRE: @a0a0bar = alias void ()* @bar
; ALIASRE: @a0bar = alias void ()* @bar
; ALIASRE: declare void @bar()
@@ -39,7 +39,7 @@ define i32* @foo() {
ret i32* @zeda0
}
-@a0a0bar = alias void ()* @a0bar
+@a0a0bar = alias void ()* @bar
@a0bar = alias void ()* @bar
diff --git a/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll b/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
index 0bdced5114..4b967997ce 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* @L1
-; CHECK: @L2 = alias internal i32* @L1
+@L2 = alias internal i32* @A
+; DEAD-NOT: @L2
-@L3 = alias i32* @L2
-; CHECK: @L3 = alias i32* @L2
+@L3 = alias i32* @A
+; CHECK: @L3 = alias i32* @A
diff --git a/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll b/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
index d6a565ad10..03d6ee4f8a 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 bitcast (i32* @g to i8*)
+@a = alias i8, i32* @g
define void @f() {
%tmp = load i8* @a
diff --git a/test/Transforms/GlobalOpt/alias-resolve.ll b/test/Transforms/GlobalOpt/alias-resolve.ll
index 2d5a956d14..bd07b31b23 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 ()* @foo2
+@foo1 = alias void ()* @bar2
; CHECK: @foo1 = alias void ()* @bar2
-@foo2 = alias void()* @bar1
+@foo2 = alias void()* @bar2
; 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 a6b56f94ff..284960b113 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 bitcast (i32 (i32)* @func_i32 to float (float)*)
+@alias_i32_to_f32 = alias float (float), i32 (i32)* @func_i32
; Test cast between vectors with same number of elements and bit sizes
-@alias_v2i32_to_v2f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*)
+@alias_v2i32_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i32> (<2 x i32>)* @func_v2i32
; Test cast from vector to scalar with same number of bits
-@alias_v2f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*)
+@alias_v2f32_to_i64 = alias <2 x float> (<2 x float>), i64 (i64)* @func_i64
; Test cast from scalar to vector with same number of bits
-@alias_i64_to_v2f32 = alias bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*)
+@alias_i64_to_v2f32 = alias i64 (i64), <2 x float> (<2 x float>)* @func_v2f32
; Test cast between vectors of pointers
-@alias_v2i32p_to_v2i64p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*)
+@alias_v2i32p_to_v2i64p = alias <2 x i64*> (<2 x i64*>), <2 x i32*> (<2 x i32*>)* @func_v2i32p
; Cases that should be invalid and unchanged
; Test cast between scalars with different bit sizes
-@alias_i64_to_f32 = alias bitcast (i64 (i64)* @func_i64 to float (float)*)
+@alias_i64_to_f32 = alias float (float), i64 (i64)* @func_i64
; Test cast between vectors with different bit sizes but the
; same number of elements
-@alias_v2i64_to_v2f32 = alias bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)
+@alias_v2i64_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i64> (<2 x i64>)* @func_v2i64
; Test cast between vectors with same number of bits and different
; numbers of elements
-@alias_v2i32_to_v4f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)
+@alias_v2i32_to_v4f32 = alias <4 x float> (<4 x float>), <2 x i32> (<2 x i32>)* @func_v2i32
; Test cast between scalar and vector with different number of bits
-@alias_i64_to_v4f32 = alias bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)
+@alias_i64_to_v4f32 = alias i64 (i64), <4 x float> (<4 x float>)* @func_v4f32
; Test cast between vector and scalar with different number of bits
-@alias_v4f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)
+@alias_v4f32_to_i64 = alias <4 x float> (<4 x float>), i64 (i64)* @func_i64
; 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 bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)
+@alias_i64_to_v2i32p = alias i64 (i64), <2 x i32*> (<2 x i32*>)* @func_v2i32p
; Test cast between vector of pointers and scalar with different number of bits
-@alias_v4i32p_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)
+@alias_v4i32p_to_i64 = alias <4 x i32*> (<4 x i32*>), i64 (i64)* @func_i64
diff --git a/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll b/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll
index c71dbb1fd8..16bfe2a460 100644
--- a/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll
+++ b/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll
@@ -6,8 +6,8 @@
@B = alias i32* @A
; CHECK: @B = alias internal i32* @A
-@C = alias i32* @B
-; CHECK: @C = alias internal i32* @B
+@C = alias i32* @A
+; CHECK: @C = alias internal i32* @A
define i32 @main() {
%tmp = load i32* @C
diff --git a/test/Verifier/aliasing-chain.ll b/test/Verifier/aliasing-chain.ll
deleted file mode 100644
index ae0b77fdc3..0000000000
--- a/test/Verifier/aliasing-chain.ll
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
-; CHECK: Aliasing chain should end with function or global variable
-; Test that alising chain does not create a cycle
-
-@b1 = alias i32* @c1
-@c1 = alias i32* @b1
diff --git a/test/Verifier/bitcast-alias-address-space.ll b/test/Verifier/bitcast-alias-address-space.ll
deleted file mode 100644
index d9794d9e33..0000000000
--- a/test/Verifier/bitcast-alias-address-space.ll
+++ /dev/null
@@ -1,10 +0,0 @@
-; 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/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index 59c9652e2e..b225ba923b 100644
--- a/unittests/IR/ConstantsTest.cpp
+++ b/unittests/IR/ConstantsTest.cpp
@@ -268,6 +268,18 @@ TEST(ConstantsTest, ReplaceWithConstantTest) {
EXPECT_DEATH(Global->replaceAllUsesWith(GEP),
"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 = new GlobalAlias(Int32Ty, GlobalValue::ExternalLinkage, "alias",
+ Global, M.get());
+ EXPECT_DEATH(Global->replaceAllUsesWith(GA),
+ "replaceAliasUseWith cannot form an alias cycle");
+}
+
#endif
#endif
diff --git a/unittests/Transforms/Utils/SpecialCaseList.cpp b/unittests/Transforms/Utils/SpecialCaseList.cpp
index 6863ea5a60..ea8fb3962b 100644
--- a/unittests/Transforms/Utils/SpecialCaseList.cpp
+++ b/unittests/Transforms/Utils/SpecialCaseList.cpp
@@ -34,7 +34,7 @@ protected:
M, ST, false, GlobalValue::ExternalLinkage, 0, Name);
}
- GlobalAlias *makeAlias(StringRef Name, GlobalValue *Aliasee) {
+ GlobalAlias *makeAlias(StringRef Name, GlobalObject *Aliasee) {
return new GlobalAlias(Aliasee->getType()->getElementType(),
GlobalValue::ExternalLinkage, Name, Aliasee,
Aliasee->getParent());