[clang] [llvm] [MTE] generalize overalignment / size of MTE globals (PR #121957)

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 21 17:07:54 PST 2025


https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/121957

>From 2feb85c15f64546cb6874e1ca0a1310bd1e1bedd Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Tue, 7 Jan 2025 07:57:09 -0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 llvm/include/llvm/IR/GlobalVariable.h      |  7 +++++
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 34 ++++++++++++++--------
 llvm/lib/IR/Globals.cpp                    | 10 +++++++
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h
index 83e484816d7d4..c1f8cdc4fd0a6 100644
--- a/llvm/include/llvm/IR/GlobalVariable.h
+++ b/llvm/include/llvm/IR/GlobalVariable.h
@@ -267,6 +267,13 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
            getAttributes().hasAttribute("rodata-section");
   }
 
+  MaybeAlign getRequiredGlobalAlignment() {
+    return isTagged() && getAlign().valueOrOne() < 16 ? MaybeAlign(16)
+                                                      : std::nullopt;
+  }
+
+  std::optional<uint64_t> getRequiredGlobalSize();
+
   /// Get the custom code model raw value of this global.
   ///
   unsigned getCodeModelRaw() const {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 7bd3fb33b47d2..8e594a8f92b20 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2398,17 +2398,23 @@ void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
   OutStreamer->emitBinaryData(Buf);
 }
 
-static void tagGlobalDefinition(Module &M, GlobalVariable *G) {
-  Constant *Initializer = G->getInitializer();
+static uint64_t globalSize(const GlobalVariable &G) {
+  const Constant *Initializer = G.getInitializer();
   uint64_t SizeInBytes =
-      M.getDataLayout().getTypeAllocSize(Initializer->getType());
+      G.getParent()->getDataLayout().getTypeAllocSize(Initializer->getType());
 
-  uint64_t NewSize = alignTo(SizeInBytes, 16);
-  if (SizeInBytes != NewSize) {
+  return SizeInBytes;
+}
+
+static void tagGlobalDefinition(GlobalVariable *G) {
+  Module &M = *G->getParent();
+  uint64_t SizeInBytes = globalSize(*G);
+  if (auto NewSize = G->getRequiredGlobalSize()) {
+    assert(*NewSize > SizeInBytes);
     // Pad the initializer out to the next multiple of 16 bytes.
-    llvm::SmallVector<uint8_t> Init(NewSize - SizeInBytes, 0);
+    llvm::SmallVector<uint8_t> Init(*NewSize - SizeInBytes, 0);
     Constant *Padding = ConstantDataArray::get(M.getContext(), Init);
-    Initializer = ConstantStruct::getAnon({Initializer, Padding});
+    auto *Initializer = ConstantStruct::getAnon({G->getInitializer(), Padding});
     auto *NewGV = new GlobalVariable(
         M, Initializer->getType(), G->isConstant(), G->getLinkage(),
         Initializer, "", G, G->getThreadLocalMode(), G->getAddressSpace());
@@ -2422,8 +2428,10 @@ static void tagGlobalDefinition(Module &M, GlobalVariable *G) {
     G = NewGV;
   }
 
-  if (G->getAlign().valueOrOne() < 16)
-    G->setAlignment(Align(16));
+  if (auto Align = G->getRequiredGlobalAlignment()) {
+    assert(*Align > G->getAlign().valueOrOne());
+    G->setAlignment(*Align);
+  }
 
   // Ensure that tagged globals don't get merged by ICF - as they should have
   // different tags at runtime.
@@ -2438,12 +2446,14 @@ bool AsmPrinter::doFinalization(Module &M) {
 
   std::vector<GlobalVariable *> GlobalsToTag;
   for (GlobalVariable &G : M.globals()) {
-    if (G.isDeclaration() || !G.isTagged())
+    if (G.isDeclaration())
       continue;
-    GlobalsToTag.push_back(&G);
+    if (G.getRequiredGlobalAlignment().has_value() ||
+        G.getRequiredGlobalSize().has_value())
+      GlobalsToTag.push_back(&G);
   }
   for (GlobalVariable *G : GlobalsToTag)
-    tagGlobalDefinition(M, G);
+    tagGlobalDefinition(G);
 
   // Gather all GOT equivalent globals in the module. We really need two
   // passes over the globals: one to compute and another to avoid its emission
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index db5e1cb57b1ba..79ff120c250e4 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -540,6 +540,16 @@ void GlobalVariable::setCodeModel(CodeModel::Model CM) {
   assert(getCodeModel() == CM && "Code model representation error!");
 }
 
+std::optional<uint64_t> GlobalVariable::getRequiredGlobalSize() {
+  if (!isTagged())
+    return std::nullopt;
+  Constant *Initializer = getInitializer();
+  uint64_t SizeInBytes =
+      getParent()->getDataLayout().getTypeAllocSize(Initializer->getType());
+  uint64_t Aligned = alignTo(SizeInBytes, 16);
+  return Aligned != SizeInBytes ? std::optional(Aligned) : std::nullopt;
+}
+
 //===----------------------------------------------------------------------===//
 // GlobalAlias Implementation
 //===----------------------------------------------------------------------===//

>From 64e954bafd4ecd7c9c3d968e5438f0780a1d4546 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Fri, 21 Feb 2025 17:07:36 -0800
Subject: [PATCH 2/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
 =?UTF-8?q?anges=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4

[skip ci]
---
 clang/test/CodeGen/memtag-globals-asm.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/clang/test/CodeGen/memtag-globals-asm.cpp b/clang/test/CodeGen/memtag-globals-asm.cpp
index 186045f8f2fb5..254624ec0b7bb 100644
--- a/clang/test/CodeGen/memtag-globals-asm.cpp
+++ b/clang/test/CodeGen/memtag-globals-asm.cpp
@@ -51,6 +51,7 @@
 // CHECK-A: .memtag global_int
 // CHECK-A: .globl global_int
 // CHECK-A: .p2align 4, 0x0
+// CHECK-A: .zero 16
 // CHECK-A: .size global_int, 16
 int global_int;
 // CHECK-B: .memtag _ZL9local_int
@@ -66,6 +67,7 @@ static char local_buffer[16];
 // CHECK-D: .p2align 4, 0x0
 // CHECK-D: _ZL22local_buffer_local_end:
 // CHECK-D: .xword _ZL12local_buffer+16
+// CHECK-D: .zero 8
 // CHECK-D: .size _ZL22local_buffer_local_end, 16
 static char* local_buffer_local_end = &local_buffer[16];
 // CHECK-E: .memtag local_buffer_global_end
@@ -73,6 +75,7 @@ static char* local_buffer_local_end = &local_buffer[16];
 // CHECK-E  .p2align 4, 0x0
 // CHECK-E: local_buffer_global_end:
 // CHECK-E: .xword _ZL12local_buffer+16
+// CHECK-E: .zero 8
 // CHECK-E: .size local_buffer_global_end, 16
 char* local_buffer_global_end = &local_buffer[16];
 
@@ -85,6 +88,7 @@ char global_buffer[16];
 // CHECK-G: .p2align 4, 0x0
 // CHECK-G: _ZL23global_buffer_local_end:
 // CHECK-G: .xword global_buffer+16
+// CHECK-G: .zero 8
 // CHECK-G: .size _ZL23global_buffer_local_end, 16
 static char* global_buffer_local_end = &global_buffer[16];
 // CHECK-H: .memtag global_buffer_global_end
@@ -104,6 +108,7 @@ class MyClass {
 // CHECK-I: .memtag _ZN7MyClass12my_class_intE
 // CHECK-I: .globl _ZN7MyClass12my_class_intE
 // CHECK-I: .p2align 4, 0x0
+// CHECK-I: .zero 16
 // CHECK-I: .size _ZN7MyClass12my_class_intE, 16
 int MyClass::my_class_int;
 // CHECK-NOT: .memtag _ZN7MyClass18my_class_const_intE
@@ -112,10 +117,12 @@ const int MyClass::my_class_const_int = 1;
 // CHECK-J: .memtag global_my_class
 // CHECK-J: .globl global_my_class
 // CHECK-J: .p2align 4, 0x0
+// CHECK-J: .zero 8
 // CHECK-J: .size global_my_class, 16
 MyClass global_my_class;
 // CHECK-K: .memtag _ZL14local_my_class
 // CHECK-K: .p2align 4, 0x0
+// CHECK-K: .zero 8
 // CHECK-K: .size _ZL14local_my_class, 16
 static MyClass local_my_class;
 
@@ -123,12 +130,14 @@ static MyClass local_my_class;
 static const char local_const_string[] = "this is a local string";
 // CHECK-L: .memtag _ZL12local_string
 // CHECK-L: .p2align 4, 0x0
+// CHECK-L: .zero 9
 // CHECK-L: .size _ZL12local_string, 32
 static char local_string[] = "this is a local string";
 
 // CHECK-M: .memtag global_atomic_int
 // CHECK-M: .globl global_atomic_int
 // CHECK-M: .p2align 4, 0x0
+// CHECK-M: .zero 16
 // CHECK-M: .size global_atomic_int, 16
 _Atomic(int) global_atomic_int;
 // CHECK-N: .memtag _ZL16local_atomic_int
@@ -144,6 +153,7 @@ union MyUnion {
 // CHECK-O: .memtag global_union
 // CHECK-O: .globl global_union
 // CHECK-O: .p2align 4, 0x0
+// CHECK-O: .zero 16
 // CHECK-O: .size global_union, 16
 MyUnion global_union;
 // CHECK-P: .memtag _ZL11local_union



More information about the llvm-commits mailing list