[llvm] [PassBuilder] Run MemCpyOpt before early SROA (PR #210875)

Rick Guo via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 21 04:42:21 PDT 2026


https://github.com/MeteorsLiu updated https://github.com/llvm/llvm-project/pull/210875

>From b2d364989bf10053a9d0f52756a95a40a9ca308c Mon Sep 17 00:00:00 2001
From: Rick Guo <hello at liuxi.ng>
Date: Tue, 21 Jul 2026 13:07:00 +0800
Subject: [PATCH] [PassBuilder] Run MemCpyOpt before early SROA

---
 llvm/lib/Passes/PassBuilderPipelines.cpp |  3 +++
 llvm/test/Other/pre-sroa-memcpyopt.ll    | 33 ++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 llvm/test/Other/pre-sroa-memcpyopt.ll

diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index d62828c78bfe4..fbdbde8b78b7e 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1173,6 +1173,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
     // SimplifyCFG.
     EarlyFPM.addPass(LowerExpectIntrinsicPass());
     EarlyFPM.addPass(SimplifyCFGPass());
+    // Canonicalize aggregate load/store pairs before SROA can split them into
+    // individual scalar accesses.
+    EarlyFPM.addPass(MemCpyOptPass());
     EarlyFPM.addPass(SROAPass(SROAOptions::ModifyCFG));
     EarlyFPM.addPass(EarlyCSEPass());
     if (Level == OptimizationLevel::O3)
diff --git a/llvm/test/Other/pre-sroa-memcpyopt.ll b/llvm/test/Other/pre-sroa-memcpyopt.ll
new file mode 100644
index 0000000000000..8833833c2593c
--- /dev/null
+++ b/llvm/test/Other/pre-sroa-memcpyopt.ll
@@ -0,0 +1,33 @@
+; RUN: opt -passes='default<O2>' -debug-pass-manager -disable-output %s 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=ORDER
+; RUN: opt -passes='default<O2>' -print-before=sroa -disable-output %s 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=IR
+
+; ORDER: Running pass: EntryExitInstrumenterPass
+; ORDER-NEXT: Running pass: LowerExpectIntrinsicPass
+; ORDER-NEXT: Running pass: SimplifyCFGPass
+; ORDER-NOT: Running pass: SROAPass
+; ORDER: Running pass: MemCpyOptPass
+; ORDER: Running pass: SROAPass
+
+; IR-LABEL: *** IR Dump Before SROAPass on copy ***
+; IR: define void @copy
+; IR: %tmp = alloca [268435455 x i8]
+; IR-NOT: load [268435455 x i8]
+; IR-NOT: store [268435455 x i8]
+; IR-COUNT-2: call void @llvm.memcpy
+; IR: ret void
+
+target triple = "x86_64-unknown-linux-gnu"
+
+%Large = type [268435455 x i8]
+
+define void @copy(ptr noalias %src, ptr noalias %dst) {
+entry:
+  %tmp = alloca %Large, align 1
+  %value = load %Large, ptr %src, align 1
+  store %Large %value, ptr %tmp, align 1
+  %result = load %Large, ptr %tmp, align 1
+  store %Large %result, ptr %dst, align 1
+  ret void
+}



More information about the llvm-commits mailing list