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