xref: /llvm-project/llvm/test/Transforms/InstCombine/strcmp-memcmp.ll (revision 635f93dff7f07a58af4e8a7c915dfdb1852bb76b)
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:e-i64:64-f80:128-n8:16:32:64-S128"
5
6@key = constant [4 x i8] c"key\00", align 1
7@abc = constant [8 x i8] c"abc\00de\00\00", align 1
8
9declare void @use(i32)
10
11define i32 @strcmp_memcmp(ptr dereferenceable (12) %buf) nofree nosync {
12; CHECK-LABEL: @strcmp_memcmp(
13; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
14; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
15; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
16; CHECK-NEXT:    ret i32 [[CONV]]
17;
18  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
19  %cmp = icmp eq i32 %call, 0
20  %conv = zext i1 %cmp to i32
21  ret i32 %conv
22}
23
24declare i32 @strcmp(ptr nocapture, ptr nocapture)
25
26define i32 @strcmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync {
27; CHECK-LABEL: @strcmp_memcmp2(
28; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
29; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
30; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
31; CHECK-NEXT:    ret i32 [[CONV]]
32;
33  %call = call i32 @strcmp(ptr @key, ptr nonnull %buf)
34  %cmp = icmp eq i32 %call, 0
35  %conv = zext i1 %cmp to i32
36  ret i32 %conv
37}
38
39define i32 @strcmp_memcmp3(ptr dereferenceable (12) %buf) nofree nosync {
40; CHECK-LABEL: @strcmp_memcmp3(
41; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
42; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
43; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
44; CHECK-NEXT:    ret i32 [[CONV]]
45;
46  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
47  %cmp = icmp ne i32 %call, 0
48  %conv = zext i1 %cmp to i32
49  ret i32 %conv
50}
51
52define i32 @strcmp_memcmp4(ptr dereferenceable (12) %buf) nofree nosync {
53; CHECK-LABEL: @strcmp_memcmp4(
54; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
55; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
56; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
57; CHECK-NEXT:    ret i32 [[CONV]]
58;
59  %call = call i32 @strcmp(ptr @key, ptr nonnull %buf)
60  %cmp = icmp ne i32 %call, 0
61  %conv = zext i1 %cmp to i32
62  ret i32 %conv
63}
64
65define i32 @strcmp_memcmp5(ptr dereferenceable (5) %buf) nofree nosync {
66; CHECK-LABEL: @strcmp_memcmp5(
67; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
68; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
69; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
70; CHECK-NEXT:    ret i32 [[CONV]]
71;
72  %call = call i32 @strcmp(ptr nonnull align 1 %buf, ptr @key)
73  %cmp = icmp eq i32 %call, 0
74  %conv = zext i1 %cmp to i32
75  ret i32 %conv
76}
77
78define i32 @strcmp_memcmp6(ptr dereferenceable (12) %buf) nofree nosync {
79; CHECK-LABEL: @strcmp_memcmp6(
80; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
81; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
82; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
83; CHECK-NEXT:    ret i32 [[CONV]]
84;
85  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
86  %cmp = icmp sgt i32 %call, 0
87  %conv = zext i1 %cmp to i32
88  ret i32 %conv
89}
90
91define i32 @strcmp_memcmp7(ptr dereferenceable (12) %buf) nofree nosync {
92; CHECK-LABEL: @strcmp_memcmp7(
93; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
94; CHECK-NEXT:    [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
95; CHECK-NEXT:    ret i32 [[MEMCMP_LOBIT]]
96;
97  %call = call i32 @strcmp(ptr @key, ptr nonnull %buf)
98  %cmp = icmp slt i32 %call, 0
99  %conv = zext i1 %cmp to i32
100  ret i32 %conv
101}
102
103define i32 @strcmp_memcmp8(ptr dereferenceable (4) %buf) nofree nosync {
104; CHECK-LABEL: @strcmp_memcmp8(
105; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
106; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
107; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
108; CHECK-NEXT:    ret i32 [[CONV]]
109;
110  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
111  %cmp = icmp eq i32 %call, 0
112  %conv = zext i1 %cmp to i32
113  ret i32 %conv
114}
115
116define i32 @strcmp_memcmp9(ptr dereferenceable (12) %buf) nofree nosync {
117; CHECK-LABEL: @strcmp_memcmp9(
118; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @abc, i64 4)
119; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
120; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
121; CHECK-NEXT:    ret i32 [[CONV]]
122;
123  %call = call i32 @strcmp(ptr nonnull %buf, ptr @abc)
124  %cmp = icmp eq i32 %call, 0
125  %conv = zext i1 %cmp to i32
126  ret i32 %conv
127}
128
129
130define i32 @strncmp_memcmp(ptr dereferenceable (12) %buf) nofree nosync {
131; CHECK-LABEL: @strncmp_memcmp(
132; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(2) [[BUF:%.*]], ptr noundef nonnull dereferenceable(2) @key, i64 2)
133; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
134; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
135; CHECK-NEXT:    ret i32 [[CONV]]
136;
137  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 2)
138  %cmp = icmp eq i32 %call, 0
139  %conv = zext i1 %cmp to i32
140  ret i32 %conv
141}
142
143declare i32 @strncmp(ptr nocapture, ptr nocapture, i64)
144
145define i32 @strncmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync {
146; CHECK-LABEL: @strncmp_memcmp2(
147; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
148; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
149; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
150; CHECK-NEXT:    ret i32 [[CONV]]
151;
152  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 11)
153  %cmp = icmp ne i32 %call, 0
154  %conv = zext i1 %cmp to i32
155  ret i32 %conv
156}
157
158define i32 @strncmp_memcmp3(ptr dereferenceable (12) %buf) nofree nosync {
159; CHECK-LABEL: @strncmp_memcmp3(
160; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
161; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
162; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
163; CHECK-NEXT:    ret i32 [[CONV]]
164;
165  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 11)
166  %cmp = icmp eq i32 %call, 0
167  %conv = zext i1 %cmp to i32
168  ret i32 %conv
169}
170
171define i32 @strncmp_memcmp4(ptr dereferenceable (12) %buf) nofree nosync {
172; CHECK-LABEL: @strncmp_memcmp4(
173; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4)
174; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
175; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
176; CHECK-NEXT:    ret i32 [[CONV]]
177;
178  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 5)
179  %cmp = icmp eq i32 %call, 0
180  %conv = zext i1 %cmp to i32
181  ret i32 %conv
182}
183
184define i32 @strncmp_memcmp5(ptr dereferenceable (12) %buf) nofree nosync {
185; CHECK-LABEL: @strncmp_memcmp5(
186; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
187; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
188; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
189; CHECK-NEXT:    ret i32 [[CONV]]
190;
191  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
192  %cmp = icmp eq i32 %call, 0
193  %conv = zext i1 %cmp to i32
194  ret i32 %conv
195}
196
197
198define i32 @strncmp_memcmp6(ptr dereferenceable (12) %buf) nofree nosync {
199; CHECK-LABEL: @strncmp_memcmp6(
200; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
201; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
202; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
203; CHECK-NEXT:    ret i32 [[CONV]]
204;
205  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
206  %cmp = icmp ne i32 %call, 0
207  %conv = zext i1 %cmp to i32
208  ret i32 %conv
209}
210
211define i32 @strncmp_memcmp7(ptr dereferenceable (12) %buf) nofree nosync {
212; CHECK-LABEL: @strncmp_memcmp7(
213; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, 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]]
217;
218  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 4)
219  %cmp = icmp eq i32 %call, 0
220  %conv = zext i1 %cmp to i32
221  ret i32 %conv
222}
223
224define i32 @strncmp_memcmp8(ptr dereferenceable (12) %buf) nofree nosync {
225; CHECK-LABEL: @strncmp_memcmp8(
226; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(3) [[BUF:%.*]], ptr noundef nonnull dereferenceable(3) @key, i64 3)
227; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
228; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
229; CHECK-NEXT:    ret i32 [[CONV]]
230;
231  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 3)
232  %cmp = icmp eq i32 %call, 0
233  %conv = zext i1 %cmp to i32
234  ret i32 %conv
235}
236
237define i32 @strncmp_memcmp9(ptr dereferenceable (12) %buf) nofree nosync {
238; CHECK-LABEL: @strncmp_memcmp9(
239; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
240; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
241; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
242; CHECK-NEXT:    ret i32 [[CONV]]
243;
244  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
245  %cmp = icmp sgt i32 %call, 0
246  %conv = zext i1 %cmp to i32
247  ret i32 %conv
248}
249
250define i32 @strncmp_memcmp10(ptr dereferenceable (12) %buf) nofree nosync {
251; CHECK-LABEL: @strncmp_memcmp10(
252; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
253; CHECK-NEXT:    [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
254; CHECK-NEXT:    ret i32 [[MEMCMP_LOBIT]]
255;
256  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
257  %cmp = icmp slt i32 %call, 0
258  %conv = zext i1 %cmp to i32
259  ret i32 %conv
260}
261
262define i32 @strncmp_memcmp11(ptr dereferenceable (12) %buf) nofree nosync {
263; CHECK-LABEL: @strncmp_memcmp11(
264; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
265; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
266; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
267; CHECK-NEXT:    ret i32 [[CONV]]
268;
269  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 12)
270  %cmp = icmp eq i32 %call, 0
271  %conv = zext i1 %cmp to i32
272  ret i32 %conv
273}
274
275define i32 @strncmp_memcmp12(ptr dereferenceable (12) %buf) nofree nosync {
276; CHECK-LABEL: @strncmp_memcmp12(
277; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4)
278; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
279; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
280; CHECK-NEXT:    ret i32 [[CONV]]
281;
282  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 12)
283  %cmp = icmp eq i32 %call, 0
284  %conv = zext i1 %cmp to i32
285  ret i32 %conv
286}
287
288define i32 @strncmp_memcmp13(ptr dereferenceable (12) %buf) nofree nosync {
289; CHECK-LABEL: @strncmp_memcmp13(
290; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(2) [[BUF:%.*]], ptr noundef nonnull dereferenceable(2) @abc, i64 2)
291; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
292; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
293; CHECK-NEXT:    ret i32 [[CONV]]
294;
295  %call = call i32 @strncmp(ptr nonnull %buf, ptr @abc, i64 2)
296  %cmp = icmp eq i32 %call, 0
297  %conv = zext i1 %cmp to i32
298  ret i32 %conv
299}
300
301define i32 @strncmp_memcmp14(ptr dereferenceable (12) %buf) nofree nosync {
302; CHECK-LABEL: @strncmp_memcmp14(
303; CHECK-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @abc, 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]]
307;
308  %call = call i32 @strncmp(ptr nonnull %buf, ptr @abc, i64 12)
309  %cmp = icmp eq i32 %call, 0
310  %conv = zext i1 %cmp to i32
311  ret i32 %conv
312}
313
314; Negative tests
315define i32 @strcmp_memcmp_bad(ptr dereferenceable (12) %buf) nofree nosync {
316; CHECK-LABEL: @strcmp_memcmp_bad(
317; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
318; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
319; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
320; CHECK-NEXT:    ret i32 [[CONV]]
321;
322  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
323  %cmp = icmp sgt i32 %call, 3
324  %conv = zext i1 %cmp to i32
325  ret i32 %conv
326}
327
328define i32 @strcmp_memcmp_bad2(ptr dereferenceable (12) %buf) nofree nosync {
329; CHECK-LABEL: @strcmp_memcmp_bad2(
330; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]])
331; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
332; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
333; CHECK-NEXT:    ret i32 [[CONV]]
334;
335  %call = call i32 @strcmp(ptr @key, ptr nonnull %buf)
336  %cmp = icmp slt i32 %call, 3
337  %conv = zext i1 %cmp to i32
338  ret i32 %conv
339}
340
341define i32 @strcmp_memcmp_bad3(ptr dereferenceable (12) %buf) nofree nosync {
342; CHECK-LABEL: @strcmp_memcmp_bad3(
343; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
344; CHECK-NEXT:    ret i32 [[CALL]]
345;
346  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
347  ret i32 %call
348}
349
350
351define i32 @strcmp_memcmp_bad4(ptr nocapture readonly %buf) nofree nosync {
352; CHECK-LABEL: @strcmp_memcmp_bad4(
353; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]])
354; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
355; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
356; CHECK-NEXT:    ret i32 [[CONV]]
357;
358  %call = tail call i32 @strcmp(ptr @key, ptr %buf)
359  %cmp = icmp eq i32 %call, 0
360  %conv = zext i1 %cmp to i32
361  ret i32 %conv
362}
363
364
365define i32 @strcmp_memcmp_bad5(ptr dereferenceable (3) %buf) nofree nosync {
366; CHECK-LABEL: @strcmp_memcmp_bad5(
367; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
368; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
369; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
370; CHECK-NEXT:    ret i32 [[CONV]]
371;
372  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
373  %cmp = icmp eq i32 %call, 0
374  %conv = zext i1 %cmp to i32
375  ret i32 %conv
376}
377
378define i32 @strcmp_memcmp_bad6(ptr dereferenceable (4) %buf, ptr nocapture readonly %k) nofree nosync {
379; CHECK-LABEL: @strcmp_memcmp_bad6(
380; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(1) [[K:%.*]])
381; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
382; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
383; CHECK-NEXT:    ret i32 [[CONV]]
384;
385  %call = call i32 @strcmp(ptr nonnull %buf, ptr %k)
386  %cmp = icmp eq i32 %call, 0
387  %conv = zext i1 %cmp to i32
388  ret i32 %conv
389}
390
391define i32 @strcmp_memcmp_bad7(ptr nocapture readonly %k) nofree nosync {
392; CHECK-LABEL: @strcmp_memcmp_bad7(
393; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[K:%.*]])
394; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
395; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
396; CHECK-NEXT:    ret i32 [[CONV]]
397;
398  %call = tail call i32 @strcmp(ptr @key, ptr %k)
399  %cmp = icmp eq i32 %call, 0
400  %conv = zext i1 %cmp to i32
401  ret i32 %conv
402}
403
404define i32 @strcmp_memcmp_bad8(ptr dereferenceable (4) %buf) nofree nosync {
405; CHECK-LABEL: @strcmp_memcmp_bad8(
406; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
407; CHECK-NEXT:    tail call void @use(i32 [[CALL]])
408; CHECK-NEXT:    ret i32 0
409;
410  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
411  tail call void @use(i32 %call)
412  ret i32 0
413}
414
415define i32 @strncmp_memcmp_bad(ptr dereferenceable (12) %buf) nofree nosync {
416; CHECK-LABEL: @strncmp_memcmp_bad(
417; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 5)
418; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
419; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
420; CHECK-NEXT:    ret i32 [[CONV]]
421;
422  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
423  %cmp = icmp sgt i32 %call, 3
424  %conv = zext i1 %cmp to i32
425  ret i32 %conv
426}
427
428
429define i32 @strncmp_memcmp_bad1(ptr dereferenceable (12) %buf) nofree nosync {
430; CHECK-LABEL: @strncmp_memcmp_bad1(
431; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 5)
432; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
433; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
434; CHECK-NEXT:    ret i32 [[CONV]]
435;
436  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5)
437  %cmp = icmp slt i32 %call, 3
438  %conv = zext i1 %cmp to i32
439  ret i32 %conv
440}
441
442define i32 @strncmp_memcmp_bad2(ptr dereferenceable (12) %buf, i64 %n) nofree nosync {
443; CHECK-LABEL: @strncmp_memcmp_bad2(
444; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(ptr nonnull @key, ptr nonnull [[BUF:%.*]], i64 [[N:%.*]])
445; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 1
446; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
447; CHECK-NEXT:    ret i32 [[CONV]]
448;
449  %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 %n)
450  %cmp = icmp slt i32 %call, 1
451  %conv = zext i1 %cmp to i32
452  ret i32 %conv
453}
454
455define i32 @strncmp_memcmp_bad3(ptr nocapture readonly %k) nofree nosync {
456; CHECK-LABEL: @strncmp_memcmp_bad3(
457; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[K:%.*]], i64 2)
458; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
459; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
460; CHECK-NEXT:    ret i32 [[CONV]]
461;
462  %call = tail call i32 @strncmp(ptr @key, ptr %k, i64 2)
463  %cmp = icmp eq i32 %call, 0
464  %conv = zext i1 %cmp to i32
465  ret i32 %conv
466}
467
468define i32 @strncmp_memcmp_bad4(ptr dereferenceable (4) %buf) nofree nosync {
469; CHECK-LABEL: @strncmp_memcmp_bad4(
470; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 2)
471; CHECK-NEXT:    tail call void @use(i32 [[CALL]])
472; CHECK-NEXT:    ret i32 0
473;
474  %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 2)
475  tail call void @use(i32 %call)
476  ret i32 0
477}
478
479define i32 @strcmp_memcmp_msan(ptr dereferenceable (12) %buf) sanitize_memory {
480; CHECK-LABEL: @strcmp_memcmp_msan(
481; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
482; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
483; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
484; CHECK-NEXT:    ret i32 [[CONV]]
485;
486  %call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
487  %cmp = icmp eq i32 %call, 0
488  %conv = zext i1 %cmp to i32
489  ret i32 %conv
490}
491
492declare i32 @memcmp(ptr nocapture, ptr nocapture, i64)
493