Skip to content

Commit a34be73

Browse files
committed
Update memcpy-memcpy-offset.ll
1 parent d238bb8 commit a34be73

File tree

1 file changed

+115
-109
lines changed

1 file changed

+115
-109
lines changed

llvm/test/Transforms/MemCpyOpt/memcpy-memcpy-offset.ll

Lines changed: 115 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -4,191 +4,197 @@
44
%buf = type [9 x i8]
55

66
; We can forward `memcpy` because the copy location are the same,
7-
define void @forward_offset(ptr %dep_src) {
7+
define void @forward_offset(ptr %src, ptr %dest) {
88
; CHECK-LABEL: define void @forward_offset(
9-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
9+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
1010
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
11-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
12-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
13-
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
14-
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEP]], ptr align 1 [[DEP]], i64 6, i1 false)
11+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
12+
; CHECK-NEXT: [[SRC_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
13+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
14+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 6, i1 false)
1515
; CHECK-NEXT: ret void
1616
;
17-
%dep_dest = alloca %buf, align 1
18-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
19-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
20-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 1
21-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
17+
%cpy_tmp = alloca %buf, align 1
18+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
19+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
20+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
2221
ret void
2322
}
2423

2524
; We need to update the align value of the source of `memcpy` when forwarding.
26-
define void @forward_offset_align(ptr %dep_src) {
25+
define void @forward_offset_align(ptr %src, ptr %dest) {
2726
; CHECK-LABEL: define void @forward_offset_align(
28-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
27+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
2928
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
30-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 4 [[DEP_SRC]], i64 9, i1 false)
31-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 3
32-
; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 3
33-
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[DEST]], i64 5, i1 false)
29+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 4 [[SRC]], i64 9, i1 false)
30+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 3
31+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 3
32+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 5, i1 false)
3433
; CHECK-NEXT: ret void
3534
;
36-
%dep_dest = alloca %buf, align 1
37-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 4 %dep_src, i64 9, i1 false)
38-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 3
39-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 3
40-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 5, i1 false)
35+
%cpy_tmp = alloca %buf, align 1
36+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 4 %src, i64 9, i1 false)
37+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 3
38+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 5, i1 false)
4139
ret void
4240
}
4341

4442
; We can change the align value to 2 when forwarding.
45-
define void @forward_offset_align_2(ptr %dep_src) {
43+
define void @forward_offset_align_2(ptr %src, ptr %dest) {
4644
; CHECK-LABEL: define void @forward_offset_align_2(
47-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
45+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
4846
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
49-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 4 [[DEP_SRC]], i64 9, i1 false)
50-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 2
51-
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 2
52-
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEP]], ptr align 2 [[DEP]], i64 6, i1 false)
47+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 4 [[SRC]], i64 9, i1 false)
48+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 2
49+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 2
50+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 2 [[TMP1]], i64 6, i1 false)
5351
; CHECK-NEXT: ret void
5452
;
55-
%dep_dest = alloca %buf, align 1
56-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 4 %dep_src, i64 9, i1 false)
57-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 2
58-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 2
59-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
53+
%cpy_tmp = alloca %buf, align 1
54+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 4 %src, i64 9, i1 false)
55+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 2
56+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
57+
ret void
58+
}
59+
60+
; If the copy destination can be used as the copy source, we don't need to create a GEP instruction.
61+
define void @forward_offset_without_gep(ptr %src) {
62+
; CHECK-LABEL: define void @forward_offset_without_gep(
63+
; CHECK-SAME: ptr [[SRC:%.*]]) {
64+
; CHECK-NEXT: [[TMP:%.*]] = alloca [9 x i8], align 1
65+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[TMP]], ptr align 1 [[SRC]], i64 7, i1 false)
66+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 1
67+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
68+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[TMP1]], ptr align 1 [[TMP1]], i64 6, i1 false)
69+
; CHECK-NEXT: ret void
70+
;
71+
%cpy_tmp = alloca %buf, align 1
72+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
73+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
74+
%dest = getelementptr inbounds i8, ptr %src, i64 1
75+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
6076
ret void
6177
}
6278

6379
; We need to create a GEP instruction when forwarding.
64-
define void @forward_offset_with_gep(ptr %dep_src) {
80+
define void @forward_offset_with_gep(ptr %src) {
6581
; CHECK-LABEL: define void @forward_offset_with_gep(
66-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
82+
; CHECK-SAME: ptr [[SRC:%.*]]) {
6783
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
68-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
69-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
70-
; CHECK-NEXT: [[DEP1:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 2
71-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
72-
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEP1]], ptr align 1 [[TMP1]], i64 6, i1 false)
84+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
85+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
86+
; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 2
87+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
88+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 6, i1 false)
7389
; CHECK-NEXT: ret void
7490
;
75-
%dep_dest = alloca %buf, align 1
76-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
77-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
78-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 2
79-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
91+
%cpy_tmp = alloca %buf, align 1
92+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
93+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
94+
%dest = getelementptr inbounds i8, ptr %src, i64 2
95+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
8096
ret void
8197
}
8298

8399
; Make sure we pass the right parameters when calling `memcpy`.
84-
define void @forward_offset_memcpy(ptr %dep_src) {
100+
define void @forward_offset_memcpy(ptr %src, ptr %dest) {
85101
; CHECK-LABEL: define void @forward_offset_memcpy(
86-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
102+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
87103
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
88-
; CHECK-NEXT: [[DEST:%.*]] = alloca [9 x i8], align 1
89-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
90-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
91-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
92-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 6, i1 false)
104+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
105+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
106+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
107+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 6, i1 false)
93108
; CHECK-NEXT: call void @use(ptr [[DEST]])
94109
; CHECK-NEXT: ret void
95110
;
96-
%dep_dest = alloca %buf, align 1
97-
%dest = alloca %buf, align 1
98-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
99-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
100-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
111+
%cpy_tmp = alloca %buf, align 1
112+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
113+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
114+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
101115
call void @use(ptr %dest)
102116
ret void
103117
}
104118

105119
; Make sure we pass the right parameters when calling `memcpy.inline`.
106-
define void @forward_offset_memcpy_inline(ptr %dep_src) {
120+
define void @forward_offset_memcpy_inline(ptr %src, ptr %dest) {
107121
; CHECK-LABEL: define void @forward_offset_memcpy_inline(
108-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
122+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
109123
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
110-
; CHECK-NEXT: [[DEST:%.*]] = alloca [9 x i8], align 1
111-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
112-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
113-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
124+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
125+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
114126
; CHECK-NEXT: call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 6, i1 false)
115127
; CHECK-NEXT: call void @use(ptr [[DEST]])
116128
; CHECK-NEXT: ret void
117129
;
118-
%dep_dest = alloca %buf, align 1
119-
%dest = alloca %buf, align 1
120-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
121-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
122-
call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
130+
%cpy_tmp = alloca %buf, align 1
131+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
132+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
133+
call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
123134
call void @use(ptr %dest)
124135
ret void
125136
}
126137

127138
; We cannot forward `memcpy` because it exceeds the size of `memcpy` it depends on.
128-
define void @do_not_forward_oversize_offset(ptr %dep_src) {
139+
define void @do_not_forward_oversize_offset(ptr %src, ptr %dest) {
129140
; CHECK-LABEL: define void @do_not_forward_oversize_offset(
130-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
141+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
131142
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
132-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 6, i1 false)
133-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
134-
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
135-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP]], ptr align 1 [[SRC]], i64 6, i1 false)
143+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 6, i1 false)
144+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
145+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP_OFFSET]], i64 6, i1 false)
136146
; CHECK-NEXT: ret void
137147
;
138-
%dep_dest = alloca %buf, align 1
139-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 6, i1 false)
140-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
141-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 1
142-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 6, i1 false)
148+
%cpy_tmp = alloca %buf, align 1
149+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 6, i1 false)
150+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
151+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 6, i1 false)
143152
ret void
144153
}
145154

146155
; We can forward `memcpy` because the write operation does not corrupt the location to be copied.
147-
define void @forward_offset_and_store(ptr %dep_src) {
156+
define void @forward_offset_and_store(ptr %src, ptr %dest) {
148157
; CHECK-LABEL: define void @forward_offset_and_store(
149-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
158+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
150159
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
151-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
152-
; CHECK-NEXT: store i8 1, ptr [[DEP_SRC]], align 1
153-
; CHECK-NEXT: [[DEP_SRC_END:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 6
160+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
161+
; CHECK-NEXT: store i8 1, ptr [[SRC]], align 1
162+
; CHECK-NEXT: [[DEP_SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 6
154163
; CHECK-NEXT: store i8 1, ptr [[DEP_SRC_END]], align 1
155-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
156-
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
157-
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEP]], ptr align 1 [[DEP]], i64 5, i1 false)
164+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
165+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
166+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP1]], i64 5, i1 false)
158167
; CHECK-NEXT: ret void
159168
;
160-
%dep_dest = alloca %buf, align 1
161-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
162-
store i8 1, ptr %dep_src, align 1
163-
%dep_src_end = getelementptr inbounds i8, ptr %dep_src, i64 6
164-
store i8 1, ptr %dep_src_end, align 1
165-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
166-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 1
167-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 5, i1 false)
169+
%cpy_tmp = alloca %buf, align 1
170+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
171+
store i8 1, ptr %src, align 1
172+
%src_end = getelementptr inbounds i8, ptr %src, i64 6
173+
store i8 1, ptr %src_end, align 1
174+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
175+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 5, i1 false)
168176
ret void
169177
}
170178

171179
; We cannot forward `memcpy` because the write operation alters the location to be copied.
172180
; Also, make sure we have removed the GEP instruction that was created temporarily.
173-
define void @do_not_forward_offset_and_store(ptr %dep_src) {
181+
define void @do_not_forward_offset_and_store(ptr %src, ptr %dest) {
174182
; CHECK-LABEL: define void @do_not_forward_offset_and_store(
175-
; CHECK-SAME: ptr [[DEP_SRC:%.*]]) {
183+
; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DEST:%.*]]) {
176184
; CHECK-NEXT: [[DEP_DEST:%.*]] = alloca [9 x i8], align 1
177-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[DEP_SRC]], i64 7, i1 false)
178-
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 1
185+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEP_DEST]], ptr align 1 [[SRC]], i64 7, i1 false)
186+
; CHECK-NEXT: [[DEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
179187
; CHECK-NEXT: store i8 1, ptr [[DEP]], align 1
180-
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
181-
; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i8, ptr [[DEP_SRC]], i64 2
182-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[SRC]], i64 5, i1 false)
188+
; CHECK-NEXT: [[TMP_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DEP_DEST]], i64 1
189+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DEST]], ptr align 1 [[TMP_OFFSET]], i64 5, i1 false)
183190
; CHECK-NEXT: ret void
184191
;
185-
%dep_dest = alloca %buf, align 1
186-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dep_dest, ptr align 1 %dep_src, i64 7, i1 false)
187-
%dep_src_offset = getelementptr inbounds i8, ptr %dep_src, i64 1
188-
store i8 1, ptr %dep_src_offset, align 1
189-
%src = getelementptr inbounds i8, ptr %dep_dest, i64 1
190-
%dest = getelementptr inbounds i8, ptr %dep_src, i64 2
191-
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %src, i64 5, i1 false)
192+
%cpy_tmp = alloca %buf, align 1
193+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %cpy_tmp, ptr align 1 %src, i64 7, i1 false)
194+
%src_offset = getelementptr inbounds i8, ptr %src, i64 1
195+
store i8 1, ptr %src_offset, align 1
196+
%cpy_tmp_offset = getelementptr inbounds i8, ptr %cpy_tmp, i64 1
197+
call void @llvm.memcpy.p0.p0.i64(ptr align 1 %dest, ptr align 1 %cpy_tmp_offset, i64 5, i1 false)
192198
ret void
193199
}
194200

0 commit comments

Comments
 (0)