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
