1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4declare void @use(i1) 5 6define void @f1(i32 %a, i32 %b) { 7; CHECK-LABEL: @f1( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[A_255:%.*]] = and i32 [[A:%.*]], 255 10; CHECK-NEXT: [[A_2:%.*]] = add nuw nsw i32 [[A_255]], 20 11; CHECK-NEXT: [[BC:%.*]] = icmp ugt i32 [[B:%.*]], [[A_2]] 12; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 13; CHECK: true: 14; CHECK-NEXT: call void @use(i1 false) 15; CHECK-NEXT: call void @use(i1 false) 16; CHECK-NEXT: call void @use(i1 false) 17; CHECK-NEXT: call void @use(i1 true) 18; CHECK-NEXT: call void @use(i1 true) 19; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[B]], 21 20; CHECK-NEXT: call void @use(i1 [[C_1]]) 21; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[B]], 21 22; CHECK-NEXT: call void @use(i1 [[C_2]]) 23; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[B]], 255 24; CHECK-NEXT: call void @use(i1 [[C_3]]) 25; CHECK-NEXT: ret void 26; CHECK: false: 27; CHECK-NEXT: call void @use(i1 false) 28; CHECK-NEXT: call void @use(i1 false) 29; CHECK-NEXT: call void @use(i1 true) 30; CHECK-NEXT: call void @use(i1 true) 31; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[B]], 21 32; CHECK-NEXT: call void @use(i1 [[C_4]]) 33; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B]], 275 34; CHECK-NEXT: call void @use(i1 [[C_5]]) 35; CHECK-NEXT: ret void 36; 37entry: 38 %a.255 = and i32 %a, 255 39 %a.2 = add i32 %a.255, 20 40 %bc = icmp ugt i32 %b, %a.2 41 br i1 %bc, label %true, label %false 42 43true: ; %b in [21, 0) 44 ; Conditions below are false. 45 %f.1 = icmp eq i32 %b, 0 46 call void @use(i1 %f.1) 47 %f.2 = icmp eq i32 %b, 20 48 call void @use(i1 %f.2) 49 %f.3 = icmp ult i32 %b, 20 50 call void @use(i1 %f.3) 51 52 ; Conditions below are true. 53 %t.1 = icmp ugt i32 %b, 5 54 call void @use(i1 %t.1) 55 %t.2 = icmp ne i32 %b, 20 56 call void @use(i1 %t.2) 57 58 ; Conditions below cannot be simplified. 59 %c.1 = icmp eq i32 %b, 21 60 call void @use(i1 %c.1) 61 %c.2 = icmp ugt i32 %b, 21 62 call void @use(i1 %c.2) 63 %c.3 = icmp ugt i32 %b, 255 64 call void @use(i1 %c.3) 65 ret void 66 67false: ;%b in [0, 276) 68 ; Conditions below are false; 69 %f.4 = icmp eq i32 %b, 276 70 call void @use(i1 %f.4) 71 %f.5 = icmp ugt i32 %b, 275 72 call void @use(i1 %f.5) 73 74 ; Conditions below are true; 75 %t.3 = icmp ne i32 %b, 276 76 call void @use(i1 %t.3) 77 %t.4 = icmp ule i32 %b, 275 78 call void @use(i1 %t.4) 79 80 ; Conditions below cannot be simplified. 81 %c.4 = icmp eq i32 %b, 21 82 call void @use(i1 %c.4) 83 %c.5 = icmp eq i32 %b, 275 84 call void @use(i1 %c.5) 85 ret void 86} 87 88define void @f2_ptr(ptr %a, ptr %b) { 89; CHECK-LABEL: @f2_ptr( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: [[BC:%.*]] = icmp eq ptr [[A:%.*]], null 92; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 93; CHECK: true: 94; CHECK-NEXT: call void @use(i1 false) 95; CHECK-NEXT: call void @use(i1 true) 96; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr null, [[B:%.*]] 97; CHECK-NEXT: call void @use(i1 [[C_1]]) 98; CHECK-NEXT: ret void 99; CHECK: false: 100; CHECK-NEXT: call void @use(i1 false) 101; CHECK-NEXT: call void @use(i1 true) 102; CHECK-NEXT: [[C_2:%.*]] = icmp eq ptr [[A]], [[B]] 103; CHECK-NEXT: call void @use(i1 [[C_2]]) 104; CHECK-NEXT: ret void 105; 106entry: 107 %bc = icmp eq ptr %a, null 108 br i1 %bc, label %true, label %false 109 110true: ; %a == 0 111 %f.1 = icmp ne ptr %a, null 112 call void @use(i1 %f.1) 113 114 %t.1 = icmp eq ptr %a, null 115 call void @use(i1 %t.1) 116 117 %c.1 = icmp eq ptr %a, %b 118 call void @use(i1 %c.1) 119 ret void 120 121false: ; %a != 0 122 %f.2 = icmp eq ptr %a, null 123 call void @use(i1 %f.2) 124 125 %t.2 = icmp ne ptr %a, null 126 call void @use(i1 %t.2) 127 128 %c.2 = icmp eq ptr %a, %b 129 call void @use(i1 %c.2) 130 ret void 131} 132 133define ptr @f3(ptr %a, ptr %b, i1 %c) { 134; CHECK-LABEL: @f3( 135; CHECK-NEXT: entry: 136; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[A:%.*]], null 137; CHECK-NEXT: br i1 [[C_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 138; CHECK: true: 139; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE_2:%.*]], label [[FALSE_2:%.*]] 140; CHECK: true.2: 141; CHECK-NEXT: br label [[EXIT_2:%.*]] 142; CHECK: false.2: 143; CHECK-NEXT: br label [[EXIT_2]] 144; CHECK: exit.2: 145; CHECK-NEXT: [[P:%.*]] = phi ptr [ null, [[TRUE_2]] ], [ [[B:%.*]], [[FALSE_2]] ] 146; CHECK-NEXT: ret ptr [[P]] 147; CHECK: false: 148; CHECK-NEXT: ret ptr null 149; 150entry: 151 %c.1 = icmp eq ptr %a, null 152 br i1 %c.1, label %true, label %false 153 154true: 155 br i1 %c, label %true.2, label %false.2 156 157true.2: 158 br label %exit.2 159 160false.2: 161 br label %exit.2 162 163exit.2: 164 %p = phi ptr [ %a, %true.2 ], [ %b, %false.2 ] 165 ret ptr %p 166 167false: 168 ret ptr null 169} 170 171define i32 @f5(i64 %sz) { 172; CHECK-LABEL: @f5( 173; CHECK-NEXT: entry: 174; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 4088, [[SZ:%.*]] 175; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 176; CHECK: cond.true: 177; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]] 178; CHECK-NEXT: br label [[COND_END]] 179; CHECK: cond.end: 180; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ] 181; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32 182; CHECK-NEXT: ret i32 [[CONV]] 183; 184entry: 185 %cmp = icmp ugt i64 4088, %sz 186 br i1 %cmp, label %cond.true, label %cond.end 187 188cond.true: ; preds = %entry 189 %div = udiv i64 4088, %sz 190 br label %cond.end 191 192cond.end: ; preds = %entry, %cond.true 193 %cond = phi i64 [ %div, %cond.true ], [ 1, %entry ] 194 %conv = trunc i64 %cond to i32 195 ret i32 %conv 196} 197 198define void @f6(i32 %b) { 199; CHECK-LABEL: @f6( 200; CHECK-NEXT: entry: 201; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[B:%.*]], 20 202; CHECK-NEXT: br i1 [[C_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 203; CHECK: true: 204; CHECK-NEXT: call void @use(i1 true) 205; CHECK-NEXT: ret void 206; CHECK: false: 207; CHECK-NEXT: ret void 208; 209entry: 210 %a = add i32 10, 10 211 %c.1 = icmp ugt i32 %b, %a 212 br i1 %c.1, label %true, label %false 213 214true: 215 %c.2 = icmp eq i32 %a, 20 216 call void @use(i1 %c.2) 217 ret void 218 219false: 220 ret void 221} 222 223; Test with 2 unrelated nested conditions. 224define void @f7_nested_conds(ptr %a, i32 %b) { 225; CHECK-LABEL: @f7_nested_conds( 226; CHECK-NEXT: entry: 227; CHECK-NEXT: [[A_V:%.*]] = load i32, ptr [[A:%.*]], align 4 228; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[A_V]], 0 229; CHECK-NEXT: br i1 [[C_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 230; CHECK: false: 231; CHECK-NEXT: br label [[TRUE_2:%.*]] 232; CHECK: true.2: 233; CHECK-NEXT: call void @use(i1 true) 234; CHECK-NEXT: ret void 235; CHECK: true: 236; CHECK-NEXT: store i32 [[B:%.*]], ptr [[A]], align 4 237; CHECK-NEXT: ret void 238; 239entry: 240 %a.v = load i32, ptr %a 241 %c.1 = icmp ne i32 %a.v, 0 242 br i1 %c.1, label %true, label %false 243 244false: 245 %c.2 = icmp ult i32 %a.v, 3 246 br i1 %c.2, label %true.2, label %true 247 248true.2: 249 %c.3 = icmp eq i32 %a.v, 0 250 call void @use(i1 %c.3) 251 ret void 252 253true: 254 store i32 %b, ptr %a 255 ret void 256} 257 258; Test with 2 related nested conditions (%b > [20, 276) && %b < 255). 259define void @f8_nested_conds(i32 %a, i32 %b) { 260; CHECK-LABEL: @f8_nested_conds( 261; CHECK-NEXT: entry: 262; CHECK-NEXT: [[A_255:%.*]] = and i32 [[A:%.*]], 255 263; CHECK-NEXT: [[A_2:%.*]] = add nuw nsw i32 [[A_255]], 20 264; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[B:%.*]], [[A_2]] 265; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 266; CHECK: true: 267; CHECK-NEXT: [[BC_2:%.*]] = icmp ult i32 [[B]], 255 268; CHECK-NEXT: br i1 [[BC_2]], label [[TRUE_2:%.*]], label [[FALSE_2:%.*]] 269; CHECK: true.2: 270; CHECK-NEXT: call void @use(i1 false) 271; CHECK-NEXT: call void @use(i1 false) 272; CHECK-NEXT: call void @use(i1 false) 273; CHECK-NEXT: call void @use(i1 false) 274; CHECK-NEXT: call void @use(i1 false) 275; CHECK-NEXT: call void @use(i1 true) 276; CHECK-NEXT: call void @use(i1 true) 277; CHECK-NEXT: call void @use(i1 true) 278; CHECK-NEXT: call void @use(i1 true) 279; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[B]], 21 280; CHECK-NEXT: call void @use(i1 [[C_1]]) 281; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[B]], 21 282; CHECK-NEXT: call void @use(i1 [[C_2]]) 283; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[B]], 34 284; CHECK-NEXT: call void @use(i1 [[C_3]]) 285; CHECK-NEXT: ret void 286; CHECK: false.2: 287; CHECK-NEXT: call void @use(i1 false) 288; CHECK-NEXT: call void @use(i1 false) 289; CHECK-NEXT: call void @use(i1 true) 290; CHECK-NEXT: call void @use(i1 true) 291; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[B]], 255 292; CHECK-NEXT: call void @use(i1 [[C_4]]) 293; CHECK-NEXT: [[C_5:%.*]] = icmp ne i32 [[B]], 275 294; CHECK-NEXT: call void @use(i1 [[C_5]]) 295; CHECK-NEXT: ret void 296; CHECK: false: 297; CHECK-NEXT: ret void 298; 299entry: 300 %a.255 = and i32 %a, 255 301 %a.2 = add i32 %a.255, 20 302 %bc.1 = icmp ugt i32 %b, %a.2 303 br i1 %bc.1, label %true, label %false 304 305true: ; %b in [21, 0) 306 %bc.2 = icmp ult i32 %b, 255 307 br i1 %bc.2, label %true.2, label %false.2 308 309true.2: ; %b in [21, 255) 310 ; Conditions below are false. 311 %f.1 = icmp eq i32 %b, 0 312 call void @use(i1 %f.1) 313 %f.2 = icmp eq i32 %b, 20 314 call void @use(i1 %f.2) 315 %f.3 = icmp ult i32 %b, 20 316 call void @use(i1 %f.3) 317 %f.4 = icmp eq i32 %b, 255 318 call void @use(i1 %f.4) 319 %f.5 = icmp ugt i32 %b, 255 320 call void @use(i1 %f.5) 321 322 323 ; Conditions below are true. 324 %t.1 = icmp ugt i32 %b, 5 325 call void @use(i1 %t.1) 326 %t.2 = icmp ne i32 %b, 20 327 call void @use(i1 %t.2) 328 %t.3 = icmp ult i32 %b, 255 329 call void @use(i1 %t.3) 330 %t.4 = icmp ne i32 %b, 300 331 call void @use(i1 %t.4) 332 333 ; Conditions below cannot be simplified. 334 %c.1 = icmp eq i32 %b, 21 335 call void @use(i1 %c.1) 336 %c.2 = icmp ugt i32 %b, 21 337 call void @use(i1 %c.2) 338 %c.3 = icmp ugt i32 %b, 34 339 call void @use(i1 %c.3) 340 ret void 341 342false.2: ;%b in [255, 0) 343 ; Conditions below are false; 344 %f.6 = icmp eq i32 %b, 254 345 call void @use(i1 %f.6) 346 %f.7 = icmp ult i32 %b, 255 347 call void @use(i1 %f.7) 348 349 ; Conditions below are true; 350 %t.5 = icmp ne i32 %b, 254 351 call void @use(i1 %t.5) 352 %t.6 = icmp uge i32 %b, 255 353 call void @use(i1 %t.6) 354 355 ; Conditions below cannot be simplified. 356 %c.4 = icmp eq i32 %b, 255 357 call void @use(i1 %c.4) 358 %c.5 = icmp ne i32 %b, 275 359 call void @use(i1 %c.5) 360 ret void 361 362false: 363 ret void 364} 365 366; Test with with nested conditions where the second conditions is more limiting than the first one. 367define void @f9_nested_conds(i32 %a, i32 %b) { 368; CHECK-LABEL: @f9_nested_conds( 369; CHECK-NEXT: entry: 370; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[B:%.*]], 10 371; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 372; CHECK: true: 373; CHECK-NEXT: call void @use(i1 false) 374; CHECK-NEXT: call void @use(i1 false) 375; CHECK-NEXT: call void @use(i1 true) 376; CHECK-NEXT: call void @use(i1 true) 377; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[B]], 11 378; CHECK-NEXT: call void @use(i1 [[C_1]]) 379; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[B]], 11 380; CHECK-NEXT: call void @use(i1 [[C_2]]) 381; CHECK-NEXT: [[BC_2:%.*]] = icmp ugt i32 [[B]], 20 382; CHECK-NEXT: br i1 [[BC_2]], label [[TRUE_2:%.*]], label [[FALSE_2:%.*]] 383; CHECK: true.2: 384; CHECK-NEXT: call void @use(i1 false) 385; CHECK-NEXT: call void @use(i1 false) 386; CHECK-NEXT: call void @use(i1 true) 387; CHECK-NEXT: call void @use(i1 true) 388; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[B]], 21 389; CHECK-NEXT: call void @use(i1 [[C_3]]) 390; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[B]], 21 391; CHECK-NEXT: call void @use(i1 [[C_4]]) 392; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[B]], 34 393; CHECK-NEXT: call void @use(i1 [[C_5]]) 394; CHECK-NEXT: ret void 395; CHECK: false.2: 396; CHECK-NEXT: call void @use(i1 false) 397; CHECK-NEXT: call void @use(i1 false) 398; CHECK-NEXT: call void @use(i1 true) 399; CHECK-NEXT: call void @use(i1 true) 400; CHECK-NEXT: call void @use(i1 true) 401; CHECK-NEXT: call void @use(i1 true) 402; CHECK-NEXT: [[C_6:%.*]] = icmp eq i32 [[B]], 11 403; CHECK-NEXT: call void @use(i1 [[C_6]]) 404; CHECK-NEXT: [[C_7:%.*]] = icmp ne i32 [[B]], 15 405; CHECK-NEXT: call void @use(i1 [[C_7]]) 406; CHECK-NEXT: ret void 407; CHECK: false: 408; CHECK-NEXT: ret void 409; 410entry: 411 %bc.1 = icmp ugt i32 %b, 10 412 br i1 %bc.1, label %true, label %false 413 414true: ; %b in [11, 0) 415 ; Conditions below are false. 416 %f.1 = icmp eq i32 %b, 0 417 call void @use(i1 %f.1) 418 %f.2 = icmp eq i32 %b, 10 419 call void @use(i1 %f.2) 420 421 ; Conditions below are true. 422 %t.1 = icmp ugt i32 %b, 5 423 call void @use(i1 %t.1) 424 %t.2 = icmp ne i32 %b, 10 425 call void @use(i1 %t.2) 426 427 ; Conditions below cannot be simplified. 428 %c.1 = icmp eq i32 %b, 11 429 call void @use(i1 %c.1) 430 %c.2 = icmp ugt i32 %b, 11 431 call void @use(i1 %c.2) 432 433 %bc.2 = icmp ugt i32 %b, 20 434 br i1 %bc.2, label %true.2, label %false.2 435 436true.2: ; %b in [21, 0) 437 ; Conditions below are false. 438 %f.3 = icmp eq i32 %b, 11 439 call void @use(i1 %f.3) 440 %f.4 = icmp eq i32 %b, 20 441 call void @use(i1 %f.4) 442 443 ; Conditions below are true. 444 %t.3 = icmp ugt i32 %b, 11 445 call void @use(i1 %t.3) 446 %t.4 = icmp ne i32 %b, 20 447 call void @use(i1 %t.4) 448 449 ; Conditions below cannot be simplified. 450 %c.3 = icmp eq i32 %b, 21 451 call void @use(i1 %c.3) 452 %c.4 = icmp ugt i32 %b, 21 453 call void @use(i1 %c.4) 454 %c.5 = icmp ugt i32 %b, 34 455 call void @use(i1 %c.5) 456 ret void 457 458false.2: ;%b in [11, 21) 459 ; Conditions below are false; 460 %f.5 = icmp eq i32 %b, 21 461 call void @use(i1 %f.5) 462 %f.6 = icmp ugt i32 %b, 21 463 call void @use(i1 %f.6) 464 %f.7 = icmp ne i32 %b, 5 465 call void @use(i1 %f.7) 466 467 ; Conditions below are true; 468 %t.5 = icmp ne i32 %b, 21 469 call void @use(i1 %t.5) 470 %t.6 = icmp ult i32 %b, 21 471 call void @use(i1 %t.6) 472 %t.7 = icmp ne i32 %b, 5 473 call void @use(i1 %t.7) 474 475 ; Conditions below cannot be simplified. 476 %c.6 = icmp eq i32 %b, 11 477 call void @use(i1 %c.6) 478 %c.7 = icmp ne i32 %b, 15 479 call void @use(i1 %c.7) 480 ret void 481 482false: 483 ret void 484} 485 486 487; Test with with nested conditions where the second conditions is more limiting than the first one. 488define void @f10_cond_does_not_restrict_range(i32 %a, i32 %b) { 489; CHECK-LABEL: @f10_cond_does_not_restrict_range( 490; CHECK-NEXT: entry: 491; CHECK-NEXT: [[B_255:%.*]] = and i32 [[B:%.*]], 255 492; CHECK-NEXT: br label [[TRUE:%.*]] 493; CHECK: true: 494; CHECK-NEXT: call void @use(i1 false) 495; CHECK-NEXT: call void @use(i1 false) 496; CHECK-NEXT: call void @use(i1 true) 497; CHECK-NEXT: call void @use(i1 true) 498; CHECK-NEXT: call void @use(i1 true) 499; CHECK-NEXT: call void @use(i1 true) 500; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[B_255]], 11 501; CHECK-NEXT: call void @use(i1 [[C_1]]) 502; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[B_255]], 30 503; CHECK-NEXT: call void @use(i1 [[C_2]]) 504; CHECK-NEXT: ret void 505; 506entry: 507 %b.255 = and i32 %b, 255 508 %bc.1 = icmp ult i32 %b.255, 300 509 br i1 %bc.1, label %true, label %false 510 511true: ; %b in [0, 256) 512 ; Conditions below are false. 513 %f.1 = icmp eq i32 %b.255, 256 514 call void @use(i1 %f.1) 515 %f.2 = icmp eq i32 %b.255, 300 516 call void @use(i1 %f.2) 517 518 ; Conditions below are true. 519 %t.1 = icmp ult i32 %b.255, 256 520 call void @use(i1 %t.1) 521 %t.2 = icmp ult i32 %b.255, 300 522 call void @use(i1 %t.2) 523 %t.3 = icmp ne i32 %b.255, 256 524 call void @use(i1 %t.3) 525 %t.4 = icmp ne i32 %b.255, 300 526 call void @use(i1 %t.4) 527 528 ; Conditions below cannot be simplified. 529 %c.1 = icmp eq i32 %b.255, 11 530 call void @use(i1 %c.1) 531 %c.2 = icmp ugt i32 %b.255, 30 532 call void @use(i1 %c.2) 533 ret void 534 535false: 536 ret void 537} 538 539define void @f11_contradiction(i32 %a, i32 %b) { 540; CHECK-LABEL: @f11_contradiction( 541; CHECK-NEXT: entry: 542; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[B:%.*]], 10 543; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 544; CHECK: true: 545; CHECK-NEXT: br label [[FALSE]] 546; CHECK: false: 547; CHECK-NEXT: ret void 548; 549entry: 550 %bc.1 = icmp eq i32 %b, 10 551 br i1 %bc.1, label %true, label %false 552 553true: ; %b in [10, 11) 554 %bc.2 = icmp eq i32 %b, 20 555 br i1 %bc.2, label %true.2, label %false 556 557true.2: 558 %f.1 = icmp eq i32 %b, 256 559 call void @use(i1 %f.1) 560 %f.2 = icmp ne i32 %b, 300 561 call void @use(i1 %f.2) 562 ret void 563 564false: 565 ret void 566} 567 568define void @f12_float(float %b) { 569; CHECK-LABEL: @f12_float( 570; CHECK-NEXT: entry: 571; CHECK-NEXT: [[BC_1:%.*]] = fcmp olt float 1.000000e+00, [[B:%.*]] 572; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 573; CHECK: true: 574; CHECK-NEXT: call void @use(i1 false) 575; CHECK-NEXT: call void @use(i1 true) 576; CHECK-NEXT: ret void 577; CHECK: false: 578; CHECK-NEXT: ret void 579; 580entry: 581 %a = fadd float 0.0, 1.0 582 %bc.1 = fcmp olt float %a, %b 583 br i1 %bc.1, label %true, label %false 584 585true: ; %b in [10, 11) 586 %f.1 = fcmp one float %a, 1.0 587 call void @use(i1 %f.1) 588 589 %t.1 = fcmp oeq float %a, 1.0 590 call void @use(i1 %t.1) 591 ret void 592 593false: 594 ret void 595} 596 597 598@A = global i32 17 599@B = global i32 17 600 601define void @f13_constexpr1() { 602; CHECK-LABEL: @f13_constexpr1( 603; CHECK-NEXT: entry: 604; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 add (i32 ptrtoint (ptr @A to i32), i32 10), 55 605; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 606; CHECK: true: 607; CHECK-NEXT: call void @use(i1 false) 608; CHECK-NEXT: call void @use(i1 true) 609; CHECK-NEXT: ret void 610; CHECK: false: 611; CHECK-NEXT: ret void 612; 613entry: 614 %a = add i32 ptrtoint (ptr @A to i32), 10 615 %bc.1 = icmp eq i32 %a, 55 616 br i1 %bc.1, label %true, label %false 617 618true: ; %b in [10, 11) 619 %f.1 = icmp eq i32 %a, 10 620 call void @use(i1 %f.1) 621 %f.2 = icmp eq i32 %a, 55 622 call void @use(i1 %f.2) 623 624 ret void 625 626false: 627 ret void 628} 629 630; TODO: can we fold the compares in the true block? 631define void @f14_constexpr2() { 632; CHECK-LABEL: @f14_constexpr2( 633; CHECK-NEXT: entry: 634; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 ptrtoint (ptr @A to i32), ptrtoint (ptr @B to i32) 635; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 636; CHECK: true: 637; CHECK-NEXT: [[F_1:%.*]] = icmp ne i32 ptrtoint (ptr @B to i32), ptrtoint (ptr @A to i32) 638; CHECK-NEXT: call void @use(i1 [[F_1]]) 639; CHECK-NEXT: [[F_2:%.*]] = icmp eq i32 ptrtoint (ptr @B to i32), ptrtoint (ptr @A to i32) 640; CHECK-NEXT: call void @use(i1 [[F_2]]) 641; CHECK-NEXT: ret void 642; CHECK: false: 643; CHECK-NEXT: ret void 644; 645entry: 646 %a = add i32 ptrtoint (ptr @A to i32), 0 647 %b = add i32 ptrtoint (ptr @B to i32), 0 648 %bc.1 = icmp eq i32 %a, %b 649 br i1 %bc.1, label %true, label %false 650 651true: ; %b in [10, 11) 652 %f.1 = icmp ne i32 %a, %b 653 call void @use(i1 %f.1) 654 %f.2 = icmp eq i32 %a, %b 655 call void @use(i1 %f.2) 656 657 ret void 658 659false: 660 ret void 661} 662 663define void @loop_1() { 664; CHECK-LABEL: @loop_1( 665; CHECK-NEXT: entry: 666; CHECK-NEXT: br label [[FOR_COND:%.*]] 667; CHECK: for.cond: 668; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC27:%.*]], [[FOR_COND_CLEANUP13:%.*]] ] 669; CHECK-NEXT: [[CMP9:%.*]] = icmp sle i32 [[I_0]], 3 670; CHECK-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 671; CHECK: for.cond.cleanup: 672; CHECK-NEXT: ret void 673; CHECK: for.body: 674; CHECK-NEXT: br label [[FOR_COND11:%.*]] 675; CHECK: for.cond11: 676; CHECK-NEXT: br label [[FOR_COND_CLEANUP13]] 677; CHECK: for.cond.cleanup13: 678; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1 679; CHECK-NEXT: br label [[FOR_COND]] 680; 681entry: 682 br label %for.cond 683 684for.cond: ; preds = %for.cond.cleanup13, %if.then 685 %i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ] 686 %cmp9 = icmp sle i32 %i.0, 3 687 br i1 %cmp9, label %for.body, label %for.cond.cleanup 688 689for.cond.cleanup: ; preds = %for.cond 690 ret void 691 692for.body: ; preds = %for.cond 693 br label %for.cond11 694 695for.cond11: ; preds = %arrayctor.cont21, %for.body 696 br label %for.cond.cleanup13 697 698for.cond.cleanup13: ; preds = %for.cond11 699 %inc27 = add nsw i32 %i.0, 1 700 br label %for.cond 701} 702 703 704define void @loop() { 705; CHECK-LABEL: @loop( 706; CHECK-NEXT: entry: 707; CHECK-NEXT: br label [[FOR_COND:%.*]] 708; CHECK: for.cond: 709; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC27:%.*]], [[FOR_COND_CLEANUP13:%.*]] ] 710; CHECK-NEXT: [[CMP9:%.*]] = icmp sle i32 [[I_0]], 3 711; CHECK-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 712; CHECK: for.cond.cleanup: 713; CHECK-NEXT: ret void 714; CHECK: for.body: 715; CHECK-NEXT: br label [[FOR_COND11:%.*]] 716; CHECK: for.cond11: 717; CHECK-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[FOR_BODY]] ], [ [[INC:%.*]], [[FOR_BODY14:%.*]] ] 718; CHECK-NEXT: [[CMP12:%.*]] = icmp slt i32 [[J_0]], 2 719; CHECK-NEXT: br i1 [[CMP12]], label [[FOR_BODY14]], label [[FOR_COND_CLEANUP13]] 720; CHECK: for.cond.cleanup13: 721; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1 722; CHECK-NEXT: br label [[FOR_COND]] 723; CHECK: for.body14: 724; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[J_0]], 1 725; CHECK-NEXT: br label [[FOR_COND11]] 726; 727entry: 728 br label %for.cond 729 730for.cond: ; preds = %for.cond.cleanup13, %if.then 731 %i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ] 732 %cmp9 = icmp sle i32 %i.0, 3 733 br i1 %cmp9, label %for.body, label %for.cond.cleanup 734 735for.cond.cleanup: ; preds = %for.cond 736 ret void 737 738for.body: ; preds = %for.cond 739 br label %for.cond11 740 741for.cond11: ; preds = %arrayctor.cont21, %for.body 742 %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.body14 ] 743 %cmp12 = icmp slt i32 %j.0, 2 744 br i1 %cmp12, label %for.body14, label %for.cond.cleanup13 745 746for.cond.cleanup13: ; preds = %for.cond11 747 %inc27 = add nsw i32 %i.0, 1 748 br label %for.cond 749 750for.body14: 751 %inc = add nsw i32 %j.0, 1 752 br label %for.cond11 753} 754 755define i32 @udiv_1(i64 %sz) { 756; CHECK-LABEL: @udiv_1( 757; CHECK-NEXT: entry: 758; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 4088, [[SZ:%.*]] 759; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 760; CHECK: cond.true: 761; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]] 762; CHECK-NEXT: br label [[COND_END]] 763; CHECK: cond.end: 764; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ] 765; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32 766; CHECK-NEXT: ret i32 [[CONV]] 767; 768entry: 769 %cmp = icmp ugt i64 4088, %sz 770 br i1 %cmp, label %cond.true, label %cond.end 771 772cond.true: ; preds = %entry 773 %div = udiv i64 4088, %sz 774 br label %cond.end 775 776cond.end: ; preds = %entry, %cond.true 777 %cond = phi i64 [ %div, %cond.true ], [ 1, %entry ] 778 %conv = trunc i64 %cond to i32 779 ret i32 %conv 780} 781 782; Same as @udiv_1, but with the condition switched. 783define i32 @udiv_2(i64 %sz) { 784; CHECK-LABEL: @udiv_2( 785; CHECK-NEXT: entry: 786; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[SZ:%.*]], 4088 787; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 788; CHECK: cond.true: 789; CHECK-NEXT: br label [[COND_END]] 790; CHECK: cond.end: 791; CHECK-NEXT: [[COND:%.*]] = phi i64 [ 0, [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ] 792; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32 793; CHECK-NEXT: ret i32 [[CONV]] 794; 795entry: 796 %cmp = icmp ugt i64 %sz, 4088 797 br i1 %cmp, label %cond.true, label %cond.end 798 799cond.true: ; preds = %entry 800 %div = udiv i64 4088, %sz 801 br label %cond.end 802 803cond.end: ; preds = %entry, %cond.true 804 %cond = phi i64 [ %div, %cond.true ], [ 1, %entry ] 805 %conv = trunc i64 %cond to i32 806 ret i32 %conv 807} 808 809define void @f16_conditions_and(i32 %a, i32 %b) { 810; CHECK-LABEL: @f16_conditions_and( 811; CHECK-NEXT: entry: 812; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[A:%.*]], 100 813; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[A]], 20 814; CHECK-NEXT: [[BC:%.*]] = and i1 [[LT]], [[GT]] 815; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 816; CHECK: true: 817; CHECK-NEXT: call void @use(i1 false) 818; CHECK-NEXT: call void @use(i1 false) 819; CHECK-NEXT: call void @use(i1 false) 820; CHECK-NEXT: call void @use(i1 true) 821; CHECK-NEXT: call void @use(i1 true) 822; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 823; CHECK-NEXT: call void @use(i1 [[C_1]]) 824; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 825; CHECK-NEXT: call void @use(i1 [[C_2]]) 826; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 827; CHECK-NEXT: call void @use(i1 [[C_3]]) 828; CHECK-NEXT: ret void 829; CHECK: false: 830; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[A]], 50 831; CHECK-NEXT: call void @use(i1 [[F_4]]) 832; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 833; CHECK-NEXT: call void @use(i1 [[T_3]]) 834; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[A]], 10 835; CHECK-NEXT: call void @use(i1 [[C_4]]) 836; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B:%.*]], 100 837; CHECK-NEXT: call void @use(i1 [[C_5]]) 838; CHECK-NEXT: ret void 839; 840entry: 841 %lt = icmp ult i32 %a, 100 842 %gt = icmp ugt i32 %a, 20 843 %bc = and i1 %lt, %gt 844 br i1 %bc, label %true, label %false 845 846true: ; %a in [21, 100) 847 ; Conditions below are false. 848 %f.1 = icmp eq i32 %a, 0 849 call void @use(i1 %f.1) 850 %f.2 = icmp eq i32 %a, 20 851 call void @use(i1 %f.2) 852 %f.3 = icmp ugt i32 %a, 100 853 call void @use(i1 %f.3) 854 855 ; Conditions below are true. 856 %t.1 = icmp ult i32 %a, 100 857 call void @use(i1 %t.1) 858 %t.2 = icmp ne i32 %a, 20 859 call void @use(i1 %t.2) 860 861 ; Conditions below cannot be simplified. 862 %c.1 = icmp eq i32 %a, 21 863 call void @use(i1 %c.1) 864 %c.2 = icmp ugt i32 %a, 21 865 call void @use(i1 %c.2) 866 %c.3 = icmp ugt i32 %a, 50 867 call void @use(i1 %c.3) 868 ret void 869 870false: 871; TODO: Currently there is no conditional range info in the false branch for branch conditions with an AND. 872; %a should be in in [100, 21) 873 ; Conditions below are false; 874 %f.4 = icmp eq i32 %a, 50 875 call void @use(i1 %f.4) 876 877 ; Conditions below are true; 878 %t.3 = icmp ne i32 %a, 50 879 call void @use(i1 %t.3) 880 881 ; Conditions below cannot be simplified. 882 %c.4 = icmp eq i32 %a, 10 883 call void @use(i1 %c.4) 884 %c.5 = icmp eq i32 %b, 100 885 call void @use(i1 %c.5) 886 ret void 887} 888 889define void @f16_conditions_and_logical(i32 %a, i32 %b) { 890; CHECK-LABEL: @f16_conditions_and_logical( 891; CHECK-NEXT: entry: 892; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[A:%.*]], 100 893; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[A]], 20 894; CHECK-NEXT: [[BC:%.*]] = select i1 [[LT]], i1 [[GT]], i1 false 895; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 896; CHECK: true: 897; CHECK-NEXT: call void @use(i1 false) 898; CHECK-NEXT: call void @use(i1 false) 899; CHECK-NEXT: call void @use(i1 false) 900; CHECK-NEXT: call void @use(i1 true) 901; CHECK-NEXT: call void @use(i1 true) 902; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 903; CHECK-NEXT: call void @use(i1 [[C_1]]) 904; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 905; CHECK-NEXT: call void @use(i1 [[C_2]]) 906; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 907; CHECK-NEXT: call void @use(i1 [[C_3]]) 908; CHECK-NEXT: ret void 909; CHECK: false: 910; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[A]], 50 911; CHECK-NEXT: call void @use(i1 [[F_4]]) 912; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 913; CHECK-NEXT: call void @use(i1 [[T_3]]) 914; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[A]], 10 915; CHECK-NEXT: call void @use(i1 [[C_4]]) 916; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B:%.*]], 100 917; CHECK-NEXT: call void @use(i1 [[C_5]]) 918; CHECK-NEXT: ret void 919; 920entry: 921 %lt = icmp ult i32 %a, 100 922 %gt = icmp ugt i32 %a, 20 923 %bc = select i1 %lt, i1 %gt, i1 false 924 br i1 %bc, label %true, label %false 925 926true: ; %a in [21, 100) 927 ; Conditions below are false. 928 %f.1 = icmp eq i32 %a, 0 929 call void @use(i1 %f.1) 930 %f.2 = icmp eq i32 %a, 20 931 call void @use(i1 %f.2) 932 %f.3 = icmp ugt i32 %a, 100 933 call void @use(i1 %f.3) 934 935 ; Conditions below are true. 936 %t.1 = icmp ult i32 %a, 100 937 call void @use(i1 %t.1) 938 %t.2 = icmp ne i32 %a, 20 939 call void @use(i1 %t.2) 940 941 ; Conditions below cannot be simplified. 942 %c.1 = icmp eq i32 %a, 21 943 call void @use(i1 %c.1) 944 %c.2 = icmp ugt i32 %a, 21 945 call void @use(i1 %c.2) 946 %c.3 = icmp ugt i32 %a, 50 947 call void @use(i1 %c.3) 948 ret void 949 950false: 951; TODO: Currently there is no conditional range info in the false branch for branch conditions with an AND. 952; %a should be in in [100, 21) 953 ; Conditions below are false; 954 %f.4 = icmp eq i32 %a, 50 955 call void @use(i1 %f.4) 956 957 ; Conditions below are true; 958 %t.3 = icmp ne i32 %a, 50 959 call void @use(i1 %t.3) 960 961 ; Conditions below cannot be simplified. 962 %c.4 = icmp eq i32 %a, 10 963 call void @use(i1 %c.4) 964 %c.5 = icmp eq i32 %b, 100 965 call void @use(i1 %c.5) 966 ret void 967} 968 969define void @f17_conditions_or(i32 %a, i32 %b) { 970; CHECK-LABEL: @f17_conditions_or( 971; CHECK-NEXT: entry: 972; CHECK-NEXT: [[GT:%.*]] = icmp uge i32 [[A:%.*]], 100 973; CHECK-NEXT: [[LT:%.*]] = icmp ule i32 [[A]], 20 974; CHECK-NEXT: [[BC:%.*]] = or i1 [[LT]], [[GT]] 975; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 976; CHECK: false: 977; CHECK-NEXT: call void @use(i1 false) 978; CHECK-NEXT: call void @use(i1 false) 979; CHECK-NEXT: call void @use(i1 false) 980; CHECK-NEXT: call void @use(i1 true) 981; CHECK-NEXT: call void @use(i1 true) 982; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 983; CHECK-NEXT: call void @use(i1 [[C_1]]) 984; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 985; CHECK-NEXT: call void @use(i1 [[C_2]]) 986; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 987; CHECK-NEXT: call void @use(i1 [[C_3]]) 988; CHECK-NEXT: ret void 989; CHECK: true: 990; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[A]], 50 991; CHECK-NEXT: call void @use(i1 [[F_4]]) 992; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 993; CHECK-NEXT: call void @use(i1 [[T_3]]) 994; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[A]], 10 995; CHECK-NEXT: call void @use(i1 [[C_4]]) 996; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B:%.*]], 100 997; CHECK-NEXT: call void @use(i1 [[C_5]]) 998; CHECK-NEXT: ret void 999; 1000entry: 1001 %gt = icmp uge i32 %a, 100 1002 %lt = icmp ule i32 %a, 20 1003 %bc = or i1 %lt, %gt 1004 br i1 %bc, label %true, label %false 1005 1006false: ; %a in [21, 100) 1007 ; Conditions below are false. 1008 %f.1 = icmp eq i32 %a, 0 1009 call void @use(i1 %f.1) 1010 %f.2 = icmp eq i32 %a, 20 1011 call void @use(i1 %f.2) 1012 %f.3 = icmp ugt i32 %a, 100 1013 call void @use(i1 %f.3) 1014 1015 ; Conditions below are true. 1016 %t.1 = icmp ult i32 %a, 100 1017 call void @use(i1 %t.1) 1018 %t.2 = icmp ne i32 %a, 20 1019 call void @use(i1 %t.2) 1020 1021 ; Conditions below cannot be simplified. 1022 %c.1 = icmp eq i32 %a, 21 1023 call void @use(i1 %c.1) 1024 %c.2 = icmp ugt i32 %a, 21 1025 call void @use(i1 %c.2) 1026 %c.3 = icmp ugt i32 %a, 50 1027 call void @use(i1 %c.3) 1028 ret void 1029 1030true: 1031; TODO: Currently there is no conditional range info in the false branch for branch conditions with an AND. 1032; %a should be in in [100, 21) 1033 ; Conditions below are false; 1034 %f.4 = icmp eq i32 %a, 50 1035 call void @use(i1 %f.4) 1036 1037 ; Conditions below are true; 1038 %t.3 = icmp ne i32 %a, 50 1039 call void @use(i1 %t.3) 1040 1041 ; Conditions below cannot be simplified. 1042 %c.4 = icmp eq i32 %a, 10 1043 call void @use(i1 %c.4) 1044 %c.5 = icmp eq i32 %b, 100 1045 call void @use(i1 %c.5) 1046 ret void 1047} 1048 1049define void @f17_conditions_or_logical(i32 %a, i32 %b) { 1050; CHECK-LABEL: @f17_conditions_or_logical( 1051; CHECK-NEXT: entry: 1052; CHECK-NEXT: [[GT:%.*]] = icmp uge i32 [[A:%.*]], 100 1053; CHECK-NEXT: [[LT:%.*]] = icmp ule i32 [[A]], 20 1054; CHECK-NEXT: [[BC:%.*]] = select i1 [[LT]], i1 true, i1 [[GT]] 1055; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 1056; CHECK: false: 1057; CHECK-NEXT: call void @use(i1 false) 1058; CHECK-NEXT: call void @use(i1 false) 1059; CHECK-NEXT: call void @use(i1 false) 1060; CHECK-NEXT: call void @use(i1 true) 1061; CHECK-NEXT: call void @use(i1 true) 1062; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 1063; CHECK-NEXT: call void @use(i1 [[C_1]]) 1064; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 1065; CHECK-NEXT: call void @use(i1 [[C_2]]) 1066; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 1067; CHECK-NEXT: call void @use(i1 [[C_3]]) 1068; CHECK-NEXT: ret void 1069; CHECK: true: 1070; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[A]], 50 1071; CHECK-NEXT: call void @use(i1 [[F_4]]) 1072; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 1073; CHECK-NEXT: call void @use(i1 [[T_3]]) 1074; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[A]], 10 1075; CHECK-NEXT: call void @use(i1 [[C_4]]) 1076; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B:%.*]], 100 1077; CHECK-NEXT: call void @use(i1 [[C_5]]) 1078; CHECK-NEXT: ret void 1079; 1080entry: 1081 %gt = icmp uge i32 %a, 100 1082 %lt = icmp ule i32 %a, 20 1083 %bc = select i1 %lt, i1 true, i1 %gt 1084 br i1 %bc, label %true, label %false 1085 1086false: ; %a in [21, 100) 1087 ; Conditions below are false. 1088 %f.1 = icmp eq i32 %a, 0 1089 call void @use(i1 %f.1) 1090 %f.2 = icmp eq i32 %a, 20 1091 call void @use(i1 %f.2) 1092 %f.3 = icmp ugt i32 %a, 100 1093 call void @use(i1 %f.3) 1094 1095 ; Conditions below are true. 1096 %t.1 = icmp ult i32 %a, 100 1097 call void @use(i1 %t.1) 1098 %t.2 = icmp ne i32 %a, 20 1099 call void @use(i1 %t.2) 1100 1101 ; Conditions below cannot be simplified. 1102 %c.1 = icmp eq i32 %a, 21 1103 call void @use(i1 %c.1) 1104 %c.2 = icmp ugt i32 %a, 21 1105 call void @use(i1 %c.2) 1106 %c.3 = icmp ugt i32 %a, 50 1107 call void @use(i1 %c.3) 1108 ret void 1109 1110true: 1111; TODO: Currently there is no conditional range info in the false branch for branch conditions with an AND. 1112; %a should be in in [100, 21) 1113 ; Conditions below are false; 1114 %f.4 = icmp eq i32 %a, 50 1115 call void @use(i1 %f.4) 1116 1117 ; Conditions below are true; 1118 %t.3 = icmp ne i32 %a, 50 1119 call void @use(i1 %t.3) 1120 1121 ; Conditions below cannot be simplified. 1122 %c.4 = icmp eq i32 %a, 10 1123 call void @use(i1 %c.4) 1124 %c.5 = icmp eq i32 %b, 100 1125 call void @use(i1 %c.5) 1126 ret void 1127} 1128 1129define void @f18_conditions_chained_and(i32 %a, i32 %b) { 1130; CHECK-LABEL: @f18_conditions_chained_and( 1131; CHECK-NEXT: entry: 1132; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[A:%.*]], 100 1133; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[A]], 20 1134; CHECK-NEXT: [[BC:%.*]] = and i1 [[LT]], [[GT]] 1135; CHECK-NEXT: [[B_LT:%.*]] = icmp ult i32 [[B:%.*]], 50 1136; CHECK-NEXT: [[BC_2:%.*]] = and i1 [[BC]], [[B_LT]] 1137; CHECK-NEXT: br i1 [[BC_2]], label [[TRUE:%.*]], label [[FALSE:%.*]] 1138; CHECK: true: 1139; CHECK-NEXT: call void @use(i1 false) 1140; CHECK-NEXT: call void @use(i1 false) 1141; CHECK-NEXT: call void @use(i1 false) 1142; CHECK-NEXT: call void @use(i1 false) 1143; CHECK-NEXT: call void @use(i1 true) 1144; CHECK-NEXT: call void @use(i1 true) 1145; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 1146; CHECK-NEXT: call void @use(i1 [[C_1]]) 1147; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 1148; CHECK-NEXT: call void @use(i1 [[C_2]]) 1149; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 1150; CHECK-NEXT: call void @use(i1 [[C_3]]) 1151; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[B]], 0 1152; CHECK-NEXT: call void @use(i1 [[C_4]]) 1153; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[B]], 20 1154; CHECK-NEXT: call void @use(i1 [[C_5]]) 1155; CHECK-NEXT: ret void 1156; CHECK: false: 1157; CHECK-NEXT: [[F_5:%.*]] = icmp eq i32 [[A]], 50 1158; CHECK-NEXT: call void @use(i1 [[F_5]]) 1159; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 1160; CHECK-NEXT: call void @use(i1 [[T_3]]) 1161; CHECK-NEXT: [[C_6:%.*]] = icmp eq i32 [[A]], 10 1162; CHECK-NEXT: call void @use(i1 [[C_6]]) 1163; CHECK-NEXT: [[C_7:%.*]] = icmp eq i32 [[B]], 100 1164; CHECK-NEXT: call void @use(i1 [[C_7]]) 1165; CHECK-NEXT: ret void 1166; 1167entry: 1168 %lt = icmp ult i32 %a, 100 1169 %gt = icmp ugt i32 %a, 20 1170 %bc = and i1 %lt, %gt 1171 %b.lt = icmp ult i32 %b, 50 1172 %bc.2 = and i1 %bc, %b.lt 1173 br i1 %bc.2, label %true, label %false 1174 1175true: ; %a in [21, 100) 1176 ; Conditions below are false. 1177 %f.1 = icmp eq i32 %a, 0 1178 call void @use(i1 %f.1) 1179 %f.2 = icmp eq i32 %a, 20 1180 call void @use(i1 %f.2) 1181 %f.3 = icmp ugt i32 %a, 100 1182 call void @use(i1 %f.3) 1183 %f.4 = icmp ugt i32 %b, 100 1184 call void @use(i1 %f.4) 1185 1186 1187 ; Conditions below are true. 1188 %t.1 = icmp ult i32 %a, 100 1189 call void @use(i1 %t.1) 1190 %t.2 = icmp ne i32 %a, 20 1191 call void @use(i1 %t.2) 1192 1193 ; Conditions below cannot be simplified. 1194 %c.1 = icmp eq i32 %a, 21 1195 call void @use(i1 %c.1) 1196 %c.2 = icmp ugt i32 %a, 21 1197 call void @use(i1 %c.2) 1198 %c.3 = icmp ugt i32 %a, 50 1199 call void @use(i1 %c.3) 1200 %c.4 = icmp eq i32 %b, 0 1201 call void @use(i1 %c.4) 1202 %c.5 = icmp eq i32 %b, 20 1203 call void @use(i1 %c.5) 1204 ret void 1205 1206false: 1207 ; Conditions below are false; 1208 %f.5 = icmp eq i32 %a, 50 1209 call void @use(i1 %f.5) 1210 1211 ; Conditions below are true; 1212 %t.3 = icmp ne i32 %a, 50 1213 call void @use(i1 %t.3) 1214 1215 ; Conditions below cannot be simplified. 1216 %c.6 = icmp eq i32 %a, 10 1217 call void @use(i1 %c.6) 1218 %c.7 = icmp eq i32 %b, 100 1219 call void @use(i1 %c.7) 1220 ret void 1221} 1222 1223define void @f19_conditions_chained_and_nested_and(i32 %a, i32 %b) { 1224; CHECK-LABEL: @f19_conditions_chained_and_nested_and( 1225; CHECK-NEXT: entry: 1226; CHECK-NEXT: [[LT_A:%.*]] = icmp ult i32 [[A:%.*]], 100 1227; CHECK-NEXT: [[LT_B:%.*]] = icmp ult i32 [[B:%.*]], 1000 1228; CHECK-NEXT: [[BC:%.*]] = and i1 [[LT_A]], [[LT_B]] 1229; CHECK-NEXT: br i1 [[BC]], label [[TRUE:%.*]], label [[FALSE:%.*]] 1230; CHECK: true: 1231; CHECK-NEXT: [[GT_A:%.*]] = icmp ugt i32 [[A]], 30 1232; CHECK-NEXT: [[GT_B:%.*]] = icmp ugt i32 [[B]], 300 1233; CHECK-NEXT: [[BC_2:%.*]] = and i1 [[GT_A]], [[GT_B]] 1234; CHECK-NEXT: br i1 [[BC_2]], label [[TRUE_2:%.*]], label [[FALSE]] 1235; CHECK: true.2: 1236; CHECK-NEXT: call void @use(i1 false) 1237; CHECK-NEXT: call void @use(i1 false) 1238; CHECK-NEXT: call void @use(i1 false) 1239; CHECK-NEXT: call void @use(i1 false) 1240; CHECK-NEXT: call void @use(i1 false) 1241; CHECK-NEXT: call void @use(i1 false) 1242; CHECK-NEXT: call void @use(i1 true) 1243; CHECK-NEXT: call void @use(i1 true) 1244; CHECK-NEXT: call void @use(i1 true) 1245; CHECK-NEXT: call void @use(i1 true) 1246; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 31 1247; CHECK-NEXT: call void @use(i1 [[C_1]]) 1248; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 31 1249; CHECK-NEXT: call void @use(i1 [[C_2]]) 1250; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i32 [[A]], 50 1251; CHECK-NEXT: call void @use(i1 [[C_3]]) 1252; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[B]], 301 1253; CHECK-NEXT: call void @use(i1 [[C_4]]) 1254; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i32 [[B]], 301 1255; CHECK-NEXT: call void @use(i1 [[C_5]]) 1256; CHECK-NEXT: [[C_6:%.*]] = icmp ugt i32 [[B]], 500 1257; CHECK-NEXT: call void @use(i1 [[C_6]]) 1258; CHECK-NEXT: ret void 1259; CHECK: false: 1260; CHECK-NEXT: ret void 1261; 1262entry: 1263 %lt.a = icmp ult i32 %a, 100 1264 %lt.b = icmp ult i32 %b, 1000 1265 %bc = and i1 %lt.a, %lt.b 1266 br i1 %bc, label %true, label %false 1267 1268true: 1269 %gt.a = icmp ugt i32 %a, 30 1270 %gt.b = icmp ugt i32 %b, 300 1271 %bc.2 = and i1 %gt.a, %gt.b 1272 br i1 %bc.2, label %true.2, label %false 1273 1274true.2: 1275 ; Conditions below are false. 1276 %f.1 = icmp eq i32 %a, 0 1277 call void @use(i1 %f.1) 1278 %f.2 = icmp eq i32 %a, 20 1279 call void @use(i1 %f.2) 1280 %f.3 = icmp ugt i32 %a, 100 1281 call void @use(i1 %f.3) 1282 %f.4 = icmp eq i32 %b, 0 1283 call void @use(i1 %f.4) 1284 %f.5 = icmp eq i32 %b, 300 1285 call void @use(i1 %f.5) 1286 %f.6 = icmp ugt i32 %b, 1000 1287 call void @use(i1 %f.6) 1288 1289 1290 ; Conditions below are true. 1291 %t.1 = icmp ult i32 %a, 100 1292 call void @use(i1 %t.1) 1293 %t.2 = icmp ne i32 %a, 20 1294 call void @use(i1 %t.2) 1295 %t.3 = icmp ult i32 %b, 1000 1296 call void @use(i1 %t.3) 1297 %t.4 = icmp ne i32 %b, 300 1298 call void @use(i1 %t.4) 1299 1300 1301 ; Conditions below cannot be simplified. 1302 %c.1 = icmp eq i32 %a, 31 1303 call void @use(i1 %c.1) 1304 %c.2 = icmp ugt i32 %a, 31 1305 call void @use(i1 %c.2) 1306 %c.3 = icmp ugt i32 %a, 50 1307 call void @use(i1 %c.3) 1308 %c.4 = icmp eq i32 %b, 301 1309 call void @use(i1 %c.4) 1310 %c.5 = icmp ugt i32 %b, 301 1311 call void @use(i1 %c.5) 1312 %c.6 = icmp ugt i32 %b, 500 1313 call void @use(i1 %c.6) 1314 1315 ret void 1316 1317false: 1318 ret void 1319} 1320 1321declare i64 @get_i64() 1322 1323declare i1 @cond() 1324 1325define void @f20_ne_0_nuked_by_and(i32 %arg) local_unnamed_addr #0 { 1326; CHECK-LABEL: @f20_ne_0_nuked_by_and( 1327; CHECK-NEXT: bb11: 1328; CHECK-NEXT: br label [[BB122:%.*]] 1329; CHECK: bb122: 1330; CHECK-NEXT: [[TMP123:%.*]] = phi i32 [ 256, [[BB11:%.*]] ], [ [[TMP136:%.*]], [[BB135:%.*]] ] 1331; CHECK-NEXT: [[TMP127:%.*]] = call i64 @get_i64() 1332; CHECK-NEXT: [[TMP128:%.*]] = trunc i64 [[TMP127]] to i32 1333; CHECK-NEXT: [[TMP131:%.*]] = icmp ne i32 [[TMP128]], 0 1334; CHECK-NEXT: [[TMP132:%.*]] = icmp sgt i32 [[TMP123]], [[TMP128]] 1335; CHECK-NEXT: [[TMP133:%.*]] = and i1 [[TMP131]], [[TMP132]] 1336; CHECK-NEXT: br i1 [[TMP133]], label [[BB134:%.*]], label [[BB135]] 1337; CHECK: bb134: 1338; CHECK-NEXT: br label [[BB135]] 1339; CHECK: bb135: 1340; CHECK-NEXT: [[TMP136]] = phi i32 [ [[TMP123]], [[BB122]] ], [ [[TMP128]], [[BB134]] ] 1341; CHECK-NEXT: [[BC:%.*]] = call i1 @cond() 1342; CHECK-NEXT: br i1 [[BC]], label [[BB139:%.*]], label [[BB122]] 1343; CHECK: bb139: 1344; CHECK-NEXT: call void @use(i1 false) 1345; CHECK-NEXT: ret void 1346; 1347bb11: ; preds = %bb1 1348 br label %bb122 1349 1350bb122: ; preds = %bb135, %bb120 1351 %tmp123 = phi i32 [ 256, %bb11 ], [ %tmp136, %bb135 ] 1352 %tmp127 = call i64 @get_i64() 1353 %tmp128 = trunc i64 %tmp127 to i32 1354 %tmp131 = icmp ne i32 %tmp128, 0 1355 %tmp132 = icmp sgt i32 %tmp123, %tmp128 1356 %tmp133 = and i1 %tmp131, %tmp132 1357 br i1 %tmp133, label %bb134, label %bb135 1358 1359bb134: ; preds = %bb122 1360 br label %bb135 1361 1362bb135: ; preds = %bb134, %bb122 1363 %tmp136 = phi i32 [ %tmp123, %bb122 ], [ %tmp128, %bb134 ] 1364 %bc = call i1 @cond() 1365 br i1 %bc, label %bb139, label %bb122 1366 1367bb139: ; preds = %bb135 1368 %tmp140 = icmp eq i32 %tmp136, 0 1369 call void @use(i1 %tmp140) 1370 ret void 1371 1372bb142: ; preds = %bb139 1373 ret void 1374} 1375 1376define i32 @equal_not_constant(ptr noundef %p, ptr noundef %q) { 1377; CHECK-LABEL: @equal_not_constant( 1378; CHECK-NEXT: entry: 1379; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P:%.*]], null 1380; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1381; CHECK: if.then: 1382; CHECK-NEXT: [[CMP_THEN:%.*]] = icmp eq ptr [[P]], [[Q:%.*]] 1383; CHECK-NEXT: br i1 [[CMP_THEN]], label [[IF_THEN1:%.*]], label [[IF_END]] 1384; CHECK: if.then1: 1385; CHECK-NEXT: call void @use(i1 true) 1386; CHECK-NEXT: br label [[IF_END]] 1387; CHECK: if.end: 1388; CHECK-NEXT: ret i32 0 1389; 1390entry: 1391 %cmp = icmp ne ptr %p, null 1392 br i1 %cmp, label %if.then, label %if.end 1393 1394if.then: ; preds = %entry 1395 %cmp.then = icmp eq ptr %p, %q 1396 br i1 %cmp.then, label %if.then1, label %if.end 1397 1398if.then1: ; preds = %if.then 1399 %cmp.then1 = icmp ne ptr %q, null 1400 call void @use(i1 %cmp.then1) 1401 br label %if.end 1402 1403if.end: 1404 ret i32 0 1405} 1406 1407define i32 @not_equal_not_constant(ptr noundef %p, ptr noundef %q) { 1408; CHECK-LABEL: @not_equal_not_constant( 1409; CHECK-NEXT: entry: 1410; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P:%.*]], null 1411; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1412; CHECK: if.then: 1413; CHECK-NEXT: [[CMP_THEN:%.*]] = icmp ne ptr [[P]], [[Q:%.*]] 1414; CHECK-NEXT: br i1 [[CMP_THEN]], label [[IF_THEN1:%.*]], label [[IF_END]] 1415; CHECK: if.then1: 1416; CHECK-NEXT: [[CMP_THEN1:%.*]] = icmp ne ptr [[Q]], null 1417; CHECK-NEXT: call void @use(i1 [[CMP_THEN1]]) 1418; CHECK-NEXT: br label [[IF_END]] 1419; CHECK: if.end: 1420; CHECK-NEXT: ret i32 0 1421; 1422entry: 1423 %cmp = icmp ne ptr %p, null 1424 br i1 %cmp, label %if.then, label %if.end 1425 1426if.then: ; preds = %entry 1427 %cmp.then = icmp ne ptr %p, %q 1428 br i1 %cmp.then, label %if.then1, label %if.end 1429 1430if.then1: ; preds = %if.then 1431 %cmp.then1 = icmp ne ptr %q, null 1432 call void @use(i1 %cmp.then1) 1433 br label %if.end 1434 1435if.end: 1436 ret i32 0 1437} 1438 1439define i1 @ptr_icmp_data_layout() { 1440; CHECK-LABEL: @ptr_icmp_data_layout( 1441; CHECK-NEXT: ret i1 false 1442; 1443 %a.end = getelementptr i32, ptr @A, i64 1 1444 %cmp = icmp eq ptr %a.end, @A 1445 ret i1 %cmp 1446} 1447