-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MemCpyOpt] Avoid infinite loop in processMemSetMemCpyDependence (PR5…
…4983) This adds an additional transform to drop zero-size memcpys, also in the case where the size is only zero after instruction simplification. The motivation is the case from PR54983 where the size is non-trivially zero, and processMemSetMemCpyDependence() keeps trying to reduce the memset size by zero bytes. This fix it's not really principled. It only works on the premise that if InstSimplify doesn't realize the size is zero, then AA also won't. The principled approach would be to instead add a isKnownNonZero() guard to the processMemSetMemCpyDependence() transform, but I suspect that would render that optimization mostly useless (at least it breaks all the existing test coverage -- worth noting that the constant size case is also handled by DSE, so I think this transform is primarily about the dynamic size case). Fixes #54983. Fixes #64886. Differential Revision: https://reviews.llvm.org/D124078
- Loading branch information
Showing
2 changed files
with
55 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |