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

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 7 07:57:25 PST 2025


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

This was requested in https://github.com/llvm/llvm-project/pull/111918


>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] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=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 83e484816d7d4c..c1f8cdc4fd0a65 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 7bd3fb33b47d2b..8e594a8f92b204 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 db5e1cb57b1bab..79ff120c250e40 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
 //===----------------------------------------------------------------------===//



More information about the llvm-commits mailing list