For the case where the memcpy size is zero, this transform is a complex no-op. This can lead to an infinite loop when the size is zero in a way that BasicAA understands, because it can still understand that dst and dst + src_size are MustAlias. I've tried to mitigate this before using the isZeroSize() check, but we can hit cases where InstSimplify doesn't understand that the size is zero, but BasicAA does. As such, this bites the bullet and adds an explicit isKnownNonZero() check to guard against no-op transforms. Fixes https://github.com/llvm/llvm-project/issues/98610.
52 lines
1.9 KiB
LLVM
52 lines
1.9 KiB
LLVM
; 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
|
|
}
|
|
|
|
define void @pr98610(ptr %p, ptr noalias %p2) {
|
|
; CHECK-LABEL: @pr98610(
|
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 0, i64 1, i1 false)
|
|
; CHECK-NEXT: [[ZERO_EXT:%.*]] = zext i32 0 to i64
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[ZERO_EXT]], 1
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2:%.*]], i64 [[MUL]], i1 false)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.memset.p0.i64(ptr %p, i8 0, i64 1, i1 false)
|
|
%zero.ext = zext i32 0 to i64
|
|
%mul = mul i64 %zero.ext, 1
|
|
call void @llvm.memcpy.p0.p0.i64(ptr %p, ptr %p2, i64 %mul, i1 false)
|
|
ret void
|
|
}
|