1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

Allow dso_local on ifunc.

It was never fully disallowed. We were rejecting it in the asm parser,
but not in the verifier.

Currently TargetMachine::shouldAssumeDSOLocal returns true for hidden
ifuncs. I considered changing it and moving the check from the asm
parser to the verifier.

The reason for deciding to allow it instead is that all linkers handle
a direct reference just fine. They use the plt address as the address
of the function. In fact doing that means that clang doesn't have the
same bug as gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83782.

This patch then removes the check from the asm parser and updates the
bitcode reader and writer.

llvm-svn: 322378
This commit is contained in:
Rafael Espindola 2018-01-12 17:03:43 +00:00
parent 4929ea0ba7
commit 2ce48efc54
5 changed files with 16 additions and 18 deletions

View File

@ -437,8 +437,7 @@ public:
void setLinkage(LinkageTypes LT) {
if (isLocalLinkage(LT)) {
Visibility = DefaultVisibility;
if (getValueID() != Value::GlobalIFuncVal)
setDSOLocal(true);
setDSOLocal(true);
}
Linkage = LT;
}

View File

@ -756,11 +756,6 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
return Error(NameLoc,
"symbol with local linkage must have default visibility");
if (DSOLocal && !IsAlias) {
return Error(NameLoc,
"dso_local is invalid on ifunc");
}
Type *Ty;
LocTy ExplicitTypeLoc = Lex.getLoc();
if (ParseType(Ty) ||

View File

@ -3054,14 +3054,17 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
// FIXME: Change to an error if non-default in 4.0.
NewGA->setVisibility(getDecodedVisibility(Record[VisInd]));
}
if (OpNum != Record.size())
NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++]));
else
upgradeDLLImportExportLinkage(NewGA, Linkage);
if (OpNum != Record.size())
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
if (OpNum != Record.size())
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
if (BitCode == bitc::MODULE_CODE_ALIAS ||
BitCode == bitc::MODULE_CODE_ALIAS_OLD) {
if (OpNum != Record.size())
NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++]));
else
upgradeDLLImportExportLinkage(NewGA, Linkage);
if (OpNum != Record.size())
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
if (OpNum != Record.size())
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
}
if (OpNum != Record.size())
NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++]));
ValueList.push_back(NewGA);

View File

@ -1302,7 +1302,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// Emit the ifunc information.
for (const GlobalIFunc &I : M.ifuncs()) {
// IFUNC: [strtab offset, strtab size, ifunc type, address space, resolver
// val#, linkage, visibility]
// val#, linkage, visibility, DSO_Local]
Vals.push_back(addToStrtab(I.getName()));
Vals.push_back(I.getName().size());
Vals.push_back(VE.getTypeID(I.getValueType()));
@ -1310,6 +1310,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(VE.getValueID(I.getResolver()));
Vals.push_back(getEncodedLinkage(I));
Vals.push_back(getEncodedVisibility(I));
Vals.push_back(I.isDSOLocal());
Stream.EmitRecord(bitc::MODULE_CODE_IFUNC, Vals);
Vals.clear();
}

View File

@ -1,7 +1,7 @@
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
@foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc
; CHECK: error: dso_local is invalid on ifunc
; CHECK: @foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc
define internal i64 @foo_ifunc() {
entry: