summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2018-01-12 17:03:43 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2018-01-12 17:03:43 +0000
commit3b9843f0ffbbef83eeecffb6d97cf9b3be3b159f (patch)
tree14df8a4d75e1eb23f82f3936b92c374c99f38fc1
parent84652cc63cce8e0afd445de0d6803d19f59cfbee (diff)
downloadbcm5719-llvm-3b9843f0ffbbef83eeecffb6d97cf9b3be3b159f.tar.gz
bcm5719-llvm-3b9843f0ffbbef83eeecffb6d97cf9b3be3b159f.zip
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
-rw-r--r--llvm/include/llvm/IR/GlobalValue.h3
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp5
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp19
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp3
-rw-r--r--llvm/test/Assembler/ifunc-dsolocal.ll (renamed from llvm/test/Assembler/ifunc-dsolocal-daig.ll)4
5 files changed, 16 insertions, 18 deletions
diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 7823eefecdc..1d8025d4a9b 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -437,8 +437,7 @@ public:
void setLinkage(LinkageTypes LT) {
if (isLocalLinkage(LT)) {
Visibility = DefaultVisibility;
- if (getValueID() != Value::GlobalIFuncVal)
- setDSOLocal(true);
+ setDSOLocal(true);
}
Linkage = LT;
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 6f425721c1b..f94b616e596 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -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) ||
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 95291a1caf9..1b029bf8885 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -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);
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a7201ed9735..f3f33c4474b 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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();
}
diff --git a/llvm/test/Assembler/ifunc-dsolocal-daig.ll b/llvm/test/Assembler/ifunc-dsolocal.ll
index 86e941d6cac..63242cb3f24 100644
--- a/llvm/test/Assembler/ifunc-dsolocal-daig.ll
+++ b/llvm/test/Assembler/ifunc-dsolocal.ll
@@ -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:
OpenPOWER on IntegriCloud