diff options
author | Fangrui Song <maskray@google.com> | 2019-05-15 02:35:32 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-05-15 02:35:32 +0000 |
commit | f4dfd63c74899e2953b176de2174ae7a8924a72c (patch) | |
tree | 10b8dd0ca599015981cbea658f927847791c4d5b /llvm/lib/IR/AutoUpgrade.cpp | |
parent | bd3adfe5e3bcb6f8f16166d1fd8a3f3c4fd70307 (diff) | |
download | bcm5719-llvm-f4dfd63c74899e2953b176de2174ae7a8924a72c.tar.gz bcm5719-llvm-f4dfd63c74899e2953b176de2174ae7a8924a72c.zip |
[IR] Disallow llvm.global_ctors and llvm.global_dtors of the 2-field form in textual format
The 3-field form was introduced by D3499 in 2014 and the legacy 2-field
form was planned to be removed in LLVM 4.0
For the textual format, this patch migrates the existing 2-field form to
use the 3-field form and deletes the compatibility code.
test/Verifier/global-ctors-2.ll checks we have a friendly error message.
For bitcode, lib/IR/AutoUpgrade UpgradeGlobalVariables will upgrade the
2-field form (add i8* null as the third field).
Reviewed By: rnk, dexonsmith
Differential Revision: https://reviews.llvm.org/D61547
llvm-svn: 360742
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index c0fd3cd7cbd..e6a096a8855 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -805,9 +805,35 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { return Upgraded; } -bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { - // Nothing to do yet. - return false; +GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) { + if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" || + GV->getName() == "llvm.global_dtors")) || + !GV->hasInitializer()) + return nullptr; + ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType()); + if (!ATy) + return nullptr; + StructType *STy = dyn_cast<StructType>(ATy->getElementType()); + if (!STy || STy->getNumElements() != 2) + return nullptr; + + LLVMContext &C = GV->getContext(); + IRBuilder<> IRB(C); + auto EltTy = StructType::get(STy->getElementType(0), STy->getElementType(1), + IRB.getInt8PtrTy()); + Constant *Init = GV->getInitializer(); + unsigned N = Init->getNumOperands(); + std::vector<Constant *> NewCtors(N); + for (unsigned i = 0; i != N; ++i) { + auto Ctor = cast<Constant>(Init->getOperand(i)); + NewCtors[i] = ConstantStruct::get( + EltTy, Ctor->getAggregateElement(0u), Ctor->getAggregateElement(1), + Constant::getNullValue(IRB.getInt8PtrTy())); + } + Constant *NewInit = ConstantArray::get(ArrayType::get(EltTy, N), NewCtors); + + return new GlobalVariable(NewInit->getType(), false, GV->getLinkage(), + NewInit, GV->getName()); } // Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them |