[llvm] [Verifier] Validate !tbaa.struct metadata (PR #225910)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 12:50:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Abhay Kanhere (AbhayKanhere)

<details>
<summary>Changes</summary>

Check that !tbaa.struct operands come in (offset, size, tag) triples with constant offset and size.

---
Full diff: https://github.com/llvm/llvm-project/pull/225910.diff


3 Files Affected:

- (modified) llvm/include/llvm/IR/Verifier.h (+1) 
- (modified) llvm/lib/IR/Verifier.cpp (+23) 
- (modified) llvm/test/Verifier/tbaa-struct.ll (+6-2) 


``````````diff
diff --git a/llvm/include/llvm/IR/Verifier.h b/llvm/include/llvm/IR/Verifier.h
index 80e9b9284c9b7..9fa37cfae1974 100644
--- a/llvm/include/llvm/IR/Verifier.h
+++ b/llvm/include/llvm/IR/Verifier.h
@@ -79,6 +79,7 @@ class TBAAVerifier {
   /// Visit an instruction, or a TBAA node itself as part of a metadata, and
   /// return true if it is valid, return false if an invalid TBAA is attached.
   LLVM_ABI bool visitTBAAMetadata(const Instruction *I, const MDNode *MD);
+  LLVM_ABI bool visitTBAAStructMetadata(const Instruction *I, const MDNode *MD);
 };
 
 /// Check a function for errors, useful for use when debugging a
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 1440b95896474..d9852a34646c7 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6062,6 +6062,9 @@ void Verifier::visitInstruction(Instruction &I) {
   if (MDNode *TBAA = I.getMetadata(LLVMContext::MD_tbaa))
     TBAAVerifyHelper.visitTBAAMetadata(&I, TBAA);
 
+  if (MDNode *TBAAStruct = I.getMetadata(LLVMContext::MD_tbaa_struct))
+    TBAAVerifyHelper.visitTBAAStructMetadata(&I, TBAAStruct);
+
   if (MDNode *MD = I.getMetadata(LLVMContext::MD_noalias))
     visitAliasScopeListMetadata(MD);
   if (MDNode *MD = I.getMetadata(LLVMContext::MD_alias_scope))
@@ -8348,6 +8351,26 @@ bool TBAAVerifier::visitTBAAMetadata(const Instruction *I, const MDNode *MD) {
   return true;
 }
 
+bool TBAAVerifier::visitTBAAStructMetadata(const Instruction *I,
+                                           const MDNode *MD) {
+  // !tbaa.struct is a list of (offset, size, tag) triples. Offset and size
+  // must be constants; a non-null tag must be a valid access tag.
+  CheckTBAA(MD->getNumOperands() % 3 == 0,
+            "!tbaa.struct operands must come in groups of three", I, MD);
+
+  for (unsigned Idx = 0, E = MD->getNumOperands(); Idx != E; Idx += 3) {
+    CheckTBAA(mdconst::dyn_extract_or_null<ConstantInt>(MD->getOperand(Idx)),
+              "!tbaa.struct field offset must be a constant integer", I, MD);
+    CheckTBAA(
+        mdconst::dyn_extract_or_null<ConstantInt>(MD->getOperand(Idx + 1)),
+        "!tbaa.struct field size must be a constant integer", I, MD);
+    if (auto *Tag = dyn_cast_or_null<MDNode>(MD->getOperand(Idx + 2)))
+      if (!visitTBAAMetadata(I, Tag))
+        return false;
+  }
+  return true;
+}
+
 char VerifierLegacyPass::ID = 0;
 INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)
 
diff --git a/llvm/test/Verifier/tbaa-struct.ll b/llvm/test/Verifier/tbaa-struct.ll
index b8ddc7cee496a..9058daaa398b1 100644
--- a/llvm/test/Verifier/tbaa-struct.ll
+++ b/llvm/test/Verifier/tbaa-struct.ll
@@ -1,6 +1,7 @@
-; RUN: llvm-as < %s 2>&1
+; RUN: not llvm-as -disable-output < %s 2>&1 | FileCheck %s
 
-; FIXME: The verifer should reject the invalid !tbaa.struct nodes below.
+; FIXME: The verifier does not yet reject the overlapping-region (@test_overlapping_regions)
+; or null-tag (@test_tbaa_missing) nodes below.
 
 define void @test_overlapping_regions(ptr %a1) {
   %ld = load i8, ptr %a1, align 1, !tbaa.struct !0
@@ -8,11 +9,13 @@ define void @test_overlapping_regions(ptr %a1) {
 }
 
 define void @test_size_not_integer(ptr %a1) {
+; CHECK-DAG: !tbaa.struct field size must be a constant integer
   store i8 1, ptr %a1, align 1, !tbaa.struct !5
   ret void
 }
 
 define void @test_offset_not_integer(ptr %a1, ptr %a2) {
+; CHECK-DAG: !tbaa.struct field offset must be a constant integer
   tail call void @llvm.memcpy.p0.p0.i64(ptr align 8 %a1, ptr align 8 %a2, i64 16, i1 false), !tbaa.struct !6
   ret void
 }
@@ -23,6 +26,7 @@ define void @test_tbaa_missing(ptr %a1, ptr %a2) {
 }
 
 define void @test_tbaa_invalid(ptr %a1) {
+; CHECK-DAG: Old-style TBAA is no longer allowed
   store i8 1, ptr %a1, align 1, !tbaa.struct !8
   ret void
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/225910


More information about the llvm-commits mailing list