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

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 22 05:25:21 PDT 2023


nikic added inline comments.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1298
           Builder.CreatePointerCast(Dest, Builder.getInt8PtrTy(DestAS)),
           SrcSize),
       MemSet->getOperand(1), MemsetLen, Alignment);
----------------
fhahn wrote:
> I think the underlying issue here is that the builder folds this GEP to `Dest` is `SrcSize` is poison. This in turn leads to the new MemSet to `must-alias` the original memcpy, causing the cycle IIUC. Could we break the cycle here by bailing out if the pointer folds to `Dest` as more general solution and leave the cleanup of the cases where the size simplifies to 0 to instcombine?
In this case, yes:
```
  %1 = icmp ule i64 %len, poison
  %2 = sub i64 %len, poison
  %3 = select i1 %1, i64 0, i64 %2
  %4 = icmp ule i64 %3, poison
  %5 = sub i64 %3, poison
  %6 = select i1 %4, i64 0, i64 %5
  call void @llvm.memset.p0.i64(ptr align 1 inttoptr (i64 -1 to ptr), i8 0, i64 %6, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr inttoptr (i64 -1 to ptr), ptr null, i64 poison, i1 false)
  ret void
```
But not in the other case:
```
  %size = shl i64 0, 0
  %1 = icmp ule i64 1, %size
  %2 = sub i64 1, %size
  %3 = select i1 %1, i64 0, i64 %2
  %4 = getelementptr i8, ptr %p, i64 %size
  %5 = icmp ule i64 %3, %size
  %6 = sub i64 %3, %size
  %7 = select i1 %5, i64 0, i64 %6
  %8 = getelementptr i8, ptr %p, i64 %size
  call void @llvm.memset.p0.i64(ptr align 1 %8, i8 0, i64 %7, i1 false)
  call void @llvm.memcpy.p0.p0.i64(ptr %p, ptr %p2, i64 %size, i1 false)
  ret void
```
Here the pointers aren't directly equal, but AA can determine they're equal.

So just checking that we get back the old Dest wouldn't fully avoid the issue.


================
Comment at: llvm/test/Transforms/MemCpyOpt/memcpy-zero-size.ll:34
+  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 null, i64 poison, i1 false)
+  ret void
----------------
fhahn wrote:
> might be good to use pointer arguments passed to the function here, instead of `null`/`inttoptr` so the `poison` is the only issue here 
I've replaced the null, but the inttoptr is important for the IRBuilder constant folding.


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

https://reviews.llvm.org/D124078



More information about the llvm-commits mailing list