[llvm-commits] [llvm] r172549 - in /llvm/trunk: lib/IR/Verifier.cpp test/Verifier/module-flags-1.ll

Daniel Dunbar daniel at zuster.org
Tue Jan 15 12:52:06 PST 2013


Author: ddunbar
Date: Tue Jan 15 14:52:06 2013
New Revision: 172549

URL: http://llvm.org/viewvc/llvm-project?rev=172549&view=rev
Log:
[IR] Add verification for module flags with the "require" behavior.

Modified:
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/Verifier/module-flags-1.ll

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=172549&r1=172548&r2=172549&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Jan 15 14:52:06 2013
@@ -243,7 +243,8 @@
     void visitNamedMDNode(NamedMDNode &NMD);
     void visitMDNode(MDNode &MD, Function *F);
     void visitModuleFlags(Module &M);
-    void visitModuleFlag(MDNode *Op, SmallSetVector<MDString*, 16> &SeenIDs);
+    void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs,
+                         SmallVectorImpl<MDNode*> &Requirements);
     void visitFunction(Function &F);
     void visitBasicBlock(BasicBlock &BB);
     using InstVisitor<Verifier>::visit;
@@ -529,15 +530,37 @@
   const NamedMDNode *Flags = M.getModuleFlagsMetadata();
   if (!Flags) return;
 
-  // Scan each flag.
-  SmallSetVector<MDString*, 16> SeenIDs;
+  // Scan each flag, and track the flags and requirements.
+  DenseMap<MDString*, MDNode*> SeenIDs;
+  SmallVector<MDNode*, 16> Requirements;
   for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) {
-    visitModuleFlag(Flags->getOperand(I), SeenIDs);
+    visitModuleFlag(Flags->getOperand(I), SeenIDs, Requirements);
+  }
+
+  // Validate that the requirements in the module are valid.
+  for (unsigned I = 0, E = Requirements.size(); I != E; ++I) {
+    MDNode *Requirement = Requirements[I];
+    MDString *Flag = cast<MDString>(Requirement->getOperand(0));
+    Value *ReqValue = Requirement->getOperand(1);
+
+    MDNode *Op = SeenIDs.lookup(Flag);
+    if (!Op) {
+      CheckFailed("invalid requirement on flag, flag is not present in module",
+                  Flag);
+      continue;
+    }
+
+    if (Op->getOperand(2) != ReqValue) {
+      CheckFailed(("invalid requirement on flag, "
+                   "flag does not have the required value"),
+                  Flag);
+      continue;
+    }
   }
 }
 
-void Verifier::visitModuleFlag(MDNode *Op, 
-                               SmallSetVector<MDString*, 16> &SeenIDs) {
+void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs,
+                               SmallVectorImpl<MDNode*> &Requirements) {
   // Each module flag should have three arguments, the merge behavior (a
   // constant int), the flag ID (an MDString), and the value.
   Assert1(Op->getNumOperands() == 3,
@@ -558,7 +581,8 @@
 
   // Unless this is a "requires" flag, check the ID is unique.
   if (BehaviorValue != Module::Require) {
-    Assert1(SeenIDs.insert(ID),
+    bool Inserted = SeenIDs.insert(std::make_pair(ID, Op)).second;
+    Assert1(Inserted,
             "module flag identifiers must be unique (or of 'require' type)",
             ID);
   }
@@ -575,6 +599,10 @@
             ("invalid value for 'require' module flag "
              "(first value operand should be a string)"),
             Value->getOperand(0));
+
+    // Append it to the list of requirements, to check once all module flags are
+    // scanned.
+    Requirements.push_back(Value);
   }
 }
 

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=172549&r1=172548&r2=172549&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/module-flags-1.ll (original)
+++ llvm/trunk/test/Verifier/module-flags-1.ll Tue Jan 15 14:52:06 2013
@@ -31,7 +31,21 @@
 !8 = metadata !{ i32 2, metadata !"foo", i32 50 }
 ; CHECK-NOT: module flag identifiers must be unique
 !9 = metadata !{ i32 2, metadata !"bar", i32 51 }
-!10 = metadata !{ i32 3, metadata !"bar", i32 51 }
+!10 = metadata !{ i32 3, metadata !"bar", metadata !{ metadata !"bar", i32 51 } }
+
+; Check that any 'require' module flags are valid.
+; CHECK: invalid requirement on flag, flag is not present in module
+!11 = metadata !{ i32 3, metadata !"bar",
+     metadata !{ metadata !"no-such-flag", i32 52 } }
+; CHECK: invalid requirement on flag, flag does not have the required value
+!12 = metadata !{ i32 1, metadata !"flag-0", i32 53 }
+!13 = metadata !{ i32 3, metadata !"bar",
+     metadata !{ metadata !"flag-0", i32 54 } }
+; CHECK-NOT: invalid requirement on flag, flag is not present in module
+; CHECK-NOT: invalid requirement on flag, flag does not have the required value
+!14 = metadata !{ i32 1, metadata !"flag-1", i32 55 }
+!15 = metadata !{ i32 3, metadata !"bar",
+     metadata !{ metadata !"flag-1", i32 55 } }
 
 !llvm.module.flags = !{
-  !0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10 }
+  !0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15 }





More information about the llvm-commits mailing list