diff --git a/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll b/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll index 4e6b0c2164a5c..933fbec4efadc 100644 --- a/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll +++ b/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll @@ -195,7 +195,7 @@ define void @test_intermediate_write(i8* %b) #0 { define void @test_throwing_call(i8* %src, i64 %src_size, i8* noalias %dst, i64 %dst_size, i8 %c) { ; CHECK-LABEL: @test_throwing_call( ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST:%.*]], i8 [[C:%.*]], i64 [[DST_SIZE:%.*]], i1 false) -; CHECK-NEXT: call void @call() [[ATTR2:#.*]] +; CHECK-NEXT: call void @call() #[[ATTR2:[0-9]+]] ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[SRC_SIZE:%.*]], i1 false) ; CHECK-NEXT: ret void ; @@ -208,7 +208,7 @@ define void @test_throwing_call(i8* %src, i64 %src_size, i8* noalias %dst, i64 % define void @test_throwing_call_alloca(i8* %src, i64 %src_size, i64 %dst_size, i8 %c) { ; CHECK-LABEL: @test_throwing_call_alloca( ; CHECK-NEXT: [[DST:%.*]] = alloca i8, align 1 -; CHECK-NEXT: call void @call() [[ATTR2]] +; CHECK-NEXT: call void @call() #[[ATTR2]] ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[DST_SIZE:%.*]], [[SRC_SIZE:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DST_SIZE]], [[SRC_SIZE]] ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]] @@ -237,6 +237,64 @@ define void @test_missing_noalias(i8* %src, i64 %src_size, i8* %dst, i64 %dst_si ret void } +define void @test_same_const_size(i8* noalias %src, i8* noalias %dst, i8 %c) { +; CHECK-LABEL: @test_same_const_size( +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 16 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 [[C:%.*]], i64 0, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 16, i1 false) +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 16, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 16, i1 false) + ret void +} + +define void @test_same_dynamic_size(i8* noalias %src, i8* noalias %dst, i64 %size, i8 %c) { +; CHECK-LABEL: @test_same_dynamic_size( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[SIZE:%.*]], [[SIZE]] +; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[SIZE]], [[SIZE]] +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 [[SIZE]] +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[SIZE]], i1 false) +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %size, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 false) + ret void +} + +; Destinations must alias, but are not trivially equal. +define void @test_must_alias_same_size(i8* noalias %src, i8* noalias %dst, i8 %c) { +; CHECK-LABEL: @test_must_alias_same_size( +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 16 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[GEP1]], i8 [[C:%.*]], i64 16, i1 false) +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8* [[DST]], i64 16 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[GEP2]], i8* [[SRC:%.*]], i64 16, i1 false) +; CHECK-NEXT: ret void +; + %gep1 = getelementptr i8, i8* %dst, i64 16 + call void @llvm.memset.p0i8.i64(i8* %gep1, i8 %c, i64 16, i1 false) + %gep2 = getelementptr i8, i8* %dst, i64 16 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %gep2, i8* %src, i64 16, i1 false) + ret void +} + +define void @test_must_alias_different_size(i8* noalias %src, i64 %src_size, i8* noalias %dst, i64 %dst_size, i8 %c) { +; CHECK-LABEL: @test_must_alias_different_size( +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 16 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[GEP1]], i8 [[C:%.*]], i64 [[DST_SIZE:%.*]], i1 false) +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, i8* [[DST]], i64 16 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[GEP2]], i8* [[SRC:%.*]], i64 [[SRC_SIZE:%.*]], i1 false) +; CHECK-NEXT: ret void +; + %gep1 = getelementptr i8, i8* %dst, i64 16 + call void @llvm.memset.p0i8.i64(i8* %gep1, i8 %c, i64 %dst_size, i1 false) + %gep2 = getelementptr i8, i8* %dst, i64 16 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %gep2, i8* %src, i64 %src_size, i1 false) + ret void +} + declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1)