[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / InstCombine / fortify-folding.ll
blobee81557615a543ab07cd457c18509798fd6e9303
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s --dump-input-on-failure
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)
20   ret i8* %ret
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)
31   ret i8* %ret
34 define i32 @test_snprintf() {
35 ; CHECK-LABEL: @test_snprintf(
36 ; 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))
37 ; CHECK-NEXT:    ret i32 [[SNPRINTF]]
39   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
40   %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
41   %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 -1, i8* %fmt)
42   ret i32 %ret
45 define i32 @test_not_snprintf() {
46 ; CHECK-LABEL: @test_not_snprintf(
47 ; 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))
48 ; 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))
49 ; CHECK-NEXT:    ret i32 [[RET]]
51   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
52   %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
53   %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 59, i8* %fmt)
54   %ign = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 1, i64 -1, i8* %fmt)
55   ret i32 %ret
58 define i32 @test_sprintf() {
59 ; CHECK-LABEL: @test_sprintf(
60 ; 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))
61 ; CHECK-NEXT:    ret i32 [[SPRINTF]]
63   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
64   %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
65   %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 -1, i8* %fmt)
66   ret i32 %ret
69 define i32 @test_not_sprintf() {
70 ; CHECK-LABEL: @test_not_sprintf(
71 ; 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))
72 ; 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))
73 ; CHECK-NEXT:    ret i32 [[RET]]
75   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
76   %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
77   %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 59, i8* %fmt)
78   %ignored = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 1, i64 -1, i8* %fmt)
79   ret i32 %ret
82 define i8* @test_strcat() {
83 ; CHECK-LABEL: @test_strcat(
84 ; 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))
85 ; CHECK-NEXT:    ret i8* [[STRCAT]]
87   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
88   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
89   %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 -1)
90   ret i8* %ret
93 define i8* @test_not_strcat() {
94 ; CHECK-LABEL: @test_not_strcat(
95 ; 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)
96 ; CHECK-NEXT:    ret i8* [[RET]]
98   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
99   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
100   %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 0)
101   ret i8* %ret
104 define i64 @test_strlcat() {
105 ; CHECK-LABEL: @test_strlcat(
106 ; 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)
107 ; CHECK-NEXT:    ret i64 [[STRLCAT]]
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 i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
112   ret i64 %ret
115 define i64 @test_not_strlcat() {
116 ; CHECK-LABEL: @test_not_strlcat(
117 ; 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)
118 ; CHECK-NEXT:    ret i64 [[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 i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 0)
123   ret i64 %ret
126 define i8* @test_strncat() {
127 ; CHECK-LABEL: @test_strncat(
128 ; 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)
129 ; CHECK-NEXT:    ret i8* [[STRNCAT]]
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 i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 -1)
134   ret i8* %ret
137 define i8* @test_not_strncat() {
138 ; CHECK-LABEL: @test_not_strncat(
139 ; 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)
140 ; CHECK-NEXT:    ret i8* [[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 i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 3)
145   ret i8* %ret
148 define i64 @test_strlcpy() {
149 ; CHECK-LABEL: @test_strlcpy(
150 ; 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)
151 ; CHECK-NEXT:    ret i64 [[STRLCPY]]
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 i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 -1)
156   ret i64 %ret
159 define i64 @test_not_strlcpy() {
160 ; CHECK-LABEL: @test_not_strlcpy(
161 ; 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)
162 ; CHECK-NEXT:    ret i64 [[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 i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 2)
167   ret i64 %ret
170 define i32 @test_vsnprintf() {
171 ; CHECK-LABEL: @test_vsnprintf(
172 ; 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)
173 ; CHECK-NEXT:    ret i32 [[VSNPRINTF]]
175   ; ret i32
176   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
177   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
178   %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
179   ret i32 %ret
182 define i32 @test_not_vsnprintf() {
183 ; CHECK-LABEL: @test_not_vsnprintf(
184 ; 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)
185 ; 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)
186 ; CHECK-NEXT:    ret i32 [[RET]]
188   ; ret i32
189   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
190   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
191   %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
192   %ign = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
193   ret i32 %ret
196 define i32 @test_vsprintf() {
197 ; CHECK-LABEL: @test_vsprintf(
198 ; 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)
199 ; CHECK-NEXT:    ret i32 [[VSPRINTF]]
201   ; ret i32
202   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
203   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
204   %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null)
205   ret i32 %ret
208 define i32 @test_not_vsprintf() {
209 ; CHECK-LABEL: @test_not_vsprintf(
210 ; 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)
211 ; 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)
212 ; CHECK-NEXT:    ret i32 [[RET]]
214   ; ret i32
215   %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
216   %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
217   %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 3, i8* %src, %struct.__va_list_tag* null)
218   %ign = call i32 @__vsprintf_chk(i8* %dst, i32 1, i64 -1, i8* %src, %struct.__va_list_tag* null)
219   ret i32 %ret
222 declare i8* @__memccpy_chk(i8*, i8*, i32, i64, i64)
223 declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)
224 declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)
225 declare i8* @__strcat_chk(i8*, i8*, i64)
226 declare i64 @__strlcat_chk(i8*, i8*, i64, i64)
227 declare i8* @__strncat_chk(i8*, i8*, i64, i64)
228 declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)
229 declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct.__va_list_tag*)
230 declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct.__va_list_tag*)