1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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([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]]
18;
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
24}
25
26declare i32 @strcmp(i8* nocapture, i8* nocapture)
27
28define 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]]
35;
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
41}
42
43define 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]]
50;
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
56}
57
58define 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]]
65;
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
71}
72
73define 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]]
80;
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
86}
87
88define 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]]
95;
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
101}
102
103define 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]]
109;
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
115}
116
117define 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]]
124;
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
130}
131
132define 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]]
139;
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
145}
146
147
148define 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]]
155;
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
161}
162
163declare i32 @strncmp(i8* nocapture, i8* nocapture, i64)
164
165define 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]]
172;
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
178}
179
180define 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]]
187;
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
193}
194
195define 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]]
202;
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
208}
209
210define 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]]
217;
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
223}
224
225
226define 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]]
233;
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
239}
240
241define 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]]
248;
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
254}
255
256define 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]]
263;
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
269}
270
271define 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]]
278;
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
284}
285
286define 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]]
292;
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
298}
299
300define 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]]
307;
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
313}
314
315define 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]]
322;
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
328}
329
330define 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]]
337;
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
343}
344
345define 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]]
352;
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
358}
359
360; Negative tests
361define 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]]
368;
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
374}
375
376define 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]]
383;
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
389}
390
391define 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]]
396;
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
400}
401
402
403define 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]]
409;
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
414}
415
416
417define 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]]
424;
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
430}
431
432define 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]]
439;
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
445}
446
447define 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]]
453;
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
458}
459
460define 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
466;
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
471}
472
473define 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]]
480;
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
486}
487
488
489define 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]]
496;
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
502}
503
504define 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]]
511;
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
517}
518
519define 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]]
525;
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
530}
531
532define 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
538;
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
543}
544
545define 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]]
552;
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
558}
559
560declare i32 @memcmp(i8* nocapture, i8* nocapture, i64)
561