xref: /llvm-project/llvm/test/Transforms/InstCombine/fortify-folding.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=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, ptr, ptr }
11
12define ptr @test_memccpy() {
13; CHECK-LABEL: @test_memccpy(
14; CHECK-NEXT:    [[MEMCCPY:%.*]] = call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60)
15; CHECK-NEXT:    ret ptr [[MEMCCPY]]
16;
17  %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1)
18  ret ptr %ret
19}
20
21define ptr @test_not_memccpy() {
22; CHECK-LABEL: @test_not_memccpy(
23; CHECK-NEXT:    [[RET:%.*]] = call ptr @__memccpy_chk(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60, i64 59)
24; CHECK-NEXT:    ret ptr [[RET]]
25;
26  %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 59)
27  ret ptr %ret
28}
29
30define ptr @test_memccpy_tail() {
31; CHECK-LABEL: @test_memccpy_tail(
32; CHECK-NEXT:    [[MEMCCPY:%.*]] = tail call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60)
33; CHECK-NEXT:    ret ptr [[MEMCCPY]]
34;
35  %ret = tail call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1)
36  ret ptr %ret
37}
38
39define ptr @test_mempcpy() {
40; CHECK-LABEL: @test_mempcpy(
41; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(15) @a, ptr noundef nonnull align 1 dereferenceable(15) @b, i64 15, i1 false)
42; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @a, i64 15)
43;
44  %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1)
45  ret ptr %ret
46}
47
48define ptr @test_not_mempcpy() {
49; CHECK-LABEL: @test_not_mempcpy(
50; CHECK-NEXT:    [[RET:%.*]] = call ptr @__mempcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 60, i64 59)
51; CHECK-NEXT:    ret ptr [[RET]]
52;
53  %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 60, i64 59)
54  ret ptr %ret
55}
56
57define ptr @test_mempcpy_tail() {
58; CHECK-LABEL: @test_mempcpy_tail(
59; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(15) @a, ptr noundef nonnull align 1 dereferenceable(15) @b, i64 15, i1 false)
60; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @a, i64 15)
61;
62  %ret = tail call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1)
63  ret ptr %ret
64}
65
66define i32 @test_snprintf() {
67; CHECK-LABEL: @test_snprintf(
68; CHECK-NEXT:    [[SNPRINTF:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b)
69; CHECK-NEXT:    ret i32 [[SNPRINTF]]
70;
71  %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b)
72  ret i32 %ret
73}
74
75define i32 @test_not_snprintf() {
76; CHECK-LABEL: @test_not_snprintf(
77; CHECK-NEXT:    [[RET:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 0, i64 59, ptr nonnull @b)
78; CHECK-NEXT:    [[IGN:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 1, i64 -1, ptr nonnull @b)
79; CHECK-NEXT:    ret i32 [[RET]]
80;
81  %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 59, ptr @b)
82  %ign = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 1, i64 -1, ptr @b)
83  ret i32 %ret
84}
85
86define i32 @test_snprintf_tail() {
87; CHECK-LABEL: @test_snprintf_tail(
88; CHECK-NEXT:    [[SNPRINTF:%.*]] = tail call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b)
89; CHECK-NEXT:    ret i32 [[SNPRINTF]]
90;
91  %ret = tail call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b)
92  ret i32 %ret
93}
94
95define i32 @test_sprintf() {
96; CHECK-LABEL: @test_sprintf(
97; CHECK-NEXT:    [[SPRINTF:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b)
98; CHECK-NEXT:    ret i32 [[SPRINTF]]
99;
100  %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b)
101  ret i32 %ret
102}
103
104define i32 @test_not_sprintf() {
105; CHECK-LABEL: @test_not_sprintf(
106; CHECK-NEXT:    [[RET:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 0, i64 59, ptr nonnull @b)
107; CHECK-NEXT:    [[IGNORED:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b)
108; CHECK-NEXT:    ret i32 [[RET]]
109;
110  %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 59, ptr @b)
111  %ignored = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 1, i64 -1, ptr @b)
112  ret i32 %ret
113}
114
115define i32 @test_sprintf_tail() {
116; CHECK-LABEL: @test_sprintf_tail(
117; CHECK-NEXT:    [[SPRINTF:%.*]] = tail call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b)
118; CHECK-NEXT:    ret i32 [[SPRINTF]]
119;
120  %ret = tail call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b)
121  ret i32 %ret
122}
123
124define ptr @test_strcat() {
125; CHECK-LABEL: @test_strcat(
126; CHECK-NEXT:    [[STRCAT:%.*]] = call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b)
127; CHECK-NEXT:    ret ptr @a
128;
129  %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1)
130  ret ptr %ret
131}
132
133define ptr @test_not_strcat() {
134; CHECK-LABEL: @test_not_strcat(
135; CHECK-NEXT:    [[RET:%.*]] = call ptr @__strcat_chk(ptr nonnull @a, ptr nonnull @b, i64 0)
136; CHECK-NEXT:    ret ptr [[RET]]
137;
138  %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 0)
139  ret ptr %ret
140}
141
142define ptr @test_strcat_tail() {
143; CHECK-LABEL: @test_strcat_tail(
144; CHECK-NEXT:    [[STRCAT:%.*]] = tail call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b)
145; CHECK-NEXT:    ret ptr @a
146;
147  %ret = tail call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1)
148  ret ptr %ret
149}
150
151define i64 @test_strlcat() {
152; CHECK-LABEL: @test_strlcat(
153; CHECK-NEXT:    [[STRLCAT:%.*]] = call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22)
154; CHECK-NEXT:    ret i64 [[STRLCAT]]
155;
156  %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1)
157  ret i64 %ret
158}
159
160define i64 @test_not_strlcat() {
161; CHECK-LABEL: @test_not_strlcat(
162; CHECK-NEXT:    [[RET:%.*]] = call i64 @__strlcat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 0)
163; CHECK-NEXT:    ret i64 [[RET]]
164;
165  %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 0)
166  ret i64 %ret
167}
168
169define i64 @test_strlcat_tail() {
170; CHECK-LABEL: @test_strlcat_tail(
171; CHECK-NEXT:    [[STRLCAT:%.*]] = tail call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22)
172; CHECK-NEXT:    ret i64 [[STRLCAT]]
173;
174  %ret = tail call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1)
175  ret i64 %ret
176}
177
178define ptr @test_strncat() {
179; CHECK-LABEL: @test_strncat(
180; CHECK-NEXT:    [[STRNCAT:%.*]] = call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22)
181; CHECK-NEXT:    ret ptr @a
182;
183  %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1)
184  ret ptr %ret
185}
186
187define ptr @test_not_strncat() {
188; CHECK-LABEL: @test_not_strncat(
189; CHECK-NEXT:    [[RET:%.*]] = call ptr @__strncat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 3)
190; CHECK-NEXT:    ret ptr [[RET]]
191;
192  %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 3)
193  ret ptr %ret
194}
195
196define ptr @test_strncat_tail() {
197; CHECK-LABEL: @test_strncat_tail(
198; CHECK-NEXT:    [[STRNCAT:%.*]] = tail call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22)
199; CHECK-NEXT:    ret ptr @a
200;
201  %ret = tail call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1)
202  ret ptr %ret
203}
204
205define i64 @test_strlcpy() {
206; CHECK-LABEL: @test_strlcpy(
207; CHECK-NEXT:    [[STRLCPY:%.*]] = call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22)
208; CHECK-NEXT:    ret i64 [[STRLCPY]]
209;
210  %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1)
211  ret i64 %ret
212}
213
214define i64 @test_not_strlcpy() {
215; CHECK-LABEL: @test_not_strlcpy(
216; CHECK-NEXT:    [[RET:%.*]] = call i64 @__strlcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 2)
217; CHECK-NEXT:    ret i64 [[RET]]
218;
219  %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 2)
220  ret i64 %ret
221}
222
223define i64 @test_strlcpy_tail() {
224; CHECK-LABEL: @test_strlcpy_tail(
225; CHECK-NEXT:    [[STRLCPY:%.*]] = tail call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22)
226; CHECK-NEXT:    ret i64 [[STRLCPY]]
227;
228  %ret = tail call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1)
229  ret i64 %ret
230}
231
232define i32 @test_vsnprintf() {
233; CHECK-LABEL: @test_vsnprintf(
234; CHECK-NEXT:    [[VSNPRINTF:%.*]] = call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null)
235; CHECK-NEXT:    ret i32 [[VSNPRINTF]]
236;
237  ; ret i32
238  %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null)
239  ret i32 %ret
240}
241
242define i32 @test_not_vsnprintf() {
243; CHECK-LABEL: @test_not_vsnprintf(
244; CHECK-NEXT:    [[RET:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 0, i64 3, ptr nonnull @b, ptr null)
245; CHECK-NEXT:    [[IGN:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 1, i64 -1, ptr nonnull @b, ptr null)
246; CHECK-NEXT:    ret i32 [[RET]]
247;
248  ; ret i32
249  %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 3, ptr @b, ptr null)
250  %ign = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 1, i64 -1, ptr @b, ptr null)
251  ret i32 %ret
252}
253
254define i32 @test_vsnprintf_tail() {
255; CHECK-LABEL: @test_vsnprintf_tail(
256; CHECK-NEXT:    [[VSNPRINTF:%.*]] = tail call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null)
257; CHECK-NEXT:    ret i32 [[VSNPRINTF]]
258;
259  ; ret i32
260  %ret = tail call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null)
261  ret i32 %ret
262}
263
264define i32 @test_vsprintf() {
265; CHECK-LABEL: @test_vsprintf(
266; CHECK-NEXT:    [[VSPRINTF:%.*]] = call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null)
267; CHECK-NEXT:    ret i32 [[VSPRINTF]]
268;
269  ; ret i32
270  %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null)
271  ret i32 %ret
272}
273
274define i32 @test_not_vsprintf() {
275; CHECK-LABEL: @test_not_vsprintf(
276; CHECK-NEXT:    [[RET:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 0, i64 3, ptr nonnull @b, ptr null)
277; CHECK-NEXT:    [[IGN:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b, ptr null)
278; CHECK-NEXT:    ret i32 [[RET]]
279;
280  ; ret i32
281  %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 3, ptr @b, ptr null)
282  %ign = call i32 @__vsprintf_chk(ptr @a, i32 1, i64 -1, ptr @b, ptr null)
283  ret i32 %ret
284}
285
286define i32 @test_vsprintf_tail() {
287; CHECK-LABEL: @test_vsprintf_tail(
288; CHECK-NEXT:    [[VSPRINTF:%.*]] = tail call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null)
289; CHECK-NEXT:    ret i32 [[VSPRINTF]]
290;
291  ; ret i32
292  %ret = tail call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null)
293  ret i32 %ret
294}
295
296declare ptr @__mempcpy_chk(ptr, ptr, i64, i64)
297declare ptr @__memccpy_chk(ptr, ptr, i32, i64, i64)
298declare i32 @__snprintf_chk(ptr, i64, i32, i64, ptr, ...)
299declare i32 @__sprintf_chk(ptr, i32, i64, ptr, ...)
300declare ptr @__strcat_chk(ptr, ptr, i64)
301declare i64 @__strlcat_chk(ptr, ptr, i64, i64)
302declare ptr @__strncat_chk(ptr, ptr, i64, i64)
303declare i64 @__strlcpy_chk(ptr, ptr, i64, i64)
304declare i32 @__vsnprintf_chk(ptr, i64, i32, i64, ptr, ptr)
305declare i32 @__vsprintf_chk(ptr, i32, i64, ptr, ptr)
306