From aecde199358b2a6440df47330c107d694274ad59 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Mon, 21 Aug 2017 21:49:13 +0000 Subject: [PATCH] [IR] AutoUpgrade ModuleFlagBehavior for PIC and PIE level Summary: From r303590, ModuleFlagBehavior for PIC and PIE level is changed from Error to Max. This will cause bitcode compatibility issue when linking against a bitcode static archive built with old compiler. Add an auto-ugprade path to upgrade the the ModuleFlagBehavior in the old bitcode to match the new one so IRLinker can link them. Reviewers: tejohnson, mehdi_amini, dexonsmith Reviewed By: dexonsmith Subscribers: hans, llvm-commits Differential Revision: https://reviews.llvm.org/D36556 llvm-svn: 311387 --- lib/IR/AutoUpgrade.cpp | 28 +++++++++++++++++++++++----- test/Bitcode/upgrade-module-flag.ll | 12 ++++++++---- test/Linker/module-flags-pic-1-a.ll | 4 ++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index 0c2062d80d6..6184ce59dc1 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -2284,14 +2284,14 @@ bool llvm::UpgradeDebugInfo(Module &M) { } bool llvm::UpgradeModuleFlags(Module &M) { - const NamedMDNode *ModFlags = M.getModuleFlagsMetadata(); + NamedMDNode *ModFlags = M.getModuleFlagsMetadata(); if (!ModFlags) return false; - bool HasObjCFlag = false, HasClassProperties = false; + bool HasObjCFlag = false, HasClassProperties = false, Changed = false; for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { MDNode *Op = ModFlags->getOperand(I); - if (Op->getNumOperands() < 2) + if (Op->getNumOperands() != 3) continue; MDString *ID = dyn_cast_or_null(Op->getOperand(1)); if (!ID) @@ -2300,7 +2300,24 @@ bool llvm::UpgradeModuleFlags(Module &M) { HasObjCFlag = true; if (ID->getString() == "Objective-C Class Properties") HasClassProperties = true; + // Upgrade PIC/PIE Module Flags. The module flag behavior for these two + // field was Error and now they are Max. + if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") { + if (auto *Behavior = + mdconst::dyn_extract_or_null(Op->getOperand(0))) { + if (Behavior->getLimitedValue() == Module::Error) { + Type *Int32Ty = Type::getInt32Ty(M.getContext()); + Metadata *Ops[3] = { + ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)), + MDString::get(M.getContext(), ID->getString()), + Op->getOperand(2)}; + ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops)); + Changed = true; + } + } + } } + // "Objective-C Class Properties" is recently added for Objective-C. We // upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module // flag of value 0, so we can correclty downgrade this flag when trying to @@ -2309,9 +2326,10 @@ bool llvm::UpgradeModuleFlags(Module &M) { if (HasObjCFlag && !HasClassProperties) { M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties", (uint32_t)0); - return true; + Changed = true; } - return false; + + return Changed; } static bool isOldLoopArgument(Metadata *MD) { diff --git a/test/Bitcode/upgrade-module-flag.ll b/test/Bitcode/upgrade-module-flag.ll index d6741faa837..de6c9b2cf1b 100644 --- a/test/Bitcode/upgrade-module-flag.ll +++ b/test/Bitcode/upgrade-module-flag.ll @@ -1,9 +1,13 @@ ; RUN: llvm-as < %s | llvm-dis | FileCheck %s ; RUN: verify-uselistorder < %s -!llvm.module.flags = !{!0} +!llvm.module.flags = !{!0, !1, !2} -!0 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!0 = !{i32 1, !"PIC Level", i32 1} +!1 = !{i32 1, !"PIE Level", i32 1} +!2 = !{i32 1, !"Objective-C Image Info Version", i32 0} -; CHECK: !0 = !{i32 1, !"Objective-C Image Info Version", i32 0} -; CHECK: !1 = !{i32 4, !"Objective-C Class Properties", i32 0} +; CHECK: !0 = !{i32 7, !"PIC Level", i32 1} +; CHECK: !1 = !{i32 7, !"PIE Level", i32 1} +; CHECK: !2 = !{i32 1, !"Objective-C Image Info Version", i32 0} +; CHECK: !3 = !{i32 4, !"Objective-C Class Properties", i32 0} diff --git a/test/Linker/module-flags-pic-1-a.ll b/test/Linker/module-flags-pic-1-a.ll index ea933359ac6..9074aa6e593 100644 --- a/test/Linker/module-flags-pic-1-a.ll +++ b/test/Linker/module-flags-pic-1-a.ll @@ -2,8 +2,8 @@ ; test linking modules with specified and default PIC levels -!0 = !{ i32 1, !"PIC Level", i32 1 } +!0 = !{ i32 7, !"PIC Level", i32 1 } !llvm.module.flags = !{!0} ; CHECK: !llvm.module.flags = !{!0} -; CHECK: !0 = !{i32 1, !"PIC Level", i32 1} +; CHECK: !0 = !{i32 7, !"PIC Level", i32 1}