forked from OSchip/llvm-project
Allow aliases to be unnamed_addr.
Alias with unnamed_addr were in a strange state. It is stored in GlobalValue, the language reference talks about "unnamed_addr aliases" but the verifier was rejecting them. It seems natural to allow unnamed_addr in aliases: * It is a property of how it is accessed, not of the data itself. * It is perfectly possible to write code that depends on the address of an alias. This patch then makes unname_addr legal for aliases. One side effect is that the syntax changes for a corner case: In globals, unnamed_addr is now printed before the address space. llvm-svn: 210302
This commit is contained in:
parent
f251e0051c
commit
42a4c9f9e0
|
@ -698,7 +698,8 @@ The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
|
|||
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 expression. ``unnamed_addr`` ones are only guaranteed to point
|
||||
to the same content.
|
||||
|
||||
Since aliases are only a second name, some restrictions apply, of which
|
||||
some can only be checked when producing an object file:
|
||||
|
|
|
@ -268,14 +268,16 @@ bool LLParser::ParseTopLevelEntities() {
|
|||
case lltok::kw_constant: // GlobalType
|
||||
case lltok::kw_global: { // GlobalType
|
||||
unsigned Linkage, Visibility, DLLStorageClass;
|
||||
bool UnnamedAddr;
|
||||
GlobalVariable::ThreadLocalMode TLM;
|
||||
bool HasLinkage;
|
||||
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
|
||||
ParseOptionalVisibility(Visibility) ||
|
||||
ParseOptionalDLLStorageClass(DLLStorageClass) ||
|
||||
ParseOptionalThreadLocal(TLM) ||
|
||||
parseOptionalUnnamedAddr(UnnamedAddr) ||
|
||||
ParseGlobal("", SMLoc(), Linkage, HasLinkage, Visibility,
|
||||
DLLStorageClass, TLM))
|
||||
DLLStorageClass, TLM, UnnamedAddr))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
@ -467,16 +469,19 @@ bool LLParser::ParseUnnamedGlobal() {
|
|||
bool HasLinkage;
|
||||
unsigned Linkage, Visibility, DLLStorageClass;
|
||||
GlobalVariable::ThreadLocalMode TLM;
|
||||
bool UnnamedAddr;
|
||||
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
|
||||
ParseOptionalVisibility(Visibility) ||
|
||||
ParseOptionalDLLStorageClass(DLLStorageClass) ||
|
||||
ParseOptionalThreadLocal(TLM))
|
||||
ParseOptionalThreadLocal(TLM) ||
|
||||
parseOptionalUnnamedAddr(UnnamedAddr))
|
||||
return true;
|
||||
|
||||
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
|
||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||
DLLStorageClass, TLM);
|
||||
return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM);
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
|
||||
UnnamedAddr);
|
||||
}
|
||||
|
||||
/// ParseNamedGlobal:
|
||||
|
@ -492,17 +497,20 @@ bool LLParser::ParseNamedGlobal() {
|
|||
bool HasLinkage;
|
||||
unsigned Linkage, Visibility, DLLStorageClass;
|
||||
GlobalVariable::ThreadLocalMode TLM;
|
||||
bool UnnamedAddr;
|
||||
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
|
||||
ParseOptionalLinkage(Linkage, HasLinkage) ||
|
||||
ParseOptionalVisibility(Visibility) ||
|
||||
ParseOptionalDLLStorageClass(DLLStorageClass) ||
|
||||
ParseOptionalThreadLocal(TLM))
|
||||
ParseOptionalThreadLocal(TLM) ||
|
||||
parseOptionalUnnamedAddr(UnnamedAddr))
|
||||
return true;
|
||||
|
||||
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
|
||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||
DLLStorageClass, TLM);
|
||||
return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM);
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
|
||||
UnnamedAddr);
|
||||
}
|
||||
|
||||
// MDString:
|
||||
|
@ -629,16 +637,18 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
|
|||
|
||||
/// ParseAlias:
|
||||
/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass
|
||||
/// OptionalThreadLocal 'alias' OptionalLinkage Aliasee
|
||||
/// OptionalThreadLocal OptionalUnNammedAddr 'alias'
|
||||
/// OptionalLinkage Aliasee
|
||||
///
|
||||
/// Aliasee
|
||||
/// ::= TypeAndValue
|
||||
///
|
||||
/// Everything through OptionalThreadLocal has already been parsed.
|
||||
/// Everything through OptionalUnNammedAddr has already been parsed.
|
||||
///
|
||||
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
|
||||
unsigned Visibility, unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM) {
|
||||
GlobalVariable::ThreadLocalMode TLM,
|
||||
bool UnnamedAddr) {
|
||||
assert(Lex.getKind() == lltok::kw_alias);
|
||||
Lex.Lex();
|
||||
LocTy LinkageLoc = Lex.getLoc();
|
||||
|
@ -687,6 +697,7 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
|
|||
GA->setThreadLocalMode(TLM);
|
||||
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
||||
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
|
||||
GA->setUnnamedAddr(UnnamedAddr);
|
||||
|
||||
// See if this value already exists in the symbol table. If so, it is either
|
||||
// a redefinition or a definition of a forward reference.
|
||||
|
@ -723,33 +734,31 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
|
|||
|
||||
/// ParseGlobal
|
||||
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
|
||||
/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
|
||||
/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
|
||||
/// OptionalExternallyInitialized GlobalType Type Const
|
||||
/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
|
||||
/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
|
||||
/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
|
||||
/// OptionalExternallyInitialized GlobalType Type Const
|
||||
///
|
||||
/// Everything up to and including OptionalThreadLocal has been parsed
|
||||
/// Everything up to and including OptionalUnNammedAddr has been parsed
|
||||
/// already.
|
||||
///
|
||||
bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
|
||||
unsigned Linkage, bool HasLinkage,
|
||||
unsigned Visibility, unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM) {
|
||||
GlobalVariable::ThreadLocalMode TLM,
|
||||
bool UnnamedAddr) {
|
||||
if (!isValidVisibilityForLinkage(Visibility, Linkage))
|
||||
return Error(NameLoc,
|
||||
"symbol with local linkage must have default visibility");
|
||||
|
||||
unsigned AddrSpace;
|
||||
bool IsConstant, UnnamedAddr, IsExternallyInitialized;
|
||||
LocTy UnnamedAddrLoc;
|
||||
bool IsConstant, IsExternallyInitialized;
|
||||
LocTy IsExternallyInitializedLoc;
|
||||
LocTy TyLoc;
|
||||
|
||||
Type *Ty = nullptr;
|
||||
if (ParseOptionalAddrSpace(AddrSpace) ||
|
||||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
|
||||
&UnnamedAddrLoc) ||
|
||||
ParseOptionalToken(lltok::kw_externally_initialized,
|
||||
IsExternallyInitialized,
|
||||
&IsExternallyInitializedLoc) ||
|
||||
|
|
|
@ -197,6 +197,9 @@ namespace llvm {
|
|||
|
||||
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
|
||||
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
|
||||
bool parseOptionalUnnamedAddr(bool &UnnamedAddr) {
|
||||
return ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr);
|
||||
}
|
||||
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
|
||||
bool ParseOptionalParamAttrs(AttrBuilder &B);
|
||||
bool ParseOptionalReturnAttrs(AttrBuilder &B);
|
||||
|
@ -240,10 +243,10 @@ namespace llvm {
|
|||
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||
bool HasLinkage, unsigned Visibility,
|
||||
unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM);
|
||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility,
|
||||
unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM);
|
||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
||||
bool ParseStandaloneMetadata();
|
||||
bool ParseNamedMetadata();
|
||||
bool ParseMDString(MDString *&Result);
|
||||
|
|
|
@ -1988,6 +1988,8 @@ error_code BitcodeReader::ParseModule(bool Resume) {
|
|||
UpgradeDLLImportExportLinkage(NewGA, Record[2]);
|
||||
if (Record.size() > 5)
|
||||
NewGA->setThreadLocalMode(GetDecodedThreadLocalMode(Record[5]));
|
||||
if (Record.size() > 6)
|
||||
NewGA->setUnnamedAddr(Record[6]);
|
||||
ValueList.push_back(NewGA);
|
||||
AliasInits.push_back(std::make_pair(NewGA, Record[1]));
|
||||
break;
|
||||
|
|
|
@ -670,8 +670,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
|
|||
Vals.push_back(getEncodedLinkage(A));
|
||||
Vals.push_back(getEncodedVisibility(A));
|
||||
Vals.push_back(getEncodedDLLStorageClass(A));
|
||||
if (A.isThreadLocal())
|
||||
Vals.push_back(getEncodedThreadLocalMode(A));
|
||||
Vals.push_back(getEncodedThreadLocalMode(A));
|
||||
Vals.push_back(A.hasUnnamedAddr());
|
||||
unsigned AbbrevToUse = 0;
|
||||
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
|
||||
Vals.clear();
|
||||
|
|
|
@ -1451,10 +1451,11 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
|||
PrintVisibility(GV->getVisibility(), Out);
|
||||
PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
|
||||
PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
|
||||
if (GV->hasUnnamedAddr())
|
||||
Out << "unnamed_addr ";
|
||||
|
||||
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
|
||||
Out << "addrspace(" << AddressSpace << ") ";
|
||||
if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
|
||||
if (GV->isExternallyInitialized()) Out << "externally_initialized ";
|
||||
Out << (GV->isConstant() ? "constant " : "global ");
|
||||
TypePrinter.print(GV->getType()->getElementType(), Out);
|
||||
|
@ -1489,6 +1490,8 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
|||
PrintVisibility(GA->getVisibility(), Out);
|
||||
PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
|
||||
PrintThreadLocalModel(GA->getThreadLocalMode(), Out);
|
||||
if (GA->hasUnnamedAddr())
|
||||
Out << "unnamed_addr ";
|
||||
|
||||
Out << "alias ";
|
||||
|
||||
|
|
|
@ -517,7 +517,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
|
|||
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(isa<GlobalValue>(Aliasee) || isa<ConstantExpr>(Aliasee),
|
||||
"Aliasee should be either GlobalValue or ConstantExpr", &GA);
|
||||
|
|
|
@ -893,6 +893,7 @@ bool ModuleLinker::linkFunctionProto(Function *SF) {
|
|||
bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
|
||||
GlobalValue *DGV = getLinkedToGlobal(SGA);
|
||||
llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;
|
||||
bool HasUnnamedAddr = SGA->hasUnnamedAddr();
|
||||
|
||||
if (DGV) {
|
||||
GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
|
||||
|
@ -901,11 +902,13 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
|
|||
if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc))
|
||||
return true;
|
||||
NewVisibility = NV;
|
||||
HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();
|
||||
|
||||
if (!LinkFromSrc) {
|
||||
// Set calculated linkage.
|
||||
DGV->setLinkage(NewLinkage);
|
||||
DGV->setVisibility(*NewVisibility);
|
||||
DGV->setUnnamedAddr(HasUnnamedAddr);
|
||||
|
||||
// Make sure to remember this mapping.
|
||||
ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType()));
|
||||
|
@ -926,6 +929,7 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
|
|||
copyGVAttributes(NewDA, SGA);
|
||||
if (NewVisibility)
|
||||
NewDA->setVisibility(*NewVisibility);
|
||||
NewDA->setUnnamedAddr(HasUnnamedAddr);
|
||||
|
||||
if (DGV) {
|
||||
// Any uses of DGV need to change to NewDA, with cast.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: opt < %s -S -nvvm-reflect -nvvm-reflect-list USE_MUL=0 -O2 | FileCheck %s --check-prefix=USE_MUL_0
|
||||
; RUN: opt < %s -S -nvvm-reflect -nvvm-reflect-list USE_MUL=1 -O2 | FileCheck %s --check-prefix=USE_MUL_1
|
||||
|
||||
@str = private addrspace(4) unnamed_addr constant [8 x i8] c"USE_MUL\00"
|
||||
@str = private unnamed_addr addrspace(4) constant [8 x i8] c"USE_MUL\00"
|
||||
|
||||
declare i32 @__nvvm_reflect(i8*)
|
||||
declare i8* @llvm.nvvm.ptr.constant.to.gen.p0i8.p4i8(i8 addrspace(4)*)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
; XXX: Test on SI once 64-bit adds are supportes.
|
||||
|
||||
@float_gv = internal addrspace(2) unnamed_addr constant [5 x float] [float 0.0, float 1.0, float 2.0, float 3.0, float 4.0], align 4
|
||||
@float_gv = internal unnamed_addr addrspace(2) constant [5 x float] [float 0.0, float 1.0, float 2.0, float 3.0, float 4.0], align 4
|
||||
|
||||
; FUNC-LABEL: @float
|
||||
|
||||
|
@ -25,7 +25,7 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
@i32_gv = internal addrspace(2) unnamed_addr constant [5 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4], align 4
|
||||
@i32_gv = internal unnamed_addr addrspace(2) constant [5 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4], align 4
|
||||
|
||||
; FUNC-LABEL: @i32
|
||||
|
||||
|
@ -47,7 +47,7 @@ entry:
|
|||
|
||||
%struct.foo = type { float, [5 x i32] }
|
||||
|
||||
@struct_foo_gv = internal addrspace(2) unnamed_addr constant [1 x %struct.foo] [ %struct.foo { float 16.0, [5 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4] } ]
|
||||
@struct_foo_gv = internal unnamed_addr addrspace(2) constant [1 x %struct.foo] [ %struct.foo { float 16.0, [5 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4] } ]
|
||||
|
||||
; FUNC-LABEL: @struct_foo_gv_load
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
; CHECK-NOT: ALU clause
|
||||
; CHECK: MOV * T{{[0-9]\.[XYZW]}}, OQAP
|
||||
|
||||
@local_mem = internal addrspace(3) unnamed_addr global [2 x i32] [i32 1, i32 2], align 4
|
||||
@local_mem = internal unnamed_addr addrspace(3) global [2 x i32] [i32 1, i32 2], align 4
|
||||
|
||||
define void @lds_input_queue(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %index) {
|
||||
entry:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
; CHECK-LABEL: @test
|
||||
; CHECK: .long 166120
|
||||
; CHECK-NEXT: .long 1
|
||||
@lds = internal addrspace(3) unnamed_addr global i32 zeroinitializer, align 4
|
||||
@lds = internal unnamed_addr addrspace(3) global i32 zeroinitializer, align 4
|
||||
|
||||
define void @test(i32 addrspace(1)* %out, i32 %cond) {
|
||||
entry:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=EG-CHECK %s
|
||||
; RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI-CHECK %s
|
||||
|
||||
@local_memory_two_objects.local_mem0 = internal addrspace(3) unnamed_addr global [4 x i32] zeroinitializer, align 4
|
||||
@local_memory_two_objects.local_mem1 = internal addrspace(3) unnamed_addr global [4 x i32] zeroinitializer, align 4
|
||||
@local_memory_two_objects.local_mem0 = internal unnamed_addr addrspace(3) global [4 x i32] zeroinitializer, align 4
|
||||
@local_memory_two_objects.local_mem1 = internal unnamed_addr addrspace(3) global [4 x i32] zeroinitializer, align 4
|
||||
|
||||
; EG-CHECK: @local_memory_two_objects
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
; RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI-CHECK %s
|
||||
; RUN: llc < %s -march=r600 -mcpu=bonaire -verify-machineinstrs | FileCheck --check-prefix=CI-CHECK %s
|
||||
|
||||
@local_memory.local_mem = internal addrspace(3) unnamed_addr global [128 x i32] zeroinitializer, align 4
|
||||
@local_memory.local_mem = internal unnamed_addr addrspace(3) global [128 x i32] zeroinitializer, align 4
|
||||
|
||||
; EG-CHECK-LABEL: @local_memory
|
||||
; SI-CHECK-LABEL: @local_memory
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
@foo1 = alias i32* @bar
|
||||
@foo2 = alias i32* @bar
|
||||
@foo3 = alias i32* @foo2
|
||||
@foo4 = unnamed_addr alias i32* @foo2
|
||||
|
||||
%FunTy = type i32()
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ fn.exit:
|
|||
}
|
||||
|
||||
|
||||
@global_as1 = private addrspace(1) unnamed_addr constant [10 x i8] c"ola\00mundo\00", align 1
|
||||
@global_as1 = private unnamed_addr addrspace(1) constant [10 x i8] c"ola\00mundo\00", align 1
|
||||
|
||||
define void @f1_as1(i8 addrspace(1)* nocapture %c) {
|
||||
; CHECK: @f1_as1
|
||||
|
|
|
@ -21,6 +21,11 @@ define weak void @func-b() unnamed_addr { ret void }
|
|||
@global-f = weak global i32 42
|
||||
; CHECK-DAG: @global-f = global i32 42
|
||||
|
||||
@alias-a = weak global i32 42
|
||||
; CHECK-DAG: @alias-a = alias i32* @global-f
|
||||
@alias-b = weak unnamed_addr global i32 42
|
||||
; CHECK-DAG: @alias-b = unnamed_addr alias i32* @global-f
|
||||
|
||||
declare void @func-c()
|
||||
; CHECK-DAG: define weak void @func-c() {
|
||||
define weak void @func-d() { ret void }
|
||||
|
@ -38,6 +43,12 @@ define weak void @func-e() unnamed_addr { ret void }
|
|||
@global-j = weak global i32 42
|
||||
; CHECK-DAG: @global-j = global i32 42
|
||||
|
||||
@alias-c = weak global i32 42
|
||||
; CHECK-DAG: @alias-c = alias i32* @global-f
|
||||
@alias-d = weak unnamed_addr global i32 42
|
||||
; CHECK-DAG: @alias-d = alias i32* @global-f
|
||||
|
||||
|
||||
declare void @func-g()
|
||||
; CHECK-DAG: define weak void @func-g() {
|
||||
define weak void @func-h() { ret void }
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
@global-e = unnamed_addr global i32 42
|
||||
@global-f = unnamed_addr global i32 42
|
||||
|
||||
@alias-a = unnamed_addr alias i32* @global-f
|
||||
@alias-b = unnamed_addr alias i32* @global-f
|
||||
|
||||
define weak void @func-c() unnamed_addr { ret void }
|
||||
define weak void @func-d() unnamed_addr { ret void }
|
||||
define weak void @func-e() unnamed_addr { ret void }
|
||||
|
@ -15,6 +18,9 @@ define weak void @func-e() unnamed_addr { ret void }
|
|||
@global-i = global i32 42
|
||||
@global-j = global i32 42
|
||||
|
||||
@alias-c = alias i32* @global-f
|
||||
@alias-d = alias i32* @global-f
|
||||
|
||||
define weak void @func-g() { ret void }
|
||||
define weak void @func-h() { ret void }
|
||||
define weak void @func-i() { ret void }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; CHECK: addrspacecast
|
||||
|
||||
@base = internal addrspace(3) unnamed_addr global [16 x i32] zeroinitializer, align 16
|
||||
@base = internal unnamed_addr addrspace(3) global [16 x i32] zeroinitializer, align 16
|
||||
declare void @foo(i32*)
|
||||
|
||||
define void @test() nounwind {
|
||||
|
|
|
@ -44,23 +44,6 @@ TEST(VerifierTest, Branch_i1) {
|
|||
EXPECT_TRUE(verifyFunction(*F));
|
||||
}
|
||||
|
||||
TEST(VerifierTest, AliasUnnamedAddr) {
|
||||
LLVMContext &C = getGlobalContext();
|
||||
Module M("M", C);
|
||||
Type *Ty = Type::getInt8Ty(C);
|
||||
Constant *Init = Constant::getNullValue(Ty);
|
||||
GlobalVariable *Aliasee = new GlobalVariable(M, Ty, true,
|
||||
GlobalValue::ExternalLinkage,
|
||||
Init, "foo");
|
||||
auto *GA = GlobalAlias::create(GlobalValue::ExternalLinkage, "bar", Aliasee);
|
||||
GA->setUnnamedAddr(true);
|
||||
std::string Error;
|
||||
raw_string_ostream ErrorOS(Error);
|
||||
EXPECT_TRUE(verifyModule(M, &ErrorOS));
|
||||
EXPECT_TRUE(
|
||||
StringRef(ErrorOS.str()).startswith("Alias cannot have unnamed_addr"));
|
||||
}
|
||||
|
||||
TEST(VerifierTest, InvalidRetAttribute) {
|
||||
LLVMContext &C = getGlobalContext();
|
||||
Module M("M", C);
|
||||
|
|
Loading…
Reference in New Issue