1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
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"
10 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
12 define 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]]
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)
23 define 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]]
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)
34 define i8* @test_mempcpy() {
35 ; CHECK-LABEL: @test_mempcpy(
36 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(15) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* noundef 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)
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)
45 define 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]]
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)
56 define 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]]
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)
67 define 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]]
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)
80 define 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]]
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)
91 define 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]]
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)
104 define i8* @test_strcat() {
105 ; CHECK-LABEL: @test_strcat(
106 ; CHECK-NEXT: [[STRCAT:%.*]] = call i8* @strcat(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* noundef 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)
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)
115 define 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]]
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)
126 define 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]]
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)
137 define 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]]
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)
148 define i8* @test_strncat() {
149 ; CHECK-LABEL: @test_strncat(
150 ; CHECK-NEXT: [[STRNCAT:%.*]] = call i8* @strncat(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* noundef 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)
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)
159 define 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]]
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)
170 define 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]]
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)
181 define 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]]
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)
192 define 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]]
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)
204 define 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]]
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)
218 define 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]]
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)
230 define 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]]
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)
244 declare i8* @__mempcpy_chk(i8*, i8*, i64, i64)
245 declare i8* @__memccpy_chk(i8*, i8*, i32, i64, i64)
246 declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)
247 declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)
248 declare i8* @__strcat_chk(i8*, i8*, i64)
249 declare i64 @__strlcat_chk(i8*, i8*, i64, i64)
250 declare i8* @__strncat_chk(i8*, i8*, i64, i64)
251 declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)
252 declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct.__va_list_tag*)
253 declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct.__va_list_tag*)