1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5
6@a = common global [60 x i8] zeroinitializer, align 1
7@b = common global [60 x i8] zeroinitializer, align 1
8@.str = private constant [12 x i8] c"abcdefghijk\00"
9
10%struct.__va_list_tag = type { i32, i32, i8*, i8* }
11
12define i8* @test_memccpy() {
13; CHECK-LABEL: @test_memccpy(
14; CHECK-NEXT:    [[MEMCCPY:%.*]] = call i8* @memccpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i32 0, i64 60)
15; CHECK-NEXT:    ret i8* [[MEMCCPY]]
16;
17  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
18  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
19  %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 -1)
20  ret i8* %ret
21}
22
23define i8* @test_not_memccpy() {
24; CHECK-LABEL: @test_not_memccpy(
25; CHECK-NEXT:    [[RET:%.*]] = call i8* @__memccpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i32 0, i64 60, i64 59)
26; CHECK-NEXT:    ret i8* [[RET]]
27;
28  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
29  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
30  %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 59)
31  ret i8* %ret
32}
33
34define i8* @test_mempcpy() {
35; CHECK-LABEL: @test_mempcpy(
36; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(15) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull align 1 dereferenceable(15) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 15, i1 false)
37; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 15)
38;
39  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
40  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
41  %ret = call i8* @__mempcpy_chk(i8* %dst, i8* %src, i64 15, i64 -1)
42  ret i8* %ret
43}
44
45define i8* @test_not_mempcpy() {
46; CHECK-LABEL: @test_not_mempcpy(
47; CHECK-NEXT:    [[RET:%.*]] = call i8* @__mempcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 60, i64 59)
48; CHECK-NEXT:    ret i8* [[RET]]
49;
50  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
51  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
52  %ret = call i8* @__mempcpy_chk(i8* %dst, i8* %src, i64 60, i64 59)
53  ret i8* %ret
54}
55
56define i32 @test_snprintf() {
57; CHECK-LABEL: @test_snprintf(
58; CHECK-NEXT:    [[SNPRINTF:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
59; CHECK-NEXT:    ret i32 [[SNPRINTF]]
60;
61  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
62  %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
63  %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 -1, i8* %fmt)
64  ret i32 %ret
65}
66
67define i32 @test_not_snprintf() {
68; CHECK-LABEL: @test_not_snprintf(
69; CHECK-NEXT:    [[RET:%.*]] = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i32 0, i64 59, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
70; CHECK-NEXT:    [[IGN:%.*]] = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
71; CHECK-NEXT:    ret i32 [[RET]]
72;
73  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
74  %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
75  %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 59, i8* %fmt)
76  %ign = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 1, i64 -1, i8* %fmt)
77  ret i32 %ret
78}
79
80define i32 @test_sprintf() {
81; CHECK-LABEL: @test_sprintf(
82; CHECK-NEXT:    [[SPRINTF:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
83; CHECK-NEXT:    ret i32 [[SPRINTF]]
84;
85  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
86  %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
87  %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 -1, i8* %fmt)
88  ret i32 %ret
89}
90
91define i32 @test_not_sprintf() {
92; CHECK-LABEL: @test_not_sprintf(
93; CHECK-NEXT:    [[RET:%.*]] = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 59, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
94; CHECK-NEXT:    [[IGNORED:%.*]] = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
95; CHECK-NEXT:    ret i32 [[RET]]
96;
97  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
98  %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
99  %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 59, i8* %fmt)
100  %ignored = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 1, i64 -1, i8* %fmt)
101  ret i32 %ret
102}
103
104define i8* @test_strcat() {
105; CHECK-LABEL: @test_strcat(
106; CHECK-NEXT:    [[STRCAT:%.*]] = call i8* @strcat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
107; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0)
108;
109  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
110  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
111  %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 -1)
112  ret i8* %ret
113}
114
115define i8* @test_not_strcat() {
116; CHECK-LABEL: @test_not_strcat(
117; CHECK-NEXT:    [[RET:%.*]] = call i8* @__strcat_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 0)
118; CHECK-NEXT:    ret i8* [[RET]]
119;
120  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
121  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
122  %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 0)
123  ret i8* %ret
124}
125
126define i64 @test_strlcat() {
127; CHECK-LABEL: @test_strlcat(
128; CHECK-NEXT:    [[STRLCAT:%.*]] = call i64 @strlcat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
129; CHECK-NEXT:    ret i64 [[STRLCAT]]
130;
131  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
132  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
133  %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
134  ret i64 %ret
135}
136
137define i64 @test_not_strlcat() {
138; CHECK-LABEL: @test_not_strlcat(
139; CHECK-NEXT:    [[RET:%.*]] = call i64 @__strlcat_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22, i64 0)
140; CHECK-NEXT:    ret i64 [[RET]]
141;
142  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
143  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
144  %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 0)
145  ret i64 %ret
146}
147
148define i8* @test_strncat() {
149; CHECK-LABEL: @test_strncat(
150; CHECK-NEXT:    [[STRNCAT:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
151; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0)
152;
153  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
154  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
155  %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
156  ret i8* %ret
157}
158
159define i8* @test_not_strncat() {
160; CHECK-LABEL: @test_not_strncat(
161; CHECK-NEXT:    [[RET:%.*]] = call i8* @__strncat_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22, i64 3)
162; CHECK-NEXT:    ret i8* [[RET]]
163;
164  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
165  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
166  %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 3)
167  ret i8* %ret
168}
169
170define i64 @test_strlcpy() {
171; CHECK-LABEL: @test_strlcpy(
172; CHECK-NEXT:    [[STRLCPY:%.*]] = call i64 @strlcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
173; CHECK-NEXT:    ret i64 [[STRLCPY]]
174;
175  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
176  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
177  %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 -1)
178  ret i64 %ret
179}
180
181define i64 @test_not_strlcpy() {
182; CHECK-LABEL: @test_not_strlcpy(
183; CHECK-NEXT:    [[RET:%.*]] = call i64 @__strlcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22, i64 2)
184; CHECK-NEXT:    ret i64 [[RET]]
185;
186  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
187  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
188  %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 2)
189  ret i64 %ret
190}
191
192define i32 @test_vsnprintf() {
193; CHECK-LABEL: @test_vsnprintf(
194; CHECK-NEXT:    [[VSNPRINTF:%.*]] = call i32 @vsnprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
195; CHECK-NEXT:    ret i32 [[VSNPRINTF]]
196;
197  ; ret i32
198  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
199  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
200  %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
201  ret i32 %ret
202}
203
204define i32 @test_not_vsnprintf() {
205; CHECK-LABEL: @test_not_vsnprintf(
206; CHECK-NEXT:    [[RET:%.*]] = call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
207; CHECK-NEXT:    [[IGN:%.*]] = call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
208; CHECK-NEXT:    ret i32 [[RET]]
209;
210  ; ret i32
211  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
212  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
213  %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
214  %ign = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
215  ret i32 %ret
216}
217
218define i32 @test_vsprintf() {
219; CHECK-LABEL: @test_vsprintf(
220; CHECK-NEXT:    [[VSPRINTF:%.*]] = call i32 @vsprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
221; CHECK-NEXT:    ret i32 [[VSPRINTF]]
222;
223  ; ret i32
224  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
225  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
226  %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
227  ret i32 %ret
228}
229
230define i32 @test_not_vsprintf() {
231; CHECK-LABEL: @test_not_vsprintf(
232; CHECK-NEXT:    [[RET:%.*]] = call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
233; CHECK-NEXT:    [[IGN:%.*]] = call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
234; CHECK-NEXT:    ret i32 [[RET]]
235;
236  ; ret i32
237  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
238  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
239  %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
240  %ign = call i32 @__vsprintf_chk(i8* %dst, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
241  ret i32 %ret
242}
243
244declare i8* @__mempcpy_chk(i8*, i8*, i64, i64)
245declare i8* @__memccpy_chk(i8*, i8*, i32, i64, i64)
246declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)
247declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)
248declare i8* @__strcat_chk(i8*, i8*, i64)
249declare i64 @__strlcat_chk(i8*, i8*, i64, i64)
250declare i8* @__strncat_chk(i8*, i8*, i64, i64)
251declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)
252declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct.__va_list_tag*)
253declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct.__va_list_tag*)
254