[llvm] r303590 - Support for taking the max of module flags when linking, use for PIE/PIC

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Mon May 22 17:08:01 PDT 2017


Author: tejohnson
Date: Mon May 22 19:08:00 2017
New Revision: 303590

URL: http://llvm.org/viewvc/llvm-project?rev=303590&view=rev
Log:
Support for taking the max of module flags when linking, use for PIE/PIC

Summary:
Add Max ModFlagBehavior, which can be used to take the max of two
module flag values when merging modules. Use it for the PIE and PIC
levels.

This avoids an error when we try to import from a module built -fpic
into a module built -fPIC, for example. For both PIE and PIC levels,
this will be legal, since the code generation gets more conservative
as the level is increased. Therefore we can take the max instead of
somehow trying to block importing between modules compiled with
different levels.

Reviewers: tmsriram, pcc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D33418

Modified:
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Linker/IRMover.cpp
    llvm/trunk/test/Linker/Inputs/module-flags-pic-2-b.ll
    llvm/trunk/test/Linker/module-flags-pic-2-a.ll
    llvm/trunk/test/Verifier/module-flags-1.ll

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Mon May 22 19:08:00 2017
@@ -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

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Mon May 22 19:08:00 2017
@@ -481,7 +481,7 @@ PICLevel::Level Module::getPICLevel() co
 }
 
 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() co
 }
 
 void Module::setPIELevel(PIELevel::Level PL) {
-  addModuleFlag(ModFlagBehavior::Error, "PIE Level", PL);
+  addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL);
 }
 
 void Module::setProfileSummary(Metadata *M) {

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon May 22 19:08:00 2017
@@ -1282,6 +1282,13 @@ Verifier::visitModuleFlag(const MDNode *
     // 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.

Modified: llvm/trunk/lib/Linker/IRMover.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/IRMover.cpp (original)
+++ llvm/trunk/lib/Linker/IRMover.cpp Mon May 22 19:08:00 2017
@@ -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));

Modified: llvm/trunk/test/Linker/Inputs/module-flags-pic-2-b.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/module-flags-pic-2-b.ll?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/test/Linker/Inputs/module-flags-pic-2-b.ll (original)
+++ llvm/trunk/test/Linker/Inputs/module-flags-pic-2-b.ll Mon May 22 19:08:00 2017
@@ -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}

Modified: llvm/trunk/test/Linker/module-flags-pic-2-a.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/module-flags-pic-2-a.ll?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/test/Linker/module-flags-pic-2-a.ll (original)
+++ llvm/trunk/test/Linker/module-flags-pic-2-a.ll Mon May 22 19:08:00 2017
@@ -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}

Modified: llvm/trunk/test/Verifier/module-flags-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/module-flags-1.ll?rev=303590&r1=303589&r2=303590&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/module-flags-1.ll (original)
+++ llvm/trunk/test/Verifier/module-flags-1.ll Mon May 22 19:08:00 2017
@@ -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 }




More information about the llvm-commits mailing list