Index: include/llvm/IR/Module.h =================================================================== --- include/llvm/IR/Module.h +++ include/llvm/IR/Module.h @@ -139,9 +139,12 @@ /// 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 Index: lib/IR/Module.cpp =================================================================== --- lib/IR/Module.cpp +++ lib/IR/Module.cpp @@ -481,7 +481,7 @@ } 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 @@ } void Module::setPIELevel(PIELevel::Level PL) { - addModuleFlag(ModFlagBehavior::Error, "PIE Level", PL); + addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL); } void Module::setProfileSummary(Metadata *M) { Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1282,6 +1282,13 @@ // These behavior types accept any value. break; + case Module::Max: { + Assert(mdconst::dyn_extract_or_null(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. Index: lib/Linker/IRMover.cpp =================================================================== --- lib/Linker/IRMover.cpp +++ lib/Linker/IRMover.cpp @@ -1157,6 +1157,11 @@ mdconst::extract(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 @@ 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 @@ } continue; } + case Module::Max: { + ConstantInt *DstValue = + mdconst::extract(DstOp->getOperand(2)); + ConstantInt *SrcValue = + mdconst::extract(SrcOp->getOperand(2)); + if (SrcValue->getZExtValue() > DstValue->getZExtValue()) + overrideDstValue(); + break; + } case Module::Append: { MDNode *DstValue = cast(DstOp->getOperand(2)); MDNode *SrcValue = cast(SrcOp->getOperand(2)); Index: test/Linker/Inputs/module-flags-pic-2-b.ll =================================================================== --- test/Linker/Inputs/module-flags-pic-2-b.ll +++ 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} Index: test/Linker/module-flags-pic-2-a.ll =================================================================== --- test/Linker/module-flags-pic-2-a.ll +++ 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}