From 41f99d789571ea41e49634397888730805b5c90b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 12 Jan 2018 17:03:43 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322378 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/GlobalValue.h | 3 +-- lib/AsmParser/LLParser.cpp | 5 ----- lib/Bitcode/Reader/BitcodeReader.cpp | 19 +++++++++++-------- lib/Bitcode/Writer/BitcodeWriter.cpp | 3 ++- .../{ifunc-dsolocal-daig.ll => ifunc-dsolocal.ll} | 4 ++-- 5 files changed, 16 insertions(+), 18 deletions(-) rename test/Assembler/{ifunc-dsolocal-daig.ll => ifunc-dsolocal.ll} (50%) diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 7823eefecdc..1d8025d4a9b 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/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/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 6f425721c1b..f94b616e596 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/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/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 95291a1caf9..1b029bf8885 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index a7201ed9735..f3f33c4474b 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/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/test/Assembler/ifunc-dsolocal-daig.ll b/test/Assembler/ifunc-dsolocal.ll similarity index 50% rename from test/Assembler/ifunc-dsolocal-daig.ll rename to test/Assembler/ifunc-dsolocal.ll index 86e941d6cac..63242cb3f24 100644 --- a/test/Assembler/ifunc-dsolocal-daig.ll +++ b/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: -- 2.11.0