[llvm] Infer alignment for memory intrinsics (PR #217172)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 17:09:00 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: SomeFlyingThing

<details>
<summary>Changes</summary>

Extends InferAlignment to infer and strengthen source/destination alignment on memcpy, memmove, memset, and related memory intrinsics.

This changes were assisted by an LLM

---
Full diff: https://github.com/llvm/llvm-project/pull/217172.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/InferAlignment.cpp (+22) 
- (added) llvm/test/Transforms/InferAlignment/memintrinsics.ll (+31) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index 92f23eaccd673..908d92be7c16e 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -69,6 +69,28 @@ static bool tryToImproveAlign(
   if (!II)
     return false;
 
+  if (auto *MI = dyn_cast<MemIntrinsic>(II)) {
+    bool Changed = false;
+
+    Align OldDestAlign = MI->getDestAlign().valueOrOne();
+    Align NewDestAlign = Fn(MI->getRawDest(), OldDestAlign, Align(1));
+    if (NewDestAlign > OldDestAlign) {
+      MI->setDestAlignment(NewDestAlign);
+      Changed = true;
+    }
+
+    if (auto *MTI = dyn_cast<MemTransferInst>(MI)) {
+      Align OldSourceAlign = MTI->getSourceAlign().valueOrOne();
+      Align NewSourceAlign = Fn(MTI->getRawSource(), OldSourceAlign, Align(1));
+      if (NewSourceAlign > OldSourceAlign) {
+        MTI->setSourceAlignment(NewSourceAlign);
+        Changed = true;
+      }
+    }
+
+    return Changed;
+  }
+
   // TODO: Handle more memory intrinsics.
   switch (II->getIntrinsicID()) {
   case Intrinsic::masked_load:
diff --git a/llvm/test/Transforms/InferAlignment/memintrinsics.ll b/llvm/test/Transforms/InferAlignment/memintrinsics.ll
new file mode 100644
index 0000000000000..4354f1d4a72af
--- /dev/null
+++ b/llvm/test/Transforms/InferAlignment/memintrinsics.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s
+
+declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
+declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
+declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
+
+define void @memcpy(i64 %len) {
+; CHECK-LABEL: define void @memcpy(
+; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 32 %dst, ptr align 16 %src, i64 %len, i1 false)
+  %dst = alloca [64 x i8], align 32
+  %src = alloca [64 x i8], align 16
+  call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
+  ret void
+}
+
+define void @memmove(i64 %len) {
+; CHECK-LABEL: define void @memmove(
+; CHECK: call void @llvm.memmove.p0.p0.i64(ptr align 64 %dst, ptr align 8 %src, i64 %len, i1 false)
+  %dst = alloca [64 x i8], align 64
+  %src = alloca [64 x i8], align 8
+  call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
+  ret void
+}
+
+define void @memset(i64 %len) {
+; CHECK-LABEL: define void @memset(
+; CHECK: call void @llvm.memset.p0.i64(ptr align 32 %dst, i8 0, i64 %len, i1 false)
+  %dst = alloca [64 x i8], align 32
+  call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 %len, i1 false)
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/217172


More information about the llvm-commits mailing list