[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