21 changes: 16 additions & 5 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,15 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
llvm_unreachable("Invalid selection kind");
}

static unsigned getEncodedUnnamedAddr(const GlobalValue &GV) {
switch (GV.getUnnamedAddr()) {
case GlobalValue::UnnamedAddr::None: return 0;
case GlobalValue::UnnamedAddr::Local: return 2;
case GlobalValue::UnnamedAddr::Global: return 1;
}
llvm_unreachable("Invalid unnamed_addr");
}

void ModuleBitcodeWriter::writeComdats() {
SmallVector<unsigned, 64> Vals;
for (const Comdat *C : VE.getComdats()) {
Expand Down Expand Up @@ -1157,12 +1166,13 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
if (GV.isThreadLocal() ||
GV.getVisibility() != GlobalValue::DefaultVisibility ||
GV.hasUnnamedAddr() || GV.isExternallyInitialized() ||
GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None ||
GV.isExternallyInitialized() ||
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
GV.hasComdat()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
Vals.push_back(GV.hasUnnamedAddr());
Vals.push_back(getEncodedUnnamedAddr(GV));
Vals.push_back(GV.isExternallyInitialized());
Vals.push_back(getEncodedDLLStorageClass(GV));
Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0);
Expand All @@ -1188,7 +1198,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
Vals.push_back(getEncodedVisibility(F));
Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
Vals.push_back(F.hasUnnamedAddr());
Vals.push_back(getEncodedUnnamedAddr(F));
Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
: 0);
Vals.push_back(getEncodedDLLStorageClass(F));
Expand All @@ -1205,15 +1215,16 @@ void ModuleBitcodeWriter::writeModuleInfo() {

// Emit the alias information.
for (const GlobalAlias &A : M.aliases()) {
// ALIAS: [alias type, aliasee val#, linkage, visibility]
// ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass,
// threadlocal, unnamed_addr]
Vals.push_back(VE.getTypeID(A.getValueType()));
Vals.push_back(A.getType()->getAddressSpace());
Vals.push_back(VE.getValueID(A.getAliasee()));
Vals.push_back(getEncodedLinkage(A));
Vals.push_back(getEncodedVisibility(A));
Vals.push_back(getEncodedDLLStorageClass(A));
Vals.push_back(getEncodedThreadLocalMode(A));
Vals.push_back(A.hasUnnamedAddr());
Vals.push_back(getEncodedUnnamedAddr(A));
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();
Expand Down
20 changes: 4 additions & 16 deletions llvm/lib/CodeGen/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,9 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
if (!GV->hasLinkOnceODRLinkage())
return false;

if (GV->hasUnnamedAddr())
// We assume that anyone who sets global unnamed_addr on a non-constant knows
// what they're doing.
if (GV->hasGlobalUnnamedAddr())
return true;

// If it is a non constant variable, it needs to be uniqued across shared
Expand All @@ -633,21 +635,7 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
return false;
}

// An alias can point to a variable. We could try to resolve the alias to
// decide, but for now just don't hide them.
if (isa<GlobalAlias>(GV))
return false;

// If we don't see every use, we have to be conservative and assume the value
// address is significant.
if (GV->getParent()->getMaterializer())
return false;

GlobalStatus GS;
if (GlobalStatus::analyzeGlobal(GV, GS))
return false;

return !GS.IsCompared;
return GV->hasAtLeastLocalUnnamedAddr();
}

// FIXME: make this a proper option
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
// Global GOT equivalents are unnamed private globals with a constant
// pointer initializer to another global symbol. They must point to a
// GlobalVariable or Function, i.e., as GlobalValue.
if (!GV->hasUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
!GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0)))
return false;

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
const TargetMachine &TM) const {
// We may only use a PLT-relative relocation to refer to unnamed_addr
// functions.
if (!LHS->hasUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
return nullptr;

// Basic sanity checks.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
V.setLinkage(GlobalValue::ExternalLinkage);
V.setVisibility(GlobalValue::HiddenVisibility);
}
V.setUnnamedAddr(false);
V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
assert(!R.needsRenaming(V) && "Invalid global name.");
}

Expand Down
26 changes: 20 additions & 6 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2426,6 +2426,17 @@ static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
}
}

static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
switch (UA) {
case GlobalVariable::UnnamedAddr::None:
return "";
case GlobalVariable::UnnamedAddr::Local:
return "local_unnamed_addr";
case GlobalVariable::UnnamedAddr::Global:
return "unnamed_addr";
}
}

static void maybePrintComdat(formatted_raw_ostream &Out,
const GlobalObject &GO) {
const Comdat *C = GO.getComdat();
Expand Down Expand Up @@ -2458,8 +2469,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
PrintVisibility(GV->getVisibility(), Out);
PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
if (GV->hasUnnamedAddr())
Out << "unnamed_addr ";
StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
if (!UA.empty())
Out << UA << ' ';

if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
Expand Down Expand Up @@ -2499,8 +2511,9 @@ void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
PrintVisibility(GIS->getVisibility(), Out);
PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
if (GIS->hasUnnamedAddr())
Out << "unnamed_addr ";
StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
if (!UA.empty())
Out << UA << ' ';

if (isa<GlobalAlias>(GIS))
Out << "alias ";
Expand Down Expand Up @@ -2656,8 +2669,9 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << "..."; // Output varargs portion of signature!
}
Out << ')';
if (F->hasUnnamedAddr())
Out << " unnamed_addr";
StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
if (!UA.empty())
Out << ' ' << UA;
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
if (F->hasSection()) {
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1560,11 +1560,13 @@ void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) {
}

LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) {
return unwrap<GlobalValue>(Global)->hasUnnamedAddr();
return unwrap<GlobalValue>(Global)->hasGlobalUnnamedAddr();
}

void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) {
unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr);
unwrap<GlobalValue>(Global)->setUnnamedAddr(
HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global
: GlobalValue::UnnamedAddr::None);
}

/*--.. Operations on global variables, load and store instructions .........--*/
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) {
/// create a GlobalValue) from the GlobalValue Src to this one.
void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
setVisibility(Src->getVisibility());
setUnnamedAddr(Src->hasUnnamedAddr());
setUnnamedAddr(Src->getUnnamedAddr());
setDLLStorageClass(Src->getDLLStorageClass());
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
StrConstant, Name, nullptr,
GlobalVariable::NotThreadLocal,
AddressSpace);
GV->setUnnamedAddr(true);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
return GV;
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
if (Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::JumpTable)) {
const GlobalValue *GV = cast<GlobalValue>(V);
Assert(GV->hasUnnamedAddr(),
Assert(GV->hasGlobalUnnamedAddr(),
"Attribute 'jumptable' requires 'unnamed_addr'", V);
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Linker/IRMover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
return stringErr(
"Appending variables with different visibility need to be linked!");

if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
return stringErr(
"Appending variables with different unnamed_addr need to be linked!");

Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Linker/LinkModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
DGV->setVisibility(Visibility);
GV.setVisibility(Visibility);

bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
DGV->setUnnamedAddr(HasUnnamedAddr);
GV.setUnnamedAddr(HasUnnamedAddr);
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(
DGV->getUnnamedAddr(), GV.getUnnamedAddr());
DGV->setUnnamedAddr(UnnamedAddr);
GV.setUnnamedAddr(UnnamedAddr);
}

// Don't want to append to global_ctors list, for example, when we
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) {
nullptr,
GlobalVariable::NotThreadLocal,
AMDGPUAS::LOCAL_ADDRESS);
GV->setUnnamedAddr(true);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
GV->setAlignment(I.getAlignment());

Value *TCntY, *TCntZ;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/TargetLoweringObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
// If the global is required to have a unique address, it can't be put
// into a mergable section: just drop it into the general read-only
// section instead.
if (!GVar->hasUnnamedAddr())
if (!GVar->hasGlobalUnnamedAddr())
return SectionKind::getReadOnly();

// If initializer is a null-terminated string, put it in a "cstring"
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Transforms/IPO/ConstantMerge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static bool IsBetterCanonical(const GlobalVariable &A,
if (A.hasLocalLinkage() && !B.hasLocalLinkage())
return false;

return A.hasUnnamedAddr();
return A.hasGlobalUnnamedAddr();
}

static unsigned getAlignment(GlobalVariable *GV) {
Expand Down Expand Up @@ -152,11 +152,11 @@ static bool mergeConstants(Module &M) {
if (!Slot || Slot == GV)
continue;

if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr())
if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr())
continue;

if (!GV->hasUnnamedAddr())
Slot->setUnnamedAddr(false);
if (!GV->hasGlobalUnnamedAddr())
Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None);

// Make all uses of the duplicate constant use the canonical version.
Replacements.push_back(std::make_pair(GV, Slot));
Expand Down
19 changes: 13 additions & 6 deletions llvm/lib/Transforms/IPO/GlobalOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1942,8 +1942,7 @@ static bool processInternalGlobal(
static bool
processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
function_ref<DominatorTree &(Function &)> LookupDomTree) {
// Do more involved optimizations if the global is internal.
if (!GV.hasLocalLinkage())
if (GV.getName().startswith("llvm."))
return false;

GlobalStatus GS;
Expand All @@ -1952,12 +1951,20 @@ processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
return false;

bool Changed = false;
if (!GS.IsCompared && !GV.hasUnnamedAddr()) {
GV.setUnnamedAddr(true);
NumUnnamed++;
Changed = true;
if (!GS.IsCompared && !GV.hasGlobalUnnamedAddr()) {
auto NewUnnamedAddr = GV.hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
: GlobalValue::UnnamedAddr::Local;
if (NewUnnamedAddr != GV.getUnnamedAddr()) {
GV.setUnnamedAddr(NewUnnamedAddr);
NumUnnamed++;
Changed = true;
}
}

// Do more involved optimizations if the global is internal.
if (!GV.hasLocalLinkage())
return Changed;

auto *GVar = dyn_cast<GlobalVariable>(&GV);
if (!GVar)
return Changed;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/IPO/MergeFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,7 +1637,7 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {

// Replace G with an alias to F if possible, or else a thunk to F. Deletes G.
void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
if (HasGlobalAliases && G->hasUnnamedAddr()) {
if (HasGlobalAliases && G->hasGlobalUnnamedAddr()) {
if (G->hasExternalLinkage() || G->hasLocalLinkage() ||
G->hasWeakLinkage()) {
writeAlias(F, G);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
GlobalVariable *GV =
new GlobalVariable(M, StrConst->getType(), true,
GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix);
if (AllowMerging) GV->setUnnamedAddr(true);
if (AllowMerging) GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
return GV;
}
Expand All @@ -849,7 +849,7 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
auto GV = new GlobalVariable(M, LocStruct->getType(), true,
GlobalValue::PrivateLinkage, LocStruct,
kAsanGenPrefix);
GV->setUnnamedAddr(true);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
return GV;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
new GlobalVariable(M, StrConst->getType(), true,
GlobalValue::PrivateLinkage, StrConst, "");
if (AllowMerging)
GV->setUnnamedAddr(true);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
return GV;
}
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ bool GCOVProfiler::emitProfileArcs() {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
"__llvm_gcov_init", M);
F->setUnnamedAddr(true);
F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
F->setLinkage(GlobalValue::InternalLinkage);
F->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone)
Expand Down Expand Up @@ -766,7 +766,7 @@ GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
ConstantArray::get(EdgeTableTy,
makeArrayRef(&EdgeTable[0],TableSize)),
"__llvm_gcda_edge_table");
EdgeTableGV->setUnnamedAddr(true);
EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
return EdgeTableGV;
}

Expand Down Expand Up @@ -840,7 +840,7 @@ GlobalVariable *GCOVProfiler::getEdgeStateValue() {
ConstantInt::get(Type::getInt32Ty(*Ctx),
0xffffffff),
"__llvm_gcov_global_state_pred");
GV->setUnnamedAddr(true);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
}
return GV;
}
Expand All @@ -852,7 +852,7 @@ Function *GCOVProfiler::insertCounterWriteout(
if (!WriteoutF)
WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
"__llvm_gcov_writeout", M);
WriteoutF->setUnnamedAddr(true);
WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
WriteoutF->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone)
WriteoutF->addFnAttr(Attribute::NoRedZone);
Expand Down Expand Up @@ -912,7 +912,7 @@ Function *GCOVProfiler::insertCounterWriteout(
void GCOVProfiler::insertIndirectCounterIncrement() {
Function *Fn =
cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
Fn->setUnnamedAddr(true);
Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
Fn->setLinkage(GlobalValue::InternalLinkage);
Fn->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone)
Expand Down Expand Up @@ -969,7 +969,7 @@ insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
"__llvm_gcov_flush", M);
else
FlushF->setLinkage(GlobalValue::InternalLinkage);
FlushF->setUnnamedAddr(true);
FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
FlushF->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone)
FlushF->addFnAttr(Attribute::NoRedZone);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ void InstrProfiling::emitRegistration() {
auto *RegisterFTy = FunctionType::get(VoidTy, false);
auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
getInstrProfRegFuncsName(), M);
RegisterF->setUnnamedAddr(true);
RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);

auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
Expand Down Expand Up @@ -606,7 +606,7 @@ void InstrProfiling::emitInitialization() {
auto *F = Function::Create(FunctionType::get(VoidTy, false),
GlobalValue::InternalLinkage,
getInstrProfInitFuncName(), M);
F->setUnnamedAddr(true);
F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
F->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true,
GlobalValue::PrivateLinkage,
PatternValue, ".memset_pattern");
GV->setUnnamedAddr(true); // Ok to merge these.
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Ok to merge these.
GV->setAlignment(16);
Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy);
NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes});
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
// of the module and recorded in the summary index for use when importing
// from that module.
auto *GVar = dyn_cast<GlobalVariable>(SGV);
if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr())
if (GVar && GVar->isConstant() && GVar->hasGlobalUnnamedAddr())
return false;

if (GVar && GVar->hasSection())
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/GlobalStatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
}
}

if (StoredVal == GV->getInitializer()) {
if (GV->hasInitializer() && StoredVal == GV->getInitializer()) {
if (GS.StoredType < GlobalStatus::InitializerStored)
GS.StoredType = GlobalStatus::InitializerStored;
} else if (isa<LoadInst>(StoredVal) &&
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4540,7 +4540,7 @@ SwitchLookupTable::SwitchLookupTable(
Array = new GlobalVariable(M, ArrayTy, /*constant=*/true,
GlobalVariable::PrivateLinkage, Initializer,
"switch.table");
Array->setUnnamedAddr(true);
Array->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
Kind = ArrayKind;
}

Expand Down
13 changes: 13 additions & 0 deletions llvm/test/Assembler/local-unnamed-addr.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s

; CHECK: @c = local_unnamed_addr constant i32 0
@c = local_unnamed_addr constant i32 0

; CHECK: @a = local_unnamed_addr alias i32, i32* @c
@a = local_unnamed_addr alias i32, i32* @c

; CHECK: define void @f() local_unnamed_addr {
define void @f() local_unnamed_addr {
ret void
}
16 changes: 11 additions & 5 deletions llvm/test/Bitcode/compatibility.ll
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ $comdat.samesize = comdat samesize

;; Global Variables
; Format: [@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass]
; [ThreadLocal] [unnamed_addr] [AddrSpace] [ExternallyInitialized]
; [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized]
; <global | constant> <Type> [<InitializerConstant>]
; [, section "name"] [, comdat [($name)]] [, align <Alignment>]

Expand Down Expand Up @@ -142,9 +142,11 @@ $comdat.samesize = comdat samesize
@g.localexec = thread_local(localexec) global i32 0
; CHECK: @g.localexec = thread_local(localexec) global i32 0

; Global Variables -- unnamed_addr
; Global Variables -- unnamed_addr and local_unnamed_addr
@g.unnamed_addr = unnamed_addr global i32 0
; CHECK: @g.unnamed_addr = unnamed_addr global i32 0
@g.local_unnamed_addr = local_unnamed_addr global i32 0
; CHECK: @g.local_unnamed_addr = local_unnamed_addr global i32 0

; Global Variables -- AddrSpace
@g.addrspace = addrspace(1) global i32 0
Expand Down Expand Up @@ -245,9 +247,11 @@ declare void @g.f1()
@a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
; CHECK: @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec

; Aliases -- unnamed_addr
; Aliases -- unnamed_addr and local_unnamed_addr
@a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
; CHECK: @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
@a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
; CHECK: @a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr

;; IFunc
; Format @<Name> = [Linkage] [Visibility] ifunc <IFuncTy>,
Expand Down Expand Up @@ -278,7 +282,7 @@ entry:
; Format: define [linkage] [visibility] [DLLStorageClass]
; [cconv] [ret attrs]
; <ResultType> @<FunctionName> ([argument list])
; [unnamed_addr] [fn Attrs] [section "name"] [comdat [($name)]]
; [(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"] [comdat [($name)]]
; [align N] [gc] [prefix Constant] [prologue Constant]
; [personality Constant] { ... }

Expand Down Expand Up @@ -523,9 +527,11 @@ declare void @f.param.dereferenceable(i8* dereferenceable(4))
declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
; CHECK: declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))

; Functions -- unnamed_addr
; Functions -- unnamed_addr and local_unnamed_addr
declare void @f.unnamed_addr() unnamed_addr
; CHECK: declare void @f.unnamed_addr() unnamed_addr
declare void @f.local_unnamed_addr() local_unnamed_addr
; CHECK: declare void @f.local_unnamed_addr() local_unnamed_addr

; Functions -- fn Attrs (Function attributes)
declare void @f.alignstack4() alignstack(4)
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/PowerPC/weak_def_can_be_hidden.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
; RUN: llc -mtriple=powerpc-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
; RUN: llc -mtriple=powerpc-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s

@v1 = linkonce_odr constant i32 32
@v1 = linkonce_odr local_unnamed_addr constant i32 32
; CHECK: .globl _v1
; CHECK: .weak_def_can_be_hidden _v1

Expand All @@ -26,7 +26,7 @@ define i32* @f2() {
ret i32* @v2
}

@v3 = linkonce_odr unnamed_addr global i32 32
@v3 = linkonce_odr unnamed_addr constant i32 32
; CHECK: .globl _v3
; CHECK: .weak_def_can_be_hidden _v3

Expand All @@ -37,9 +37,9 @@ define i32* @f3() {
ret i32* @v3
}

@v4 = linkonce_odr global i32 32
@v4 = linkonce_odr unnamed_addr global i32 32
; CHECK: .globl _v4
; CHECK: .weak_definition _v4
; CHECK: .weak_def_can_be_hidden _v4

; CHECK-D89: .globl _v4
; CHECK-D89: .weak_definition _v4
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/X86/weak_def_can_be_hidden.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
; RUN: llc -mtriple=i686-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
; RUN: llc -mtriple=i686-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s

@v1 = linkonce_odr constant i32 32
@v1 = linkonce_odr local_unnamed_addr constant i32 32
; CHECK: .globl _v1
; CHECK: .weak_def_can_be_hidden _v1

Expand All @@ -27,7 +27,7 @@ define i32* @f2() {
ret i32* @v2
}

@v3 = linkonce_odr unnamed_addr global i32 32
@v3 = linkonce_odr unnamed_addr constant i32 32
; CHECK: .globl _v3
; CHECK: .weak_def_can_be_hidden _v3

Expand All @@ -38,9 +38,9 @@ define i32* @f3() {
ret i32* @v3
}

@v4 = linkonce_odr global i32 32
@v4 = linkonce_odr unnamed_addr global i32 32
; CHECK: .globl _v4
; CHECK: .weak_definition _v4
; CHECK: .weak_def_can_be_hidden _v4

; CHECK-D89: .globl _v4
; CHECK-D89: .weak_definition _v4
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Feature/OperandBundles/pr26510.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

declare void @foo() readnone

; CHECK-LABEL: define i8* @test(i8* %p) {
; CHECK-LABEL: define i8* @test(i8* %p)
; CHECK: %a = alloca i8*, align 8
; CHECK: store i8* %p, i8** %a, align 8
; CHECK: call void @foo() [ "abc"(i8** %a) ]
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/LTO/X86/cfi_endproc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ define i32* @get_zed1() {
ret i32* @zed1
}

; ZED1_AND_ZED2: d zed2
@zed2 = linkonce_odr unnamed_addr global i32 42
; ZED1_AND_ZED2: r zed2
@zed2 = linkonce_odr unnamed_addr constant i32 42

define i32 @useZed2() {
%x = load i32, i32* @zed2
Expand Down
59 changes: 26 additions & 33 deletions llvm/test/LTO/X86/linkonce_odr_func.ll
Original file line number Diff line number Diff line change
@@ -1,61 +1,54 @@
; RUN: llvm-as < %s >%t1
; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
; RUN: -dso-symbol=foo4 -dso-symbol=v1 -dso-symbol=v2 %t1 -O0
; RUN: -dso-symbol=v1 -dso-symbol=v2 -dso-symbol=v3 \
; RUN: -dso-symbol=v4 -dso-symbol=v5 -dso-symbol=v6 %t1 -O0
; RUN: llvm-nm %t2 | FileCheck %s

target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; CHECK: t foo1
; CHECK: W foo1
define linkonce_odr void @foo1() noinline {
ret void
}

; CHECK: W foo2
define linkonce_odr void @foo2() noinline {
; CHECK: t foo2
define linkonce_odr void @foo2() local_unnamed_addr noinline {
ret void
}

; CHECK: t foo3
define linkonce_odr void @foo3() noinline {
define linkonce_odr void @foo3() unnamed_addr noinline {
ret void
}

; CHECK: W foo4
define linkonce_odr void @foo4() noinline {
ret void
}

; CHECK: r v1
; CHECK: V v1
@v1 = linkonce_odr constant i32 32

define i32 @useV1() {
%x = load i32, i32* @v1
ret i32 %x
}
; CHECK: r v2
@v2 = linkonce_odr local_unnamed_addr constant i32 32

; CHECK: V v2
@v2 = linkonce_odr global i32 32
; CHECK: r v3
@v3 = linkonce_odr unnamed_addr constant i32 32

define i32 @useV2() {
%x = load i32, i32* @v2
ret i32 %x
}
; CHECK: V v4
@v4 = linkonce_odr global i32 32

declare void @f(void()*)
; CHECK: V v5
@v5 = linkonce_odr local_unnamed_addr global i32 32

declare void @p()
; CHECK: d v6
@v6 = linkonce_odr unnamed_addr global i32 32

define void @bar() personality void()* @p {
bb0:
define void @use() {
call void @foo1()
call void @f(void()* @foo2)
invoke void @foo3() to label %bb1 unwind label %clean
bb1:
invoke void @f(void()* @foo4) to label %bb2 unwind label %clean
bb2:
ret void
clean:
landingpad {i32, i32} cleanup
call void @foo2()
call void @foo3()
%x1 = load i32, i32* @v1
%x2 = load i32, i32* @v2
%x3 = load i32, i32* @v3
%x4 = load i32, i32* @v4
%x5 = load i32, i32* @v5
%x6 = load i32, i32* @v6
ret void
}
156 changes: 78 additions & 78 deletions llvm/test/Other/constant-fold-gep.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@
; PLAIN: @F1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -2)
; PLAIN: @H8 = global i8* getelementptr (i8, i8* null, i32 -1)
; PLAIN: @H1 = global i1* getelementptr (i1, i1* null, i32 -1)
; OPT: @G8 = global i8* null
; OPT: @G1 = global i1* null
; OPT: @F8 = global i8* inttoptr (i64 -1 to i8*)
; OPT: @F1 = global i1* inttoptr (i64 -1 to i1*)
; OPT: @H8 = global i8* inttoptr (i64 -1 to i8*)
; OPT: @H1 = global i1* inttoptr (i64 -1 to i1*)
; TO: @G8 = global i8* null
; TO: @G1 = global i1* null
; TO: @F8 = global i8* inttoptr (i64 -1 to i8*)
; TO: @F1 = global i1* inttoptr (i64 -1 to i1*)
; TO: @H8 = global i8* inttoptr (i64 -1 to i8*)
; TO: @H1 = global i1* inttoptr (i64 -1 to i1*)
; OPT: @G8 = local_unnamed_addr global i8* null
; OPT: @G1 = local_unnamed_addr global i1* null
; OPT: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
; OPT: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
; OPT: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
; OPT: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
; TO: @G8 = local_unnamed_addr global i8* null
; TO: @G1 = local_unnamed_addr global i1* null
; TO: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
; TO: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
; TO: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
; TO: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)

@G8 = global i8* getelementptr (i8, i8* inttoptr (i32 1 to i8*), i32 -1)
@G1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -1)
Expand All @@ -57,24 +57,24 @@
; PLAIN: @g = constant i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64)
; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)
; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64)
; OPT: @a = constant i64 18480
; OPT: @b = constant i64 8
; OPT: @c = constant i64 16
; OPT: @d = constant i64 88
; OPT: @e = constant i64 16
; OPT: @f = constant i64 1
; OPT: @g = constant i64 8
; OPT: @h = constant i64 8
; OPT: @i = constant i64 8
; TO: @a = constant i64 18480
; TO: @b = constant i64 8
; TO: @c = constant i64 16
; TO: @d = constant i64 88
; TO: @e = constant i64 16
; TO: @f = constant i64 1
; TO: @g = constant i64 8
; TO: @h = constant i64 8
; TO: @i = constant i64 8
; OPT: @a = local_unnamed_addr constant i64 18480
; OPT: @b = local_unnamed_addr constant i64 8
; OPT: @c = local_unnamed_addr constant i64 16
; OPT: @d = local_unnamed_addr constant i64 88
; OPT: @e = local_unnamed_addr constant i64 16
; OPT: @f = local_unnamed_addr constant i64 1
; OPT: @g = local_unnamed_addr constant i64 8
; OPT: @h = local_unnamed_addr constant i64 8
; OPT: @i = local_unnamed_addr constant i64 8
; TO: @a = local_unnamed_addr constant i64 18480
; TO: @b = local_unnamed_addr constant i64 8
; TO: @c = local_unnamed_addr constant i64 16
; TO: @d = local_unnamed_addr constant i64 88
; TO: @e = local_unnamed_addr constant i64 16
; TO: @f = local_unnamed_addr constant i64 1
; TO: @g = local_unnamed_addr constant i64 8
; TO: @h = local_unnamed_addr constant i64 8
; TO: @i = local_unnamed_addr constant i64 8

@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}, {i1, [13 x double]}* null, i64 0, i32 1) to i64)
Expand All @@ -91,12 +91,12 @@
; PLAIN: @M = constant i64* getelementptr (i64, i64* null, i32 1)
; PLAIN: @N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
; PLAIN: @O = constant i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1)
; OPT: @M = constant i64* inttoptr (i64 8 to i64*)
; OPT: @N = constant i64* inttoptr (i64 8 to i64*)
; OPT: @O = constant i64* inttoptr (i64 8 to i64*)
; TO: @M = constant i64* inttoptr (i64 8 to i64*)
; TO: @N = constant i64* inttoptr (i64 8 to i64*)
; TO: @O = constant i64* inttoptr (i64 8 to i64*)
; OPT: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
; OPT: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
; OPT: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
; TO: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
; TO: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
; TO: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)

@M = constant i64* getelementptr (i64, i64* null, i32 1)
@N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
Expand All @@ -106,10 +106,10 @@

; PLAIN: @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
; PLAIN: @Z = global i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
; OPT: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
; OPT: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; TO: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
; TO: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; OPT: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
; OPT: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; TO: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
; TO: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)

@ext = external global [3 x { i32, i32 }]
@Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 1), i64 1)
Expand Down Expand Up @@ -142,40 +142,40 @@
; PLAIN: %t = bitcast i1* getelementptr (i1, i1* null, i32 -1) to i1*
; PLAIN: ret i1* %t
; PLAIN: }
; OPT: define i8* @goo8() #0 {
; OPT: define i8* @goo8() local_unnamed_addr #0 {
; OPT: ret i8* null
; OPT: }
; OPT: define i1* @goo1() #0 {
; OPT: define i1* @goo1() local_unnamed_addr #0 {
; OPT: ret i1* null
; OPT: }
; OPT: define i8* @foo8() #0 {
; OPT: define i8* @foo8() local_unnamed_addr #0 {
; OPT: ret i8* inttoptr (i64 -1 to i8*)
; OPT: }
; OPT: define i1* @foo1() #0 {
; OPT: define i1* @foo1() local_unnamed_addr #0 {
; OPT: ret i1* inttoptr (i64 -1 to i1*)
; OPT: }
; OPT: define i8* @hoo8() #0 {
; OPT: define i8* @hoo8() local_unnamed_addr #0 {
; OPT: ret i8* inttoptr (i64 -1 to i8*)
; OPT: }
; OPT: define i1* @hoo1() #0 {
; OPT: define i1* @hoo1() local_unnamed_addr #0 {
; OPT: ret i1* inttoptr (i64 -1 to i1*)
; OPT: }
; TO: define i8* @goo8() #0 {
; TO: define i8* @goo8() local_unnamed_addr #0 {
; TO: ret i8* null
; TO: }
; TO: define i1* @goo1() #0 {
; TO: define i1* @goo1() local_unnamed_addr #0 {
; TO: ret i1* null
; TO: }
; TO: define i8* @foo8() #0 {
; TO: define i8* @foo8() local_unnamed_addr #0 {
; TO: ret i8* inttoptr (i64 -1 to i8*)
; TO: }
; TO: define i1* @foo1() #0 {
; TO: define i1* @foo1() local_unnamed_addr #0 {
; TO: ret i1* inttoptr (i64 -1 to i1*)
; TO: }
; TO: define i8* @hoo8() #0 {
; TO: define i8* @hoo8() local_unnamed_addr #0 {
; TO: ret i8* inttoptr (i64 -1 to i8*)
; TO: }
; TO: define i1* @hoo1() #0 {
; TO: define i1* @hoo1() local_unnamed_addr #0 {
; TO: ret i1* inttoptr (i64 -1 to i1*)
; TO: }
; SCEV: Classifying expressions for: @goo8
Expand Down Expand Up @@ -256,58 +256,58 @@ define i1* @hoo1() nounwind {
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64) to i64
; PLAIN: ret i64 %t
; PLAIN: }
; OPT: define i64 @fa() #0 {
; OPT: define i64 @fa() local_unnamed_addr #0 {
; OPT: ret i64 18480
; OPT: }
; OPT: define i64 @fb() #0 {
; OPT: define i64 @fb() local_unnamed_addr #0 {
; OPT: ret i64 8
; OPT: }
; OPT: define i64 @fc() #0 {
; OPT: define i64 @fc() local_unnamed_addr #0 {
; OPT: ret i64 16
; OPT: }
; OPT: define i64 @fd() #0 {
; OPT: define i64 @fd() local_unnamed_addr #0 {
; OPT: ret i64 88
; OPT: }
; OPT: define i64 @fe() #0 {
; OPT: define i64 @fe() local_unnamed_addr #0 {
; OPT: ret i64 16
; OPT: }
; OPT: define i64 @ff() #0 {
; OPT: define i64 @ff() local_unnamed_addr #0 {
; OPT: ret i64 1
; OPT: }
; OPT: define i64 @fg() #0 {
; OPT: define i64 @fg() local_unnamed_addr #0 {
; OPT: ret i64 8
; OPT: }
; OPT: define i64 @fh() #0 {
; OPT: define i64 @fh() local_unnamed_addr #0 {
; OPT: ret i64 8
; OPT: }
; OPT: define i64 @fi() #0 {
; OPT: define i64 @fi() local_unnamed_addr #0 {
; OPT: ret i64 8
; OPT: }
; TO: define i64 @fa() #0 {
; TO: define i64 @fa() local_unnamed_addr #0 {
; TO: ret i64 18480
; TO: }
; TO: define i64 @fb() #0 {
; TO: define i64 @fb() local_unnamed_addr #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fc() #0 {
; TO: define i64 @fc() local_unnamed_addr #0 {
; TO: ret i64 16
; TO: }
; TO: define i64 @fd() #0 {
; TO: define i64 @fd() local_unnamed_addr #0 {
; TO: ret i64 88
; TO: }
; TO: define i64 @fe() #0 {
; TO: define i64 @fe() local_unnamed_addr #0 {
; TO: ret i64 16
; TO: }
; TO: define i64 @ff() #0 {
; TO: define i64 @ff() local_unnamed_addr #0 {
; TO: ret i64 1
; TO: }
; TO: define i64 @fg() #0 {
; TO: define i64 @fg() local_unnamed_addr #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fh() #0 {
; TO: define i64 @fh() local_unnamed_addr #0 {
; TO: ret i64 8
; TO: }
; TO: define i64 @fi() #0 {
; TO: define i64 @fi() local_unnamed_addr #0 {
; TO: ret i64 8
; TO: }
; SCEV: Classifying expressions for: @fa
Expand Down Expand Up @@ -387,22 +387,22 @@ define i64 @fi() nounwind {
; PLAIN: %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64*
; PLAIN: ret i64* %t
; PLAIN: }
; OPT: define i64* @fM() #0 {
; OPT: define i64* @fM() local_unnamed_addr #0 {
; OPT: ret i64* inttoptr (i64 8 to i64*)
; OPT: }
; OPT: define i64* @fN() #0 {
; OPT: define i64* @fN() local_unnamed_addr #0 {
; OPT: ret i64* inttoptr (i64 8 to i64*)
; OPT: }
; OPT: define i64* @fO() #0 {
; OPT: define i64* @fO() local_unnamed_addr #0 {
; OPT: ret i64* inttoptr (i64 8 to i64*)
; OPT: }
; TO: define i64* @fM() #0 {
; TO: define i64* @fM() local_unnamed_addr #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; TO: define i64* @fN() #0 {
; TO: define i64* @fN() local_unnamed_addr #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; TO: define i64* @fO() #0 {
; TO: define i64* @fO() local_unnamed_addr #0 {
; TO: ret i64* inttoptr (i64 8 to i64*)
; TO: }
; SCEV: Classifying expressions for: @fM
Expand Down Expand Up @@ -432,10 +432,10 @@ define i64* @fO() nounwind {
; PLAIN: %t = bitcast i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
; PLAIN: ret i32* %t
; PLAIN: }
; OPT: define i32* @fZ() #0 {
; OPT: define i32* @fZ() local_unnamed_addr #0 {
; OPT: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; OPT: }
; TO: define i32* @fZ() #0 {
; TO: define i32* @fZ() local_unnamed_addr #0 {
; TO: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
; TO: }
; SCEV: Classifying expressions for: @fZ
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

; PR8389: Globals with weak_odr linkage type must not be modified

; CHECK: weak_odr global i32 0
; CHECK: weak_odr local_unnamed_addr global i32 0

@SomeVar = weak_odr global i32 0

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/alias-used-address-space.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ target datalayout = "p:32:32:32-p1:16:16:16"
; CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ia to i8*)], section "llvm.metadata"

@sameAsUsed = global [1 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ca to i8*)]
; CHECK-DAG: @sameAsUsed = global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]

@ca = internal alias i8, i8 addrspace(1)* @c
; CHECK: @ca = internal alias i8, i8 addrspace(1)* @c
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GlobalOpt/alias-used.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
; CHECK-DAG: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* @ia], section "llvm.metadata"

@sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca]
; CHECK-DAG: @sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]

@other = global i32* bitcast (void ()* @fa to i32*)
; CHECK-DAG: @other = global i32* bitcast (void ()* @f to i32*)
; CHECK-DAG: @other = local_unnamed_addr global i32* bitcast (void ()* @f to i32*)

@fa = internal alias void (), void ()* @f
; CHECK: @fa = internal alias void (), void ()* @f
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/assume.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: opt -S -globalopt < %s | FileCheck %s

; CHECK: @tmp = global i32 42
; CHECK: @tmp = local_unnamed_addr global i32 42

@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
@tmp = global i32 0
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/Transforms/GlobalOpt/constantfold-initializers.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3

@.str91250 = global [3 x i8] zeroinitializer

; CHECK: @A = global i1 false
; CHECK: @A = local_unnamed_addr global i1 false
@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)

; PR11352

@xs = global [2 x i32] zeroinitializer, align 4
; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
; CHECK: @xs = local_unnamed_addr global [2 x i32] [i32 1, i32 1]

; PR12642
%PR12642.struct = type { i8 }
Expand All @@ -32,7 +32,7 @@ entry:
@f = internal global %closure zeroinitializer, align 4
@m = global i32 0, align 4
; CHECK-NOT: @f
; CHECK: @m = global i32 13
; CHECK: @m = local_unnamed_addr global i32 13

define internal i32 @test2_helper(%closure* %this, i32 %b) {
entry:
Expand All @@ -53,7 +53,7 @@ entry:
; PR19955

@dllimportptr = global i32* null, align 4
; CHECK: @dllimportptr = global i32* null, align 4
; CHECK: @dllimportptr = local_unnamed_addr global i32* null, align 4
@dllimportvar = external dllimport global i32
define internal void @test3() {
entry:
Expand All @@ -62,7 +62,7 @@ entry:
}

@dllexportptr = global i32* null, align 4
; CHECK: @dllexportptr = global i32* @dllexportvar, align 4
; CHECK: @dllexportptr = local_unnamed_addr global i32* @dllexportvar, align 4
@dllexportvar = dllexport global i32 0, align 4
; CHECK: @dllexportvar = dllexport global i32 20, align 4
define internal void @test4() {
Expand All @@ -83,7 +83,7 @@ entry:

@test6_v1 = internal global { i32, i32 } { i32 42, i32 0 }, align 8
@test6_v2 = global i32 0, align 4
; CHECK: @test6_v2 = global i32 42, align 4
; CHECK: @test6_v2 = local_unnamed_addr global i32 42, align 4
define internal void @test6() {
%load = load { i32, i32 }, { i32, i32 }* @test6_v1, align 8
%xv0 = extractvalue { i32, i32 } %load, 0
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
; Don't get fooled by the inbounds keyword; it doesn't change
; the computed address.

; CHECK: @H = global i32 2
; CHECK: @I = global i32 2
; CHECK: @H = local_unnamed_addr global i32 2
; CHECK: @I = local_unnamed_addr global i32 2

@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
@addr = external global i32
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

; This test is hint, what could globalOpt optimize and what it can't
; FIXME: @tmp and @tmp2 can be safely set to 42
; CHECK: @tmp = global i32 0
; CHECK: @tmp2 = global i32 0
; CHECK: @tmp = local_unnamed_addr global i32 0
; CHECK: @tmp2 = local_unnamed_addr global i32 0
; CHECK: @tmp3 = global i32 0

@tmp = global i32 0
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/invoke.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; rdar://11022897

; Globalopt should be able to evaluate an invoke.
; CHECK: @tmp = global i32 1
; CHECK: @tmp = local_unnamed_addr global i32 1

@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
@tmp = global i32 0
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/GlobalOpt/pr21191.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ $c = comdat any
define linkonce_odr void @foo() comdat($c) {
ret void
}
; CHECK: define linkonce_odr void @foo() comdat($c)
; CHECK: define linkonce_odr void @foo() local_unnamed_addr comdat($c)

define linkonce_odr void @bar() comdat($c) {
ret void
}
; CHECK: define linkonce_odr void @bar() comdat($c)
; CHECK: define linkonce_odr void @bar() local_unnamed_addr comdat($c)

define void @zed() {
call void @foo()
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/unnamed-addr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
; CHECK: @b = internal global i32 0, align 4
; CHECK: @c = internal unnamed_addr global i32 0, align 4
; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
; CHECK: @e = linkonce_odr global i32 0
; CHECK: @e = linkonce_odr local_unnamed_addr global i32 0

; CHECK: define internal fastcc void @used_internal() unnamed_addr {
define internal void @used_internal() {
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/tools/gold/X86/coff.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ define hidden void @g() {
ret void
}

; CHECK: define internal void @h() {
define linkonce_odr void @h() {
; CHECK: define internal void @h() local_unnamed_addr {
define linkonce_odr void @h() local_unnamed_addr {
ret void
}
28 changes: 23 additions & 5 deletions llvm/test/tools/gold/X86/emit-llvm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@

target triple = "x86_64-unknown-linux-gnu"

; CHECK-DAG: @g1 = linkonce_odr constant i32 32
@g1 = linkonce_odr constant i32 32

; CHECK-DAG: @g2 = internal local_unnamed_addr constant i32 32
@g2 = linkonce_odr local_unnamed_addr constant i32 32

; CHECK-DAG: @g3 = internal unnamed_addr constant i32 32
@g3 = linkonce_odr unnamed_addr constant i32 32

; CHECK-DAG: @g4 = linkonce_odr global i32 32
@g4 = linkonce_odr global i32 32

; CHECK-DAG: @g5 = linkonce_odr local_unnamed_addr global i32 32
@g5 = linkonce_odr local_unnamed_addr global i32 32

; CHECK-DAG: @g6 = internal unnamed_addr global i32 32
@g6 = linkonce_odr unnamed_addr global i32 32

@g7 = extern_weak global i32
; CHECK-DAG: @g7 = extern_weak global i32

Expand Down Expand Up @@ -53,7 +71,7 @@ define void @f3() {

; CHECK-DAG: define internal void @f4()
; OPT2-NOT: @f4
define linkonce_odr void @f4() {
define linkonce_odr void @f4() local_unnamed_addr {
ret void
}

Expand All @@ -62,14 +80,14 @@ define linkonce_odr void @f4() {
define linkonce_odr void @f5() {
ret void
}
@g5 = global void()* @f5
@g9 = global void()* @f5

; CHECK-DAG: define internal void @f6() unnamed_addr
; OPT-DAG: define internal void @f6() unnamed_addr
define linkonce_odr void @f6() unnamed_addr {
ret void
}
@g6 = global void()* @f6
@g10 = global void()* @f6

define i32* @f7() {
ret i32* @g7
Expand All @@ -89,5 +107,5 @@ define i32* @f8() {
; API: f8 PREVAILING_DEF_IRONLY_EXP
; API: g7 UNDEF
; API: g8 UNDEF
; API: g5 PREVAILING_DEF_IRONLY_EXP
; API: g6 PREVAILING_DEF_IRONLY_EXP
; API: g9 PREVAILING_DEF_IRONLY_EXP
; API: g10 PREVAILING_DEF_IRONLY_EXP
41 changes: 15 additions & 26 deletions llvm/tools/gold/gold-plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct ResolutionInfo {
uint64_t CommonSize = 0;
unsigned CommonAlign = 0;
bool IsLinkonceOdr = true;
bool UnnamedAddr = true;
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::Global;
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
bool CommonInternal = false;
bool UseCommon = false;
Expand Down Expand Up @@ -551,7 +551,8 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,

sym.visibility = LDPV_DEFAULT;
if (GV) {
Res.UnnamedAddr &= GV->hasUnnamedAddr();
Res.UnnamedAddr =
GlobalValue::getMinUnnamedAddr(Res.UnnamedAddr, GV->getUnnamedAddr());
Res.IsLinkonceOdr &= GV->hasLinkOnceLinkage();
Res.Visibility = getMinVisibility(Res.Visibility, GV->getVisibility());
switch (GV->getVisibility()) {
Expand Down Expand Up @@ -690,10 +691,11 @@ getModuleSummaryIndexForFile(claimed_file &F) {
return Obj.takeIndex();
}

static std::unique_ptr<Module> getModuleForFile(
LLVMContext &Context, claimed_file &F, const void *View, StringRef Name,
raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe,
std::vector<GlobalValue *> &Keep, StringMap<unsigned> &Realign) {
static std::unique_ptr<Module>
getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
StringRef Name, raw_fd_ostream *ApiFile,
StringSet<> &Internalize, std::vector<GlobalValue *> &Keep,
StringMap<unsigned> &Realign) {
MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), Name);
ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
object::IRObjectFile::create(BufferRef, Context);
Expand Down Expand Up @@ -827,12 +829,9 @@ static std::unique_ptr<Module> getModuleForFile(
break;

case LDPR_PREVAILING_DEF_IRONLY_EXP: {
// We can only check for address uses after we merge the modules. The
// reason is that this GV might have a copy in another module
// and in that module the address might be significant, but that
// copy will be LDPR_PREEMPTED_IR.
Maybe.insert(GV->getName());
Keep.push_back(GV);
if (canBeOmittedFromSymbolTable(GV))
Internalize.insert(GV->getName());
break;
}
}
Expand Down Expand Up @@ -1149,11 +1148,11 @@ void CodeGen::runAll() {
static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
const void *View, StringRef Name,
raw_fd_ostream *ApiFile, StringSet<> &Internalize,
StringSet<> &Maybe, bool SetName = false) {
bool SetName = false) {
std::vector<GlobalValue *> Keep;
StringMap<unsigned> Realign;
std::unique_ptr<Module> M = getModuleForFile(
Context, F, View, Name, ApiFile, Internalize, Maybe, Keep, Realign);
std::unique_ptr<Module> M = getModuleForFile(Context, F, View, Name, ApiFile,
Internalize, Keep, Realign);
if (!M.get())
return;
if (!options::triple.empty())
Expand Down Expand Up @@ -1204,7 +1203,7 @@ static void thinLTOBackendTask(claimed_file &F, const void *View,
IRMover L(*NewModule.get());

StringSet<> Dummy;
linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy, true);
linkInModule(Context, L, F, View, Name, ApiFile, Dummy, true);
if (renameModuleForThinLTO(*NewModule, CombinedIndex))
message(LDPL_FATAL, "Failed to rename module for ThinLTO");

Expand Down Expand Up @@ -1474,15 +1473,14 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
IRMover L(*Combined);

StringSet<> Internalize;
StringSet<> Maybe;
for (claimed_file &F : Modules) {
// RAII object to manage the file opening and releasing interfaces with
// gold.
PluginInputFile InputFile(F.handle);
const void *View = getSymbolsAndView(F);
if (!View)
continue;
linkInModule(Context, L, F, View, F.name, ApiFile, Internalize, Maybe);
linkInModule(Context, L, F, View, F.name, ApiFile, Internalize);
}

for (const auto &Name : Internalize) {
Expand All @@ -1491,15 +1489,6 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
internalize(*GV);
}

for (const auto &Name : Maybe) {
GlobalValue *GV = Combined->getNamedValue(Name.first());
if (!GV)
continue;
GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
if (canBeOmittedFromSymbolTable(GV))
internalize(*GV);
}

if (options::TheOutputType == options::OT_DISABLE)
return LDPS_OK;

Expand Down