[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