diff options
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 5 | ||||
-rw-r--r-- | llvm/lib/IR/Module.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 17 | ||||
-rw-r--r-- | llvm/test/Linker/Inputs/module-flags-pic-2-b.ll | 5 | ||||
-rw-r--r-- | llvm/test/Linker/module-flags-pic-2-a.ll | 13 | ||||
-rw-r--r-- | llvm/test/Verifier/module-flags-1.ll | 6 |
7 files changed, 43 insertions, 14 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 3024d9e27a2..5e1f680c5b3 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -139,9 +139,12 @@ public: /// during the append operation. AppendUnique = 6, + /// Takes the max of the two values, which are required to be integers. + Max = 7, + // Markers: ModFlagBehaviorFirstVal = Error, - ModFlagBehaviorLastVal = AppendUnique + ModFlagBehaviorLastVal = Max }; /// Checks if Metadata represents a valid ModFlagBehavior, and stores the diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 12c258d95f5..95673e515a5 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -481,7 +481,7 @@ PICLevel::Level Module::getPICLevel() const { } void Module::setPICLevel(PICLevel::Level PL) { - addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL); + addModuleFlag(ModFlagBehavior::Max, "PIC Level", PL); } PIELevel::Level Module::getPIELevel() const { @@ -495,7 +495,7 @@ PIELevel::Level Module::getPIELevel() const { } void Module::setPIELevel(PIELevel::Level PL) { - addModuleFlag(ModFlagBehavior::Error, "PIE Level", PL); + addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL); } void Module::setProfileSummary(Metadata *M) { diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 21e8048442b..ffb9ad27922 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1282,6 +1282,13 @@ Verifier::visitModuleFlag(const MDNode *Op, // These behavior types accept any value. break; + case Module::Max: { + Assert(mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)), + "invalid value for 'max' module flag (expected constant integer)", + Op->getOperand(2)); + break; + } + case Module::Require: { // The value should itself be an MDNode with two operands, a flag ID (an // MDString), and a value. diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index c0af21aa148..defad190498 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1157,6 +1157,11 @@ Error IRLinker::linkModuleFlagsMetadata() { mdconst::extract<ConstantInt>(DstOp->getOperand(0)); unsigned DstBehaviorValue = DstBehavior->getZExtValue(); + auto overrideDstValue = [&]() { + DstModFlags->setOperand(DstIndex, SrcOp); + Flags[ID].first = SrcOp; + }; + // If either flag has override behavior, handle it first. if (DstBehaviorValue == Module::Override) { // Diagnose inconsistent flags which both have override behavior. @@ -1167,8 +1172,7 @@ Error IRLinker::linkModuleFlagsMetadata() { continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. - DstModFlags->setOperand(DstIndex, SrcOp); - Flags[ID].first = SrcOp; + overrideDstValue(); continue; } @@ -1204,6 +1208,15 @@ Error IRLinker::linkModuleFlagsMetadata() { } continue; } + case Module::Max: { + ConstantInt *DstValue = + mdconst::extract<ConstantInt>(DstOp->getOperand(2)); + ConstantInt *SrcValue = + mdconst::extract<ConstantInt>(SrcOp->getOperand(2)); + if (SrcValue->getZExtValue() > DstValue->getZExtValue()) + overrideDstValue(); + break; + } case Module::Append: { MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); diff --git a/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll b/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll index 0d78cafc6a0..f652eddb384 100644 --- a/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll +++ b/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll @@ -1,3 +1,4 @@ -!0 = !{ i32 1, !"PIC Level", i32 2 } +!0 = !{ i32 7, !"PIC Level", i32 2 } +!1 = !{ i32 7, !"PIE Level", i32 2 } -!llvm.module.flags = !{!0} +!llvm.module.flags = !{!0, !1} diff --git a/llvm/test/Linker/module-flags-pic-2-a.ll b/llvm/test/Linker/module-flags-pic-2-a.ll index e09af6bcd12..8898d72d510 100644 --- a/llvm/test/Linker/module-flags-pic-2-a.ll +++ b/llvm/test/Linker/module-flags-pic-2-a.ll @@ -1,10 +1,11 @@ -; RUN: not llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - 2> %t -; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s +; RUN: llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - | FileCheck %s -; test linking modules with two different PIC levels +; test linking modules with two different PIC and PIE levels -!0 = !{ i32 1, !"PIC Level", i32 1 } +!0 = !{ i32 7, !"PIC Level", i32 1 } +!1 = !{ i32 7, !"PIE Level", i32 1 } -!llvm.module.flags = !{!0} +!llvm.module.flags = !{!0, !1} -; CHECK-ERRORS: ERROR: linking module flags 'PIC Level': IDs have conflicting values +; CHECK: !0 = !{i32 7, !"PIC Level", i32 2} +; CHECK: !1 = !{i32 7, !"PIE Level", i32 2} diff --git a/llvm/test/Verifier/module-flags-1.ll b/llvm/test/Verifier/module-flags-1.ll index 36bcb335ffc..ff82c284523 100644 --- a/llvm/test/Verifier/module-flags-1.ll +++ b/llvm/test/Verifier/module-flags-1.ll @@ -41,6 +41,10 @@ ; CHECK-NOT: invalid value for 'append'-type module flag (expected a metadata node) !18 = !{i32 5, !"flag-4", !{i32 57}} +; Check that any 'max' module flags are valid. +; CHECK: invalid value for 'max' module flag (expected constant integer) +!19 = !{i32 7, !"max", !"max"} + ; Check that any 'require' module flags are valid. ; CHECK: invalid requirement on flag, flag is not present in module !11 = !{i32 3, !"bar", !{!"no-such-flag", i32 52}} @@ -54,4 +58,4 @@ !llvm.module.flags = !{ !0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, - !16, !17, !18 } + !16, !17, !18, !19 } |