[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / strcmp-memcmp.ll
blob4c89b81b8f28b5f236490e7d0de03c79911eedc9
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:e-i64:64-f80:128-n8:16:32:64-S128"
6 @key = constant [4 x i8] c"key\00", align 1
7 @abc = constant [8 x i8] c"abc\00de\00\00", align 1
9 declare void @use(i32)
11 define i32 @strcmp_memcmp([12 x i8]* dereferenceable (12) %buf) {
12 ; CHECK-LABEL: @strcmp_memcmp(
13 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
14 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
15 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
16 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
17 ; CHECK-NEXT:    ret i32 [[CONV]]
19   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
20   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
21   %cmp = icmp eq i32 %call, 0
22   %conv = zext i1 %cmp to i32
23   ret i32 %conv
26 declare i32 @strcmp(i8* nocapture, i8* nocapture)
28 define i32 @strcmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
29 ; CHECK-LABEL: @strcmp_memcmp2(
30 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
31 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
32 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
33 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
34 ; CHECK-NEXT:    ret i32 [[CONV]]
36   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
37   %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string)
38   %cmp = icmp eq i32 %call, 0
39   %conv = zext i1 %cmp to i32
40   ret i32 %conv
43 define i32 @strcmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
44 ; CHECK-LABEL: @strcmp_memcmp3(
45 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
46 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
47 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
48 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
49 ; CHECK-NEXT:    ret i32 [[CONV]]
51   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
52   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
53   %cmp = icmp ne i32 %call, 0
54   %conv = zext i1 %cmp to i32
55   ret i32 %conv
58 define i32 @strcmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
59 ; CHECK-LABEL: @strcmp_memcmp4(
60 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
61 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
62 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
63 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
64 ; CHECK-NEXT:    ret i32 [[CONV]]
66   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
67   %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string)
68   %cmp = icmp ne i32 %call, 0
69   %conv = zext i1 %cmp to i32
70   ret i32 %conv
73 define i32 @strcmp_memcmp5([5 x i8]* dereferenceable (5) %buf) {
74 ; CHECK-LABEL: @strcmp_memcmp5(
75 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* [[BUF:%.*]], i64 0, i64 0
76 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
77 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
78 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
79 ; CHECK-NEXT:    ret i32 [[CONV]]
81   %string = getelementptr inbounds [5 x i8], [5 x i8]* %buf, i64 0, i64 0
82   %call = call i32 @strcmp(i8* nonnull align 1 %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
83   %cmp = icmp eq i32 %call, 0
84   %conv = zext i1 %cmp to i32
85   ret i32 %conv
88 define i32 @strcmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
89 ; CHECK-LABEL: @strcmp_memcmp6(
90 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
91 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
92 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
93 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
94 ; CHECK-NEXT:    ret i32 [[CONV]]
96   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
97   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
98   %cmp = icmp sgt i32 %call, 0
99   %conv = zext i1 %cmp to i32
100   ret i32 %conv
103 define i32 @strcmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
104 ; CHECK-LABEL: @strcmp_memcmp7(
105 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
106 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
107 ; CHECK-NEXT:    [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
108 ; CHECK-NEXT:    ret i32 [[MEMCMP_LOBIT]]
110   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
111   %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string)
112   %cmp = icmp slt i32 %call, 0
113   %conv = zext i1 %cmp to i32
114   ret i32 %conv
117 define i32 @strcmp_memcmp8([4 x i8]* dereferenceable (4) %buf) {
118 ; CHECK-LABEL: @strcmp_memcmp8(
119 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
120 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
121 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
122 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
123 ; CHECK-NEXT:    ret i32 [[CONV]]
125   %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0
126   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
127   %cmp = icmp eq i32 %call, 0
128   %conv = zext i1 %cmp to i32
129   ret i32 %conv
132 define i32 @strcmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
133 ; CHECK-LABEL: @strcmp_memcmp9(
134 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
135 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4)
136 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
137 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
138 ; CHECK-NEXT:    ret i32 [[CONV]]
140   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
141   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0))
142   %cmp = icmp eq i32 %call, 0
143   %conv = zext i1 %cmp to i32
144   ret i32 %conv
148 define i32 @strncmp_memcmp([12 x i8]* dereferenceable (12) %buf) {
149 ; CHECK-LABEL: @strncmp_memcmp(
150 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
151 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
152 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
153 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
154 ; CHECK-NEXT:    ret i32 [[CONV]]
156   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
157   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
158   %cmp = icmp eq i32 %call, 0
159   %conv = zext i1 %cmp to i32
160   ret i32 %conv
163 declare i32 @strncmp(i8* nocapture, i8* nocapture, i64)
165 define i32 @strncmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
166 ; CHECK-LABEL: @strncmp_memcmp2(
167 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
168 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
169 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
170 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
171 ; CHECK-NEXT:    ret i32 [[CONV]]
173   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
174   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 11)
175   %cmp = icmp ne i32 %call, 0
176   %conv = zext i1 %cmp to i32
177   ret i32 %conv
180 define i32 @strncmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
181 ; CHECK-LABEL: @strncmp_memcmp3(
182 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
183 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
184 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
185 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
186 ; CHECK-NEXT:    ret i32 [[CONV]]
188   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
189   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 11)
190   %cmp = icmp eq i32 %call, 0
191   %conv = zext i1 %cmp to i32
192   ret i32 %conv
195 define i32 @strncmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
196 ; CHECK-LABEL: @strncmp_memcmp4(
197 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
198 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
199 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
200 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
201 ; CHECK-NEXT:    ret i32 [[CONV]]
203   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
204   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 5)
205   %cmp = icmp eq i32 %call, 0
206   %conv = zext i1 %cmp to i32
207   ret i32 %conv
210 define i32 @strncmp_memcmp5([12 x i8]* dereferenceable (12) %buf) {
211 ; CHECK-LABEL: @strncmp_memcmp5(
212 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
213 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
214 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
215 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
216 ; CHECK-NEXT:    ret i32 [[CONV]]
218   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
219   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
220   %cmp = icmp eq i32 %call, 0
221   %conv = zext i1 %cmp to i32
222   ret i32 %conv
226 define i32 @strncmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
227 ; CHECK-LABEL: @strncmp_memcmp6(
228 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
229 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
230 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
231 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
232 ; CHECK-NEXT:    ret i32 [[CONV]]
234   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
235   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
236   %cmp = icmp ne i32 %call, 0
237   %conv = zext i1 %cmp to i32
238   ret i32 %conv
241 define i32 @strncmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
242 ; CHECK-LABEL: @strncmp_memcmp7(
243 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
244 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
245 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
246 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
247 ; CHECK-NEXT:    ret i32 [[CONV]]
249   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
250   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
251   %cmp = icmp eq i32 %call, 0
252   %conv = zext i1 %cmp to i32
253   ret i32 %conv
256 define i32 @strncmp_memcmp8([12 x i8]* dereferenceable (12) %buf) {
257 ; CHECK-LABEL: @strncmp_memcmp8(
258 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
259 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(3) [[STRING]], i8* nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3)
260 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
261 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
262 ; CHECK-NEXT:    ret i32 [[CONV]]
264   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
265   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3)
266   %cmp = icmp eq i32 %call, 0
267   %conv = zext i1 %cmp to i32
268   ret i32 %conv
271 define i32 @strncmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
272 ; CHECK-LABEL: @strncmp_memcmp9(
273 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
274 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
275 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
276 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
277 ; CHECK-NEXT:    ret i32 [[CONV]]
279   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
280   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
281   %cmp = icmp sgt i32 %call, 0
282   %conv = zext i1 %cmp to i32
283   ret i32 %conv
286 define i32 @strncmp_memcmp10([12 x i8]* dereferenceable (12) %buf) {
287 ; CHECK-LABEL: @strncmp_memcmp10(
288 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
289 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
290 ; CHECK-NEXT:    [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
291 ; CHECK-NEXT:    ret i32 [[MEMCMP_LOBIT]]
293   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
294   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
295   %cmp = icmp slt i32 %call, 0
296   %conv = zext i1 %cmp to i32
297   ret i32 %conv
300 define i32 @strncmp_memcmp11([12 x i8]* dereferenceable (12) %buf) {
301 ; CHECK-LABEL: @strncmp_memcmp11(
302 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
303 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
304 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
305 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
306 ; CHECK-NEXT:    ret i32 [[CONV]]
308   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
309   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12)
310   %cmp = icmp eq i32 %call, 0
311   %conv = zext i1 %cmp to i32
312   ret i32 %conv
315 define i32 @strncmp_memcmp12([12 x i8]* dereferenceable (12) %buf) {
316 ; CHECK-LABEL: @strncmp_memcmp12(
317 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
318 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4)
319 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
320 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
321 ; CHECK-NEXT:    ret i32 [[CONV]]
323   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
324   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12)
325   %cmp = icmp eq i32 %call, 0
326   %conv = zext i1 %cmp to i32
327   ret i32 %conv
330 define i32 @strncmp_memcmp13([12 x i8]* dereferenceable (12) %buf) {
331 ; CHECK-LABEL: @strncmp_memcmp13(
332 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
333 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2)
334 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
335 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
336 ; CHECK-NEXT:    ret i32 [[CONV]]
338   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
339   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2)
340   %cmp = icmp eq i32 %call, 0
341   %conv = zext i1 %cmp to i32
342   ret i32 %conv
345 define i32 @strncmp_memcmp14([12 x i8]* dereferenceable (12) %buf) {
346 ; CHECK-LABEL: @strncmp_memcmp14(
347 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
348 ; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4)
349 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
350 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
351 ; CHECK-NEXT:    ret i32 [[CONV]]
353   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
354   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 12)
355   %cmp = icmp eq i32 %call, 0
356   %conv = zext i1 %cmp to i32
357   ret i32 %conv
360 ; Negative tests
361 define i32 @strcmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) {
362 ; CHECK-LABEL: @strcmp_memcmp_bad(
363 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
364 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
365 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
366 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
367 ; CHECK-NEXT:    ret i32 [[CONV]]
369   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
370   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
371   %cmp = icmp sgt i32 %call, 3
372   %conv = zext i1 %cmp to i32
373   ret i32 %conv
376 define i32 @strcmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf) {
377 ; CHECK-LABEL: @strcmp_memcmp_bad2(
378 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
379 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
380 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
381 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
382 ; CHECK-NEXT:    ret i32 [[CONV]]
384   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
385   %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string)
386   %cmp = icmp slt i32 %call, 3
387   %conv = zext i1 %cmp to i32
388   ret i32 %conv
391 define i32 @strcmp_memcmp_bad3([12 x i8]* dereferenceable (12) %buf) {
392 ; CHECK-LABEL: @strcmp_memcmp_bad3(
393 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
394 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
395 ; CHECK-NEXT:    ret i32 [[CALL]]
397   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
398   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
399   ret i32 %call
403 define i32 @strcmp_memcmp_bad4(i8* nocapture readonly %buf) {
404 ; CHECK-LABEL: @strcmp_memcmp_bad4(
405 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[BUF:%.*]])
406 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
407 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
408 ; CHECK-NEXT:    ret i32 [[CONV]]
410   %call = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %buf)
411   %cmp = icmp eq i32 %call, 0
412   %conv = zext i1 %cmp to i32
413   ret i32 %conv
417 define i32 @strcmp_memcmp_bad5([3 x i8]* dereferenceable (3) %buf) {
418 ; CHECK-LABEL: @strcmp_memcmp_bad5(
419 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* [[BUF:%.*]], i64 0, i64 0
420 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
421 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
422 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
423 ; CHECK-NEXT:    ret i32 [[CONV]]
425   %string = getelementptr inbounds [3 x i8], [3 x i8]* %buf, i64 0, i64 0
426   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
427   %cmp = icmp eq i32 %call, 0
428   %conv = zext i1 %cmp to i32
429   ret i32 %conv
432 define i32 @strcmp_memcmp_bad6([4 x i8]* dereferenceable (4) %buf, i8* nocapture readonly %k) {
433 ; CHECK-LABEL: @strcmp_memcmp_bad6(
434 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
435 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(1) [[K:%.*]])
436 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
437 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
438 ; CHECK-NEXT:    ret i32 [[CONV]]
440   %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0
441   %call = call i32 @strcmp(i8* nonnull %string, i8* %k)
442   %cmp = icmp eq i32 %call, 0
443   %conv = zext i1 %cmp to i32
444   ret i32 %conv
447 define i32 @strcmp_memcmp_bad7(i8* nocapture readonly %k) {
448 ; CHECK-LABEL: @strcmp_memcmp_bad7(
449 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[K:%.*]])
450 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
451 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
452 ; CHECK-NEXT:    ret i32 [[CONV]]
454   %call = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %k)
455   %cmp = icmp eq i32 %call, 0
456   %conv = zext i1 %cmp to i32
457   ret i32 %conv
460 define i32 @strcmp_memcmp_bad8([4 x i8]* dereferenceable (4) %buf) {
461 ; CHECK-LABEL: @strcmp_memcmp_bad8(
462 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
463 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
464 ; CHECK-NEXT:    tail call void @use(i32 [[CALL]])
465 ; CHECK-NEXT:    ret i32 0
467   %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0
468   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
469   tail call void @use(i32 %call)
470   ret i32 0
473 define i32 @strncmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) {
474 ; CHECK-LABEL: @strncmp_memcmp_bad(
475 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
476 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
477 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
478 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
479 ; CHECK-NEXT:    ret i32 [[CONV]]
481   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
482   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
483   %cmp = icmp sgt i32 %call, 3
484   %conv = zext i1 %cmp to i32
485   ret i32 %conv
489 define i32 @strncmp_memcmp_bad1([12 x i8]* dereferenceable (12) %buf) {
490 ; CHECK-LABEL: @strncmp_memcmp_bad1(
491 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
492 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
493 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
494 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
495 ; CHECK-NEXT:    ret i32 [[CONV]]
497   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
498   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5)
499   %cmp = icmp slt i32 %call, 3
500   %conv = zext i1 %cmp to i32
501   ret i32 %conv
504 define i32 @strncmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf, i64 %n) {
505 ; CHECK-LABEL: @strncmp_memcmp_bad2(
506 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
507 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 [[N:%.*]])
508 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 1
509 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
510 ; CHECK-NEXT:    ret i32 [[CONV]]
512   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
513   %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 %n)
514   %cmp = icmp slt i32 %call, 1
515   %conv = zext i1 %cmp to i32
516   ret i32 %conv
519 define i32 @strncmp_memcmp_bad3(i8* nocapture readonly %k) {
520 ; CHECK-LABEL: @strncmp_memcmp_bad3(
521 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[K:%.*]], i64 2)
522 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
523 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
524 ; CHECK-NEXT:    ret i32 [[CONV]]
526   %call = tail call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %k, i64 2)
527   %cmp = icmp eq i32 %call, 0
528   %conv = zext i1 %cmp to i32
529   ret i32 %conv
532 define i32 @strncmp_memcmp_bad4([4 x i8]* dereferenceable (4) %buf) {
533 ; CHECK-LABEL: @strncmp_memcmp_bad4(
534 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
535 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
536 ; CHECK-NEXT:    tail call void @use(i32 [[CALL]])
537 ; CHECK-NEXT:    ret i32 0
539   %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0
540   %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
541   tail call void @use(i32 %call)
542   ret i32 0
545 define i32 @strcmp_memcmp_msan([12 x i8]* dereferenceable (12) %buf) sanitize_memory {
546 ; CHECK-LABEL: @strcmp_memcmp_msan(
547 ; CHECK-NEXT:    [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
548 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
549 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
550 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
551 ; CHECK-NEXT:    ret i32 [[CONV]]
553   %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
554   %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
555   %cmp = icmp eq i32 %call, 0
556   %conv = zext i1 %cmp to i32
557   ret i32 %conv
560 declare i32 @memcmp(i8* nocapture, i8* nocapture, i64)