[PATCH] D121970: [Verify] check that BlockAddresses don't refer to functions with certain linkages which wont be emitted

Nick Desaulniers via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 17 15:37:17 PDT 2022


nickdesaulniers created this revision.
nickdesaulniers added reviewers: dexonsmith, efriedma, jyknight.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nickdesaulniers requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

In D120781 <https://reviews.llvm.org/D120781>, there's discussion that various linkages can cause the
definitions of functions to not be emitted, or replaced. In those cases,
what does it mean to take the address of a block?

For a function with available_externally linkage, it obviously doesn't
make sense (as the function definition will not be emitted).

Check the users of each blockaddress; permit the above linkage if the
usage is local to the function.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121970

Files:
  llvm/lib/IR/Verifier.cpp


Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -459,6 +459,7 @@
   void visitModuleFlagCGProfileEntry(const MDOperand &MDO);
   void visitFunction(const Function &F);
   void visitBasicBlock(BasicBlock &BB);
+  void visitBlockAddress(const BlockAddress &BA);
   void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
   void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
   void visitProfMetadata(Instruction &I, MDNode *MD);
@@ -2729,8 +2730,31 @@
 
   // Check that all instructions have their parent pointers set up correctly.
   for (auto &I : BB)
-  {
     Assert(I.getParent() == &BB, "Instruction has bogus parent pointer!");
+
+  if (BlockAddress *BA = BlockAddress::lookup(&BB))
+    visitBlockAddress(*BA);
+}
+
+void Verifier::visitBlockAddress(const BlockAddress &BA) {
+  // Check the users of this BA.
+  Function *F = BA.getFunction();
+  // TODO: what about other linkages? isIterposableLinkage? isWeakForLinker?
+  if (!F->hasAvailableExternallyLinkage())
+    return;
+
+  // maybe use a set, too?
+  SmallVector<const User *, 4> Worklist(BA.user_begin(), BA.user_end());
+  while (!Worklist.empty()) {
+    const User *U = Worklist.pop_back_val();
+
+    Assert(!isa<GlobalValue>(U),
+           "BlockAddress refers to BasicBlock that will not be emitted");
+    if (isa<ConstantExpr>(U))
+      Worklist.append(U->user_begin(), U->user_end());
+    if (auto *I = dyn_cast<Instruction>(U))
+      Assert(I->getParent()->getParent() == F,
+             "BlockAddress refers to BasicBlock that will not be emitted");
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121970.416349.patch
Type: text/x-patch
Size: 1682 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220317/9733a2b3/attachment.bin>


More information about the llvm-commits mailing list