summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Module.h5
-rw-r--r--llvm/lib/IR/Module.cpp4
-rw-r--r--llvm/lib/IR/Verifier.cpp7
-rw-r--r--llvm/lib/Linker/IRMover.cpp17
-rw-r--r--llvm/test/Linker/Inputs/module-flags-pic-2-b.ll5
-rw-r--r--llvm/test/Linker/module-flags-pic-2-a.ll13
-rw-r--r--llvm/test/Verifier/module-flags-1.ll6
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 }
OpenPOWER on IntegriCloud