[PATCH] D124078: [MemCpyOpt] Avoid infinite loop in processMemSetMemCpyDependence (PR54983)

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 00:10:30 PDT 2023


This revision was automatically updated to reflect the committed changes.
Closed by commit rG07460b666664: [MemCpyOpt] Avoid infinite loop in processMemSetMemCpyDependence (PR54983) (authored by nikic).

Changed prior to commit:
  https://reviews.llvm.org/D124078?vs=552320&id=556831#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124078/new/

https://reviews.llvm.org/D124078

Files:
  llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
  llvm/test/Transforms/MemCpyOpt/memcpy-zero-size.ll


Index: llvm/test/Transforms/MemCpyOpt/memcpy-zero-size.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/MemCpyOpt/memcpy-zero-size.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=memcpyopt < %s | FileCheck %s
+
+declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
+declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
+
+define void @zero_size(ptr %p, ptr %p2) {
+; CHECK-LABEL: @zero_size(
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.memcpy.p0.p0.i64(ptr %p, ptr %p2, i64 0, i1 false)
+  ret void
+}
+
+; The memcpy size is zero in a way that is non-trivial, but understood by AA.
+define void @pr54983(ptr %p, ptr noalias %p2) {
+; CHECK-LABEL: @pr54983(
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 0, i64 1, i1 false)
+; CHECK-NEXT:    [[SIZE:%.*]] = shl i64 0, 0
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.memset.p0.i64(ptr %p, i8 0, i64 1, i1 false)
+  %size = shl i64 0, 0
+  call void @llvm.memcpy.p0.p0.i64(ptr %p, ptr %p2, i64 %size, i1 false)
+  ret void
+}
+
+define void @pr64886(i64 %len, ptr noalias %p) {
+; CHECK-LABEL: @pr64886(
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr inttoptr (i64 -1 to ptr), i8 0, i64 [[LEN:%.*]], i1 false)
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.memset.p0.i64(ptr inttoptr (i64 -1 to ptr), i8 0, i64 %len, i1 false)
+  call void @llvm.memcpy.p0.p0.i64(ptr inttoptr (i64 -1 to ptr), ptr %p, i64 poison, i1 false)
+  ret void
+}
Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/CaptureTracking.h"
 #include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/MemoryLocation.h"
 #include "llvm/Analysis/MemorySSA.h"
@@ -1626,6 +1627,16 @@
   return true;
 }
 
+static bool isZeroSize(Value *Size) {
+  if (auto *I = dyn_cast<Instruction>(Size))
+    if (auto *Res = simplifyInstruction(I, I->getModule()->getDataLayout()))
+      Size = Res;
+  // Treat undef/poison size like zero.
+  if (auto *C = dyn_cast<Constant>(Size))
+    return isa<UndefValue>(C) || C->isNullValue();
+  return false;
+}
+
 /// Perform simplification of memcpy's.  If we have memcpy A
 /// which copies X to Y, and memcpy B which copies Y to Z, then we can rewrite
 /// B to be a memcpy from X to Z (or potentially a memmove, depending on
@@ -1642,6 +1653,14 @@
     return true;
   }
 
+  // If the size is zero, remove the memcpy. This also prevents infinite loops
+  // in processMemSetMemCpyDependence, which is a no-op for zero-length memcpys.
+  if (isZeroSize(M->getLength())) {
+    ++BBI;
+    eraseInstruction(M);
+    return true;
+  }
+
   // If copying from a constant, try to turn the memcpy into a memset.
   if (auto *GV = dyn_cast<GlobalVariable>(M->getSource()))
     if (GV->isConstant() && GV->hasDefinitiveInitializer())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124078.556831.patch
Type: text/x-patch
Size: 3178 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230915/77a92c2a/attachment.bin>


More information about the llvm-commits mailing list