[clang] [llvm] Global string alignment (PR #142346)

Dominik Steenken via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 5 07:52:04 PDT 2025


https://github.com/dominik-steenken updated https://github.com/llvm/llvm-project/pull/142346

>From ff817c7a1b79596712d24b7cfac9212edcef9280 Mon Sep 17 00:00:00 2001
From: Dominik Steenken <dost at de.ibm.com>
Date: Mon, 26 May 2025 14:53:41 +0200
Subject: [PATCH 1/3] Align global strings according to data layout

When creating global strings, some targets have requirements that need to
be taken into account. Previously, the global strings created by
`IRBuilder::createGlobalString` had a hard-coded alignment of `1`.

This commit makes it so that the alignment is taken from the data layout
instead, giving targets the chance to align global strings according to
their preferences.
---
 llvm/lib/IR/IRBuilder.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 580b0af709337..ab06a587a861f 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -52,7 +52,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
       *M, StrConstant->getType(), true, GlobalValue::PrivateLinkage,
       StrConstant, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace);
   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
-  GV->setAlignment(Align(1));
+  GV->setAlignment(M->getDataLayout().getPreferredAlign(GV));
   return GV;
 }
 

>From b48d7b108150d154bb15b83a96f6b26dbe9f100c Mon Sep 17 00:00:00 2001
From: Dominik Steenken <dost at de.ibm.com>
Date: Fri, 30 May 2025 15:01:45 +0200
Subject: [PATCH 2/3] [SystemZ] Add codegen test for global string alignment

This commit adds a test to the `clang` test suite for the SystemZ backend
that checks for the correct alignment of global strings created by the
PrintFOptimizer for the case `printf("foo\n")` -> `puts("foo")`.
---
 .../CodeGen/SystemZ/align-systemz-globalstring.c   | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 clang/test/CodeGen/SystemZ/align-systemz-globalstring.c

diff --git a/clang/test/CodeGen/SystemZ/align-systemz-globalstring.c b/clang/test/CodeGen/SystemZ/align-systemz-globalstring.c
new file mode 100644
index 0000000000000..f5178a079f898
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/align-systemz-globalstring.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -O1 -triple s390x-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+// #include <stdio.h>
+
+// CHECK: @msg1 = local_unnamed_addr constant [13 x i8] c"Hello World\0A\00", align 2
+// CHECK: @str = private unnamed_addr constant [12 x i8] c"Hello World\00", align 2
+
+const char msg1 [] = "Hello World\n";
+
+extern int printf(const char *__restrict __format, ...);
+
+void foo() {
+    printf(msg1);
+}
\ No newline at end of file

>From 97f3c2031e0898b005381fe603cdfab6ca5ce3cd Mon Sep 17 00:00:00 2001
From: Dominik Steenken <dost at de.ibm.com>
Date: Thu, 5 Jun 2025 16:18:37 +0200
Subject: [PATCH 3/3] Copy Attributes for derived global strings from existing
 ones

---
 llvm/lib/IR/IRBuilder.cpp                     |  2 +-
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 21 +++++++++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index ab06a587a861f..580b0af709337 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -52,7 +52,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
       *M, StrConstant->getType(), true, GlobalValue::PrivateLinkage,
       StrConstant, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace);
   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
-  GV->setAlignment(M->getDataLayout().getPreferredAlign(GV));
+  GV->setAlignment(Align(1));
   return GV;
 }
 
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 94a79ad824370..6df54fd1d3831 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -24,6 +24,7 @@
 #include "llvm/IR/AttributeMask.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
@@ -3323,8 +3324,14 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilderBase &B) {
     // printf("%s", str"\n") --> puts(str)
     if (OperandStr.back() == '\n') {
       OperandStr = OperandStr.drop_back();
-      Value *GV = B.CreateGlobalString(OperandStr, "str");
-      return copyFlags(*CI, emitPutS(GV, B, TLI));
+      // Because we were able to derive OperandStr, we know it's safe to cast to
+      // GlobalVariable*.
+      GlobalVariable *OldStr =
+          dyn_cast<GlobalVariable>(getUnderlyingObject(CI->getArgOperand(1)));
+      GlobalVariable *NewStr = B.CreateGlobalString(
+          OperandStr, Twine(OldStr->getName(), ".clipped"));
+      NewStr->copyAttributesFrom(OldStr);
+      return copyFlags(*CI, emitPutS(NewStr, B, TLI));
     }
     return nullptr;
   }
@@ -3335,8 +3342,14 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilderBase &B) {
     // Create a string literal with no \n on it.  We expect the constant merge
     // pass to be run after this pass, to merge duplicate strings.
     FormatStr = FormatStr.drop_back();
-    Value *GV = B.CreateGlobalString(FormatStr, "str");
-    return copyFlags(*CI, emitPutS(GV, B, TLI));
+    // Because we were able to derive FormatStr, we know it's safe to cast to
+    // GlobalVariable*.
+    GlobalVariable *OldStr =
+        dyn_cast<GlobalVariable>(getUnderlyingObject(CI->getArgOperand(0)));
+    GlobalVariable *NewStr =
+        B.CreateGlobalString(FormatStr, Twine(OldStr->getName(), ".clipped"));
+    NewStr->copyAttributesFrom(OldStr);
+    return copyFlags(*CI, emitPutS(NewStr, B, TLI));
   }
 
   // Optimize specific format strings.



More information about the llvm-commits mailing list