45 changes: 33 additions & 12 deletions llvm/lib/IR/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
}

Expand All @@ -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();
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}
25 changes: 0 additions & 25 deletions llvm/lib/IR/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
63 changes: 41 additions & 22 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
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);
Expand Down Expand Up @@ -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);
}
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/LTO/LTOModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
42 changes: 7 additions & 35 deletions llvm/lib/Linker/LinkModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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!");

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
22 changes: 10 additions & 12 deletions llvm/lib/Target/XCore/XCoreISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/CloneModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Assembler/addrspacecast-alias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)*)
6 changes: 0 additions & 6 deletions llvm/test/Assembler/alias-addrspace.ll

This file was deleted.

5 changes: 0 additions & 5 deletions llvm/test/Assembler/alias-to-alias.ll

This file was deleted.

7 changes: 0 additions & 7 deletions llvm/test/Assembler/alias-to-alias2.ll

This file was deleted.

6 changes: 0 additions & 6 deletions llvm/test/Assembler/alias-type.ll

This file was deleted.

8 changes: 4 additions & 4 deletions llvm/test/Bitcode/old-aliases.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/ARM/aliases.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
15 changes: 14 additions & 1 deletion llvm/test/CodeGen/X86/aliases.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/dllexport-x86_64.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
22 changes: 14 additions & 8 deletions llvm/test/Feature/alias2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
4 changes: 3 additions & 1 deletion llvm/test/Feature/aliases.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@
@bar = global i32 0
@foo1 = alias i32* @bar
@foo2 = alias i32* @bar
@foo3 = alias i32* @foo2

%FunTy = type i32()

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:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Linker/Inputs/PR8300.b.ll
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Linker/Inputs/alias.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@zed = global i32 42
@foo = alias i32* @zed
@foo2 = alias i16, i32* @zed
@foo2 = alias bitcast (i32* @zed to i16*)
2 changes: 0 additions & 2 deletions llvm/test/Linker/Inputs/cycle.ll

This file was deleted.

6 changes: 3 additions & 3 deletions llvm/test/Linker/alias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 0 additions & 7 deletions llvm/test/Linker/cycle.ll

This file was deleted.

8 changes: 4 additions & 4 deletions llvm/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GlobalOpt/alias-resolve.ll
Original file line number Diff line number Diff line change
@@ -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
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/Transforms/InstCombine/bitcast-alias-function.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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*>)*)



Expand Down
15 changes: 15 additions & 0 deletions llvm/test/Verifier/alias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 10 additions & 0 deletions llvm/test/Verifier/bitcast-alias-address-space.ll
Original file line number Diff line number Diff line change
@@ -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)*)
8 changes: 2 additions & 6 deletions llvm/tools/llvm-nm/llvm-nm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
10 changes: 0 additions & 10 deletions llvm/unittests/IR/ConstantsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down