@@ -139,6 +139,37 @@ define void @test6_memcpy(ptr %src, ptr %dest) nounwind {
139139 ret void
140140}
141141
142+ ; When forwarding to memcpy(arg+1, arg+1), we don't need to create this memcpy.
143+ define void @test6_memcpy_forward_back (ptr %arg ) nounwind {
144+ ; CHECK-LABEL: @test6_memcpy_forward_back(
145+ ; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
146+ ; CHECK-NEXT: ret void
147+ ;
148+ %tmp = alloca [16 x i8 ], align 1
149+ %src = getelementptr inbounds i8 , ptr %arg , i64 1
150+ %dest = getelementptr inbounds i8 , ptr %arg , i64 1
151+ call void @llvm.memcpy.inline.p0.p0.i32 (ptr align 1 %tmp , ptr align 1 %src , i32 16 , i1 false )
152+ call void @llvm.memcpy.inline.p0.p0.i32 (ptr align 1 %dest , ptr align 1 %tmp , i32 16 , i1 false )
153+ ret void
154+ }
155+
156+ ; We have to retain this `memcpy(arg+2, arg+1)` forwarding.
157+ define void @test6_memcpy_forward_not_back (ptr %arg ) nounwind {
158+ ; CHECK-LABEL: @test6_memcpy_forward_not_back(
159+ ; CHECK-NEXT: [[TMP:%.*]] = alloca [16 x i8], align 1
160+ ; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[ARG:%.*]], i64 1
161+ ; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
162+ ; CHECK-NEXT: call void @llvm.memcpy.inline.p0.p0.i32(ptr align 1 [[TMP]], ptr align 1 [[SRC]], i32 16, i1 false)
163+ ; CHECK-NEXT: call void @llvm.memcpy.inline.p0.p0.i32(ptr align 1 [[DEST]], ptr align 1 [[TMP]], i32 16, i1 false)
164+ ; CHECK-NEXT: ret void
165+ ;
166+ %tmp = alloca [16 x i8 ], align 1
167+ %src = getelementptr inbounds i8 , ptr %arg , i64 1
168+ %dest = getelementptr inbounds i8 , ptr %arg , i64 2
169+ call void @llvm.memcpy.inline.p0.p0.i32 (ptr align 1 %tmp , ptr align 1 %src , i32 16 , i1 false )
170+ call void @llvm.memcpy.inline.p0.p0.i32 (ptr align 1 %dest , ptr align 1 %tmp , i32 16 , i1 false )
171+ ret void
172+ }
142173
143174@x = external global %0
144175
0 commit comments