Author: Antonio Frighetto
Date: 2026-07-22T13:53:52Z
New Revision: c22ddf0f405f9e21e9f0c51b85caf7b3d7147313

URL: 
https://github.com/llvm/llvm-project/commit/c22ddf0f405f9e21e9f0c51b85caf7b3d7147313
DIFF: 
https://github.com/llvm/llvm-project/commit/c22ddf0f405f9e21e9f0c51b85caf7b3d7147313.diff

LOG: [MemCpyOpt] Ensure call slot optz does not lower destination alloca 
alignment

A destination alloca's alignment could have been unconditionally
overwritten, letting a lower-aligned source incorrectly undo a
previous alignment increase. This issue has been addressed by
considering the maximum alignment between the new source target
and current destination, adhering to what the existing comment
already promises.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    llvm/test/Transforms/MemCpyOpt/callslot.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp 
b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 3fc84f2fc8c13..92e1d9cf21240 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -1075,7 +1075,8 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction 
*cpyLoad,
   // If the destination wasn't sufficiently aligned then increase its 
alignment.
   if (!isDestSufficientlyAligned) {
     assert(isa<AllocaInst>(cpyDest) && "Can only increase alloca alignment!");
-    cast<AllocaInst>(cpyDest)->setAlignment(srcAlign);
+    AllocaInst *DestAlloca = cast<AllocaInst>(cpyDest);
+    DestAlloca->setAlignment(std::max(DestAlloca->getAlign(), srcAlign));
   }
 
   if (NeedMoveGEP) {

diff  --git a/llvm/test/Transforms/MemCpyOpt/callslot.ll 
b/llvm/test/Transforms/MemCpyOpt/callslot.ll
index 6c999c57f9187..25698a97ea145 100644
--- a/llvm/test/Transforms/MemCpyOpt/callslot.ll
+++ b/llvm/test/Transforms/MemCpyOpt/callslot.ll
@@ -234,6 +234,24 @@ define void @dest_not_writable(ptr noalias 
dereferenceable(128) %dst) {
   ret void
 }
 
+; Ensure call slot optimization does not attempt to lower the existing 
destination
+; alloca's alignment.
+define void @dest_alignment(ptr %src) {
+; CHECK-LABEL: @dest_alignment(
+; CHECK-NEXT:    [[SRC_2:%.*]] = alloca [24 x i8], align 4
+; CHECK-NEXT:    [[DST:%.*]] = alloca [24 x i8], align 16
+; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[DST]], ptr 
[[SRC:%.*]], i64 24, i1 false)
+; CHECK-NEXT:    call void @accept_ptr(ptr [[DST]])
+; CHECK-NEXT:    ret void
+;
+  %src.2 = alloca [24 x i8], align 4
+  %dst = alloca [24 x i8], align 16
+  call void @llvm.memcpy.p0.p0.i64(ptr align 16 %dst, ptr %src, i64 24, i1 
false)
+  call void @accept_ptr(ptr %src.2)
+  call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src.2, i64 24, i1 false)
+  ret void
+}
+
 declare void @may_throw()
 declare void @accept_ptr(ptr)
 declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)


        
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to