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