[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