[llvm] 8af5ec6 - [AutoUpgrade] Upgrade old-style !tbaa.struct field tags (#225967)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 14:15:35 PDT 2026
Author: Abhay Kanhere
Date: 2026-09-25T14:15:28-07:00
New Revision: 8af5ec67c2001eb379d53cc61ccce0ca521a6c3c
URL: https://github.com/llvm/llvm-project/commit/8af5ec67c2001eb379d53cc61ccce0ca521a6c3c
DIFF: https://github.com/llvm/llvm-project/commit/8af5ec67c2001eb379d53cc61ccce0ca521a6c3c.diff
LOG: [AutoUpgrade] Upgrade old-style !tbaa.struct field tags (#225967)
Extend the TBAA auto-upgrade to rewrite old-style scalar field tags
inside !tbaa.struct
to the struct-path aware format. bitcode (MetadataLoader) upgraded to
match the existing top-level !tbaa upgrade.
Added:
llvm/test/Bitcode/upgrade-tbaa-struct.ll
llvm/test/Bitcode/upgrade-tbaa-struct.ll.bc
Modified:
llvm/include/llvm/IR/AutoUpgrade.h
llvm/lib/Bitcode/Reader/MetadataLoader.cpp
llvm/lib/IR/AutoUpgrade.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h
index 53da20d63a7f1..b129994885b2d 100644
--- a/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/llvm/include/llvm/IR/AutoUpgrade.h
@@ -85,6 +85,11 @@ namespace llvm {
/// Otherwise return the \p TBAANode itself.
LLVM_ABI MDNode *UpgradeTBAANode(MDNode &TBAANode);
+ /// If the given !tbaa.struct node has old-style scalar field tags, return an
+ /// equivalent node with each field tag upgraded to the struct-path aware
+ /// format. Otherwise return the node itself.
+ LLVM_ABI MDNode *UpgradeTBAAStructNode(MDNode &TBAAStructNode);
+
/// This is an auto-upgrade for bitcast between pointers with
diff erent
/// address spaces: the instruction is replaced by a pair ptrtoint+inttoptr.
LLVM_ABI Instruction *UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 6f1fbd627edbc..80e44634d6f95 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -2647,6 +2647,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment(
if (I->second == LLVMContext::MD_tbaa) {
assert(!MD->isTemporary() && "should load MDs before attachments");
MD = UpgradeTBAANode(*MD);
+ } else if (I->second == LLVMContext::MD_tbaa_struct) {
+ assert(!MD->isTemporary() && "should load MDs before attachments");
+ MD = UpgradeTBAAStructNode(*MD);
}
Inst->setMetadata(I->second, MD);
}
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index cb0e0690a261f..42f456e82f387 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -6670,6 +6670,28 @@ MDNode *llvm::UpgradeTBAANode(MDNode &MD) {
return MDNode::get(Context, Elts);
}
+MDNode *llvm::UpgradeTBAAStructNode(MDNode &MD) {
+ // !tbaa.struct is a list of (offset, size, tag) triples. Upgrade any
+ // old-style scalar field tag to struct-path form via UpgradeTBAANode.
+ unsigned NumOperands = MD.getNumOperands();
+ if (NumOperands == 0 || NumOperands % 3 != 0)
+ return &MD; // Malformed; leave it for the verifier to reject.
+
+ SmallVector<Metadata *, 12> Elts(MD.op_begin(), MD.op_end());
+ bool Changed = false;
+ for (unsigned I = 2; I < NumOperands; I += 3) {
+ auto *Tag = dyn_cast_or_null<MDNode>(Elts[I]);
+ if (!Tag)
+ continue;
+ MDNode *Upgraded = UpgradeTBAANode(*Tag);
+ if (Upgraded == Tag)
+ continue;
+ Elts[I] = Upgraded;
+ Changed = true;
+ }
+ return Changed ? MDNode::get(MD.getContext(), Elts) : &MD;
+}
+
Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
Instruction *&Temp) {
if (Opc != Instruction::BitCast)
diff --git a/llvm/test/Bitcode/upgrade-tbaa-struct.ll b/llvm/test/Bitcode/upgrade-tbaa-struct.ll
new file mode 100644
index 0000000000000..d3c71ab22a1e4
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-tbaa-struct.ll
@@ -0,0 +1,68 @@
+; RUN: llvm-dis < %s.bc | FileCheck %s
+; RUN: verify-uselistorder < %s.bc
+; Test that old-style scalar tags used as !tbaa.struct field tags in older
+; bitcode are auto-upgraded to the struct-path aware format on load, whatever
+; instruction carries the !tbaa.struct. Null and already struct-path field
+; tags are left unchanged; an immutability flag is kept.
+;
+
+define void @copy_memcpy(ptr %a, ptr %b) {
+; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct [[TS:![0-9]+]]
+ call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct !0
+ ret void
+}
+
+define void @copy_memmove(ptr %a, ptr %b) {
+; CHECK: call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct [[TS]]
+ call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct !0
+ ret void
+}
+
+define i32 @access_load_store(ptr %p) {
+; CHECK: %v = load i32, ptr %p, align 4, !tbaa.struct [[TS]]
+; CHECK: store i32 %v, ptr %p, align 4, !tbaa.struct [[TS]]
+ %v = load i32, ptr %p, align 4, !tbaa.struct !0
+ store i32 %v, ptr %p, align 4, !tbaa.struct !0
+ ret i32 %v
+}
+
+define i32 @access_atomicrmw(ptr %p, i32 %v) {
+; CHECK: %r = atomicrmw add ptr %p, i32 %v seq_cst, align 4, !tbaa.struct [[TS]]
+ %r = atomicrmw add ptr %p, i32 %v seq_cst, align 4, !tbaa.struct !0
+ ret i32 %r
+}
+
+define void @copy_flag_and_structpath(ptr %a, ptr %b) {
+; CHECK: call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 8, i1 false), !tbaa.struct [[TS2:![0-9]+]]
+ call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 8, i1 false), !tbaa.struct !5
+ ret void
+}
+
+declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
+declare void @llvm.memmove.p0.p0.i64(ptr, ptr, i64, i1)
+
+; Old-style 2-operand scalar field tags and a null field tag.
+!0 = !{i64 0, i64 4, !1, i64 4, i64 4, !3, i64 8, i64 4, null}
+!1 = !{!"int", !2}
+!2 = !{!"omnipotent char", !4}
+!3 = !{!"float", !2}
+!4 = !{!"Simple C/C++ TBAA"}
+
+; Old-style 3-operand (immutable) field tag and an already struct-path field tag.
+!5 = !{i64 0, i64 4, !6, i64 4, i64 4, !7}
+!6 = !{!"const int", !2, i64 1}
+!7 = !{!8, !8, i64 0}
+!8 = !{!"double", !2}
+
+; CHECK: [[TS]] = !{i64 0, i64 4, [[TAG_INT:![0-9]+]], i64 4, i64 4, [[TAG_FLOAT:![0-9]+]], i64 8, i64 4, null}
+; CHECK: [[TAG_INT]] = !{[[TYPE_INT:![0-9]+]], [[TYPE_INT]], i64 0}
+; CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR:![0-9]+]]}
+; CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", !{{[0-9]+}}}
+; CHECK: [[TAG_FLOAT]] = !{[[TYPE_FLOAT:![0-9]+]], [[TYPE_FLOAT]], i64 0}
+; CHECK: [[TYPE_FLOAT]] = !{!"float", [[TYPE_CHAR]]}
+; The immutability flag (i64 1) is preserved; the already struct-path tag is unchanged.
+; CHECK: [[TS2]] = !{i64 0, i64 4, [[TAG_CONST:![0-9]+]], i64 4, i64 4, [[TAG_DOUBLE:![0-9]+]]}
+; CHECK: [[TAG_CONST]] = !{[[TYPE_CONST:![0-9]+]], [[TYPE_CONST]], i64 0, i64 1}
+; CHECK: [[TYPE_CONST]] = !{!"const int", [[TYPE_CHAR]]}
+; CHECK: [[TAG_DOUBLE]] = !{[[TYPE_DOUBLE:![0-9]+]], [[TYPE_DOUBLE]], i64 0}
+; CHECK: [[TYPE_DOUBLE]] = !{!"double", [[TYPE_CHAR]]}
diff --git a/llvm/test/Bitcode/upgrade-tbaa-struct.ll.bc b/llvm/test/Bitcode/upgrade-tbaa-struct.ll.bc
new file mode 100644
index 0000000000000..0b85cec94aa1b
Binary files /dev/null and b/llvm/test/Bitcode/upgrade-tbaa-struct.ll.bc
diff er
More information about the llvm-commits
mailing list