[llvm] 4d33cf4 - [MemCpyOpt] Avoid moving lifetime marker above def (PR58903)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 11 06:06:44 PST 2022
Author: Nikita Popov
Date: 2022-11-11T15:06:34+01:00
New Revision: 4d33cf4166f9a4438cb36ab60502eef7affd7df2
URL: https://github.com/llvm/llvm-project/commit/4d33cf4166f9a4438cb36ab60502eef7affd7df2
DIFF: https://github.com/llvm/llvm-project/commit/4d33cf4166f9a4438cb36ab60502eef7affd7df2.diff
LOG: [MemCpyOpt] Avoid moving lifetime marker above def (PR58903)
This is unlikely to happen with opaque pointers, so just bail out
of the transform, rather than trying to move bitcasts/etc as well.
Fixes https://github.com/llvm/llvm-project/issues/58903.
Added:
Modified:
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/test/Transforms/MemCpyOpt/lifetime.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 43259cb42da18..12336ef21e085 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -931,6 +931,17 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
return false;
}
+ // If we need to move a lifetime.start above the call, make sure that we can
+ // actually do so. If the argument is bitcasted for example, we would have to
+ // move the bitcast as well, which we don't handle.
+ if (SkippedLifetimeStart) {
+ auto *LifetimeArg =
+ dyn_cast<Instruction>(SkippedLifetimeStart->getOperand(1));
+ if (LifetimeArg && LifetimeArg->getParent() == C->getParent() &&
+ C->comesBefore(LifetimeArg))
+ return false;
+ }
+
// Check that accessing the first srcSize bytes of dest will not cause a
// trap. Otherwise the transform is invalid since it might cause a trap
// to occur earlier than it otherwise would.
diff --git a/llvm/test/Transforms/MemCpyOpt/lifetime.ll b/llvm/test/Transforms/MemCpyOpt/lifetime.ll
index 58e4ab8950553..3f567c381b7a9 100644
--- a/llvm/test/Transforms/MemCpyOpt/lifetime.ll
+++ b/llvm/test/Transforms/MemCpyOpt/lifetime.ll
@@ -116,3 +116,22 @@ define i32 @call_slot_clobber_before_lifetime_start() {
%v = load i32, ptr %dst
ret i32 %v
}
+
+define void @call_slot_lifetime_bitcast(ptr %ptr) {
+; CHECK-LABEL: @call_slot_lifetime_bitcast(
+; CHECK-NEXT: [[TMP1:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP2]], ptr align 4 [[PTR:%.*]], i64 4, i1 false)
+; CHECK-NEXT: [[TMP1_CAST:%.*]] = bitcast ptr [[TMP1]] to ptr
+; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[TMP1_CAST]])
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1_CAST]], ptr align 4 [[PTR]], i64 4, i1 false)
+; CHECK-NEXT: ret void
+;
+ %tmp1 = alloca i32
+ %tmp2 = alloca i32
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp2, ptr align 4 %ptr, i64 4, i1 false)
+ %tmp1.cast = bitcast ptr %tmp1 to ptr
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %tmp1.cast)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp1.cast, ptr align 4 %tmp2, i64 4, i1 false)
+ ret void
+}
More information about the llvm-commits
mailing list