1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -correlated-propagation -S < %s | FileCheck %s 3 4declare i32 @foo() 5 6define i32 @test1(i32 %a) nounwind { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 9; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8 10; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 11; CHECK: then: 12; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 13; CHECK: else: 14; CHECK-NEXT: ret i32 1 15; CHECK: end: 16; CHECK-NEXT: ret i32 2 17; 18 %a.off = add i32 %a, -8 19 %cmp = icmp ult i32 %a.off, 8 20 br i1 %cmp, label %then, label %else 21 22then: 23 %dead = icmp eq i32 %a, 7 24 br i1 %dead, label %end, label %else 25 26else: 27 ret i32 1 28 29end: 30 ret i32 2 31} 32 33define i32 @test2(i32 %a) nounwind { 34; CHECK-LABEL: @test2( 35; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 36; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8 37; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 38; CHECK: then: 39; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 40; CHECK: else: 41; CHECK-NEXT: ret i32 1 42; CHECK: end: 43; CHECK-NEXT: ret i32 2 44; 45 %a.off = add i32 %a, -8 46 %cmp = icmp ult i32 %a.off, 8 47 br i1 %cmp, label %then, label %else 48 49then: 50 %dead = icmp ugt i32 %a, 15 51 br i1 %dead, label %end, label %else 52 53else: 54 ret i32 1 55 56end: 57 ret i32 2 58} 59 60define i32 @test3(i32 %c) nounwind { 61; CHECK-LABEL: @test3( 62; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 2 63; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 64; CHECK: if.then: 65; CHECK-NEXT: ret i32 1 66; CHECK: if.end: 67; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 3 68; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END8:%.*]] 69; CHECK: if.then2: 70; CHECK-NEXT: br i1 true, label [[IF_THEN4:%.*]], label [[IF_END6:%.*]] 71; CHECK: if.end6: 72; CHECK-NEXT: ret i32 2 73; CHECK: if.then4: 74; CHECK-NEXT: ret i32 3 75; CHECK: if.end8: 76; CHECK-NEXT: ret i32 4 77; 78 %cmp = icmp slt i32 %c, 2 79 br i1 %cmp, label %if.then, label %if.end 80 81if.then: 82 ret i32 1 83 84if.end: 85 %cmp1 = icmp slt i32 %c, 3 86 br i1 %cmp1, label %if.then2, label %if.end8 87 88if.then2: 89 %cmp2 = icmp eq i32 %c, 2 90 br i1 %cmp2, label %if.then4, label %if.end6 91 92if.end6: 93 ret i32 2 94 95if.then4: 96 ret i32 3 97 98if.end8: 99 ret i32 4 100} 101 102define i32 @test4(i32 %c) nounwind { 103; CHECK-LABEL: @test4( 104; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [ 105; CHECK-NEXT: i32 1, label [[SW_BB:%.*]] 106; CHECK-NEXT: i32 2, label [[SW_BB]] 107; CHECK-NEXT: i32 4, label [[SW_BB]] 108; CHECK-NEXT: ] 109; CHECK: sw.bb: 110; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_END:%.*]] 111; CHECK: if.then: 112; CHECK-NEXT: br label [[RETURN:%.*]] 113; CHECK: if.end: 114; CHECK-NEXT: br label [[RETURN]] 115; CHECK: sw.default: 116; CHECK-NEXT: br label [[RETURN]] 117; CHECK: return: 118; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 42, [[SW_DEFAULT]] ], [ 4, [[IF_THEN]] ], [ 9, [[IF_END]] ] 119; CHECK-NEXT: ret i32 [[RETVAL_0]] 120; 121 switch i32 %c, label %sw.default [ 122 i32 1, label %sw.bb 123 i32 2, label %sw.bb 124 i32 4, label %sw.bb 125 ] 126 127sw.bb: 128 %cmp = icmp sge i32 %c, 1 129 br i1 %cmp, label %if.then, label %if.end 130 131if.then: 132 br label %return 133 134if.end: 135 br label %return 136 137sw.default: 138 br label %return 139 140return: 141 %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ] 142 ret i32 %retval.0 143} 144 145define i1 @test5(i32 %c) nounwind { 146; CHECK-LABEL: @test5( 147; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 5 148; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 149; CHECK: if.then: 150; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[C]], 4 151; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END]], label [[IF_END8:%.*]] 152; CHECK: if.end: 153; CHECK-NEXT: ret i1 true 154; CHECK: if.end8: 155; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[C]], 3 156; CHECK-NEXT: [[OR:%.*]] = or i1 false, false 157; CHECK-NEXT: ret i1 [[CMP2]] 158; 159 %cmp = icmp slt i32 %c, 5 160 br i1 %cmp, label %if.then, label %if.end 161 162if.then: 163 %cmp1 = icmp eq i32 %c, 4 164 br i1 %cmp1, label %if.end, label %if.end8 165 166if.end: 167 ret i1 true 168 169if.end8: 170 %cmp2 = icmp eq i32 %c, 3 171 %cmp3 = icmp eq i32 %c, 4 172 %cmp4 = icmp eq i32 %c, 6 173 %or = or i1 %cmp3, %cmp4 174 ret i1 %cmp2 175} 176 177define i1 @test6(i32 %c) nounwind { 178; CHECK-LABEL: @test6( 179; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[C:%.*]], 7 180; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 181; CHECK: if.then: 182; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[C]], 6 183; CHECK-NEXT: br i1 [[COND]], label [[SW_BB:%.*]], label [[IF_END]] 184; CHECK: if.end: 185; CHECK-NEXT: ret i1 true 186; CHECK: sw.bb: 187; CHECK-NEXT: ret i1 true 188; 189 %cmp = icmp ule i32 %c, 7 190 br i1 %cmp, label %if.then, label %if.end 191 192if.then: 193 switch i32 %c, label %if.end [ 194 i32 6, label %sw.bb 195 i32 8, label %sw.bb 196 ] 197 198if.end: 199 ret i1 true 200 201sw.bb: 202 %cmp2 = icmp eq i32 %c, 6 203 ret i1 %cmp2 204} 205 206define i1 @test7(i32 %c) nounwind { 207; CHECK-LABEL: @test7( 208; CHECK-NEXT: entry: 209; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [ 210; CHECK-NEXT: i32 6, label [[SW_BB:%.*]] 211; CHECK-NEXT: i32 7, label [[SW_BB]] 212; CHECK-NEXT: ] 213; CHECK: sw.bb: 214; CHECK-NEXT: ret i1 true 215; CHECK: sw.default: 216; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[C]], 5 217; CHECK-NEXT: [[CMP8:%.*]] = icmp eq i32 [[C]], 8 218; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP5]], false 219; CHECK-NEXT: [[OR2:%.*]] = or i1 false, [[CMP8]] 220; CHECK-NEXT: ret i1 false 221; 222entry: 223 switch i32 %c, label %sw.default [ 224 i32 6, label %sw.bb 225 i32 7, label %sw.bb 226 ] 227 228sw.bb: 229 ret i1 true 230 231sw.default: 232 %cmp5 = icmp eq i32 %c, 5 233 %cmp6 = icmp eq i32 %c, 6 234 %cmp7 = icmp eq i32 %c, 7 235 %cmp8 = icmp eq i32 %c, 8 236 %or = or i1 %cmp5, %cmp6 237 %or2 = or i1 %cmp7, %cmp8 238 ret i1 false 239} 240 241define i1 @test8(i64* %p) { 242; CHECK-LABEL: @test8( 243; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, !range [[RNG0:![0-9]+]] 244; CHECK-NEXT: ret i1 false 245; 246 %a = load i64, i64* %p, !range !{i64 4, i64 255} 247 %res = icmp eq i64 %a, 0 248 ret i1 %res 249} 250 251define i1 @test9(i64* %p) { 252; CHECK-LABEL: @test9( 253; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, !range [[RNG1:![0-9]+]] 254; CHECK-NEXT: ret i1 true 255; 256 %a = load i64, i64* %p, !range !{i64 0, i64 1} 257 %res = icmp eq i64 %a, 0 258 ret i1 %res 259} 260 261define i1 @test10(i64* %p) { 262; CHECK-LABEL: @test10( 263; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, !range [[RNG2:![0-9]+]] 264; CHECK-NEXT: ret i1 false 265; 266 %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20} 267 %res = icmp eq i64 %a, 0 268 ret i1 %res 269} 270 271@g = external global i32 272 273define i1 @test11() { 274; CHECK-LABEL: @test11( 275; CHECK-NEXT: [[POSITIVE:%.*]] = load i32, i32* @g, align 4, !range [[RNG3:![0-9]+]] 276; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[POSITIVE]], 1 277; CHECK-NEXT: br label [[NEXT:%.*]] 278; CHECK: next: 279; CHECK-NEXT: ret i1 true 280; 281 %positive = load i32, i32* @g, !range !{i32 1, i32 2048} 282 %add = add i32 %positive, 1 283 %test = icmp sgt i32 %add, 0 284 br label %next 285 286next: 287 ret i1 %test 288} 289 290define i32 @test12(i32 %a, i32 %b) { 291; CHECK-LABEL: @test12( 292; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 293; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 294; CHECK: then: 295; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 296; CHECK: else: 297; CHECK-NEXT: ret i32 1 298; CHECK: end: 299; CHECK-NEXT: ret i32 2 300; 301 %cmp = icmp ult i32 %a, %b 302 br i1 %cmp, label %then, label %else 303 304then: 305 %dead = icmp eq i32 %a, -1 306 br i1 %dead, label %end, label %else 307 308else: 309 ret i32 1 310 311end: 312 ret i32 2 313} 314 315define i32 @test12_swap(i32 %a, i32 %b) { 316; CHECK-LABEL: @test12_swap( 317; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A:%.*]] 318; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 319; CHECK: then: 320; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 321; CHECK: else: 322; CHECK-NEXT: ret i32 1 323; CHECK: end: 324; CHECK-NEXT: ret i32 2 325; 326 %cmp = icmp ugt i32 %b, %a 327 br i1 %cmp, label %then, label %else 328 329then: 330 %dead = icmp eq i32 %a, -1 331 br i1 %dead, label %end, label %else 332 333else: 334 ret i32 1 335 336end: 337 ret i32 2 338} 339 340; The same as @test12 but the second check is on the false path 341 342define i32 @test12_neg(i32 %a, i32 %b) { 343; CHECK-LABEL: @test12_neg( 344; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 345; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 346; CHECK: else: 347; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], -1 348; CHECK-NEXT: br i1 [[ALIVE]], label [[END:%.*]], label [[THEN]] 349; CHECK: then: 350; CHECK-NEXT: ret i32 1 351; CHECK: end: 352; CHECK-NEXT: ret i32 2 353; 354 %cmp = icmp ult i32 %a, %b 355 br i1 %cmp, label %then, label %else 356 357else: 358 %alive = icmp eq i32 %a, -1 359 br i1 %alive, label %end, label %then 360 361then: 362 ret i32 1 363 364end: 365 ret i32 2 366} 367 368; The same as @test12 but with signed comparison 369 370define i32 @test12_signed(i32 %a, i32 %b) { 371; CHECK-LABEL: @test12_signed( 372; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 373; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 374; CHECK: then: 375; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 376; CHECK: else: 377; CHECK-NEXT: ret i32 1 378; CHECK: end: 379; CHECK-NEXT: ret i32 2 380; 381 %cmp = icmp slt i32 %a, %b 382 br i1 %cmp, label %then, label %else 383 384then: 385 %dead = icmp eq i32 %a, 2147483647 386 br i1 %dead, label %end, label %else 387 388else: 389 ret i32 1 390 391end: 392 ret i32 2 393} 394 395define i32 @test13(i32 %a, i32 %b) { 396; CHECK-LABEL: @test13( 397; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 398; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], [[B:%.*]] 399; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 400; CHECK: then: 401; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 402; CHECK: else: 403; CHECK-NEXT: ret i32 1 404; CHECK: end: 405; CHECK-NEXT: ret i32 2 406; 407 %a.off = add i32 %a, -8 408 %cmp = icmp ult i32 %a.off, %b 409 br i1 %cmp, label %then, label %else 410 411then: 412 %dead = icmp eq i32 %a, 7 413 br i1 %dead, label %end, label %else 414 415else: 416 ret i32 1 417 418end: 419 ret i32 2 420} 421 422define i32 @test13_swap(i32 %a, i32 %b) { 423; CHECK-LABEL: @test13_swap( 424; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 425; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A_OFF]] 426; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 427; CHECK: then: 428; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]] 429; CHECK: else: 430; CHECK-NEXT: ret i32 1 431; CHECK: end: 432; CHECK-NEXT: ret i32 2 433; 434 %a.off = add i32 %a, -8 435 %cmp = icmp ugt i32 %b, %a.off 436 br i1 %cmp, label %then, label %else 437 438then: 439 %dead = icmp eq i32 %a, 7 440 br i1 %dead, label %end, label %else 441 442else: 443 ret i32 1 444 445end: 446 ret i32 2 447} 448 449define i1 @test14_slt(i32 %a) { 450; CHECK-LABEL: @test14_slt( 451; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 452; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A_OFF]], 8 453; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 454; CHECK: then: 455; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false 456; CHECK-NEXT: ret i1 false 457; CHECK: else: 458; CHECK-NEXT: ret i1 false 459; 460 %a.off = add i32 %a, -8 461 %cmp = icmp slt i32 %a.off, 8 462 br i1 %cmp, label %then, label %else 463 464then: 465 %dead.1 = icmp eq i32 %a, -2147483641 466 %dead.2 = icmp eq i32 %a, 16 467 %result = or i1 %dead.1, %dead.2 468 ret i1 %result 469 470else: 471 ret i1 false 472} 473 474define i1 @test14_sle(i32 %a) { 475; CHECK-LABEL: @test14_sle( 476; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 477; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A_OFF]], 8 478; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 479; CHECK: then: 480; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16 481; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]] 482; CHECK-NEXT: ret i1 [[RESULT]] 483; CHECK: else: 484; CHECK-NEXT: ret i1 false 485; 486 %a.off = add i32 %a, -8 487 %cmp = icmp sle i32 %a.off, 8 488 br i1 %cmp, label %then, label %else 489 490then: 491 %dead = icmp eq i32 %a, -2147483641 492 %alive = icmp eq i32 %a, 16 493 %result = or i1 %dead, %alive 494 ret i1 %result 495 496else: 497 ret i1 false 498} 499 500define i1 @test14_sgt(i32 %a) { 501; CHECK-LABEL: @test14_sgt( 502; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 503; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A_OFF]], 8 504; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 505; CHECK: then: 506; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false 507; CHECK-NEXT: ret i1 false 508; CHECK: else: 509; CHECK-NEXT: ret i1 false 510; 511 %a.off = add i32 %a, -8 512 %cmp = icmp sgt i32 %a.off, 8 513 br i1 %cmp, label %then, label %else 514 515then: 516 %dead.1 = icmp eq i32 %a, -2147483640 517 %dead.2 = icmp eq i32 %a, 16 518 %result = or i1 %dead.1, %dead.2 519 ret i1 %result 520 521else: 522 ret i1 false 523} 524 525define i1 @test14_sge(i32 %a) { 526; CHECK-LABEL: @test14_sge( 527; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 528; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A_OFF]], 8 529; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 530; CHECK: then: 531; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16 532; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]] 533; CHECK-NEXT: ret i1 [[RESULT]] 534; CHECK: else: 535; CHECK-NEXT: ret i1 false 536; 537 %a.off = add i32 %a, -8 538 %cmp = icmp sge i32 %a.off, 8 539 br i1 %cmp, label %then, label %else 540 541then: 542 %dead = icmp eq i32 %a, -2147483640 543 %alive = icmp eq i32 %a, 16 544 %result = or i1 %dead, %alive 545 ret i1 %result 546 547else: 548 ret i1 false 549} 550 551define i1 @test14_ule(i32 %a) { 552; CHECK-LABEL: @test14_ule( 553; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 554; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A_OFF]], 8 555; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 556; CHECK: then: 557; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16 558; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]] 559; CHECK-NEXT: ret i1 [[RESULT]] 560; CHECK: else: 561; CHECK-NEXT: ret i1 false 562; 563 %a.off = add i32 %a, -8 564 %cmp = icmp ule i32 %a.off, 8 565 br i1 %cmp, label %then, label %else 566 567then: 568 %dead = icmp eq i32 %a, 7 569 %alive = icmp eq i32 %a, 16 570 %result = or i1 %dead, %alive 571 ret i1 %result 572 573else: 574 ret i1 false 575} 576 577define i1 @test14_ugt(i32 %a) { 578; CHECK-LABEL: @test14_ugt( 579; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 580; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8 581; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 582; CHECK: then: 583; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false 584; CHECK-NEXT: ret i1 false 585; CHECK: else: 586; CHECK-NEXT: ret i1 false 587; 588 %a.off = add i32 %a, -8 589 %cmp = icmp ugt i32 %a.off, 8 590 br i1 %cmp, label %then, label %else 591 592then: 593 %dead.1 = icmp eq i32 %a, 8 594 %dead.2 = icmp eq i32 %a, 16 595 %result = or i1 %dead.1, %dead.2 596 ret i1 %result 597 598else: 599 ret i1 false 600} 601 602define i1 @test14_uge(i32 %a) { 603; CHECK-LABEL: @test14_uge( 604; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 605; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A_OFF]], 8 606; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 607; CHECK: then: 608; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16 609; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]] 610; CHECK-NEXT: ret i1 [[RESULT]] 611; CHECK: else: 612; CHECK-NEXT: ret i1 false 613; 614 %a.off = add i32 %a, -8 615 %cmp = icmp uge i32 %a.off, 8 616 br i1 %cmp, label %then, label %else 617 618then: 619 %dead = icmp eq i32 %a, 8 620 %alive = icmp eq i32 %a, 16 621 %result = or i1 %dead, %alive 622 ret i1 %result 623 624else: 625 ret i1 false 626} 627 628define i1 @test14_ugt_and(i32 %a) { 629; CHECK-LABEL: @test14_ugt_and( 630; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8 631; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8 632; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 633; CHECK: then: 634; CHECK-NEXT: [[RESULT:%.*]] = and i1 false, false 635; CHECK-NEXT: ret i1 false 636; CHECK: else: 637; CHECK-NEXT: ret i1 false 638; 639 %a.off = add i32 %a, -8 640 %cmp = icmp ugt i32 %a.off, 8 641 br i1 %cmp, label %then, label %else 642 643then: 644 %dead.1 = icmp eq i32 %a, 8 645 %dead.2 = icmp eq i32 %a, 16 646 %result = and i1 %dead.1, %dead.2 647 ret i1 %result 648 649else: 650 ret i1 false 651} 652 653@limit = external global i32 654define i1 @test15(i32 %a) { 655; CHECK-LABEL: @test15( 656; CHECK-NEXT: [[LIMIT:%.*]] = load i32, i32* @limit, align 4, !range [[RNG4:![0-9]+]] 657; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[LIMIT]] 658; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 659; CHECK: then: 660; CHECK-NEXT: ret i1 false 661; CHECK: else: 662; CHECK-NEXT: ret i1 false 663; 664 %limit = load i32, i32* @limit, !range !{i32 0, i32 256} 665 %cmp = icmp ult i32 %a, %limit 666 br i1 %cmp, label %then, label %else 667 668then: 669 %result = icmp eq i32 %a, 255 670 ret i1 %result 671 672else: 673 ret i1 false 674} 675 676define i32 @test16(i8 %a) { 677; CHECK-LABEL: @test16( 678; CHECK-NEXT: entry: 679; CHECK-NEXT: [[B:%.*]] = zext i8 [[A:%.*]] to i32 680; CHECK-NEXT: br label [[DISPATCH:%.*]] 681; CHECK: dispatch: 682; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93 683; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]] 684; CHECK: target93: 685; CHECK-NEXT: ret i32 93 686; 687entry: 688 %b = zext i8 %a to i32 689 br label %dispatch 690 691dispatch: 692 %cmp = icmp eq i8 %a, 93 693 br i1 %cmp, label %target93, label %dispatch 694 695target93: 696 ret i32 %b 697} 698 699define i32 @test16_i1(i1 %a) { 700; CHECK-LABEL: @test16_i1( 701; CHECK-NEXT: entry: 702; CHECK-NEXT: [[B:%.*]] = zext i1 [[A:%.*]] to i32 703; CHECK-NEXT: br label [[DISPATCH:%.*]] 704; CHECK: dispatch: 705; CHECK-NEXT: br i1 [[A]], label [[TRUE:%.*]], label [[DISPATCH]] 706; CHECK: true: 707; CHECK-NEXT: ret i32 1 708; 709entry: 710 %b = zext i1 %a to i32 711 br label %dispatch 712 713dispatch: 714 br i1 %a, label %true, label %dispatch 715 716true: 717 ret i32 %b 718} 719 720define i8 @test17(i8 %a) { 721; CHECK-LABEL: @test17( 722; CHECK-NEXT: entry: 723; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], 3 724; CHECK-NEXT: br label [[DISPATCH:%.*]] 725; CHECK: dispatch: 726; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93 727; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]] 728; CHECK: target93: 729; CHECK-NEXT: ret i8 96 730; 731entry: 732 %c = add i8 %a, 3 733 br label %dispatch 734 735dispatch: 736 %cmp = icmp eq i8 %a, 93 737 br i1 %cmp, label %target93, label %dispatch 738 739target93: 740 ret i8 %c 741} 742 743define i8 @test17_2(i8 %a) { 744; CHECK-LABEL: @test17_2( 745; CHECK-NEXT: entry: 746; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], [[A]] 747; CHECK-NEXT: br label [[DISPATCH:%.*]] 748; CHECK: dispatch: 749; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93 750; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]] 751; CHECK: target93: 752; CHECK-NEXT: ret i8 -70 753; 754entry: 755 %c = add i8 %a, %a 756 br label %dispatch 757 758dispatch: 759 %cmp = icmp eq i8 %a, 93 760 br i1 %cmp, label %target93, label %dispatch 761 762target93: 763 ret i8 %c 764} 765 766define i1 @test17_i1(i1 %a) { 767; CHECK-LABEL: @test17_i1( 768; CHECK-NEXT: entry: 769; CHECK-NEXT: br label [[DISPATCH:%.*]] 770; CHECK: dispatch: 771; CHECK-NEXT: br i1 [[A:%.*]], label [[TRUE:%.*]], label [[DISPATCH]] 772; CHECK: true: 773; CHECK-NEXT: ret i1 true 774; 775entry: 776 %c = and i1 %a, true 777 br label %dispatch 778 779dispatch: 780 br i1 %a, label %true, label %dispatch 781 782true: 783 ret i1 %c 784} 785 786define i32 @test18(i8 %a) { 787; CHECK-LABEL: @test18( 788; CHECK-NEXT: entry: 789; CHECK-NEXT: [[B:%.*]] = zext i8 [[A:%.*]] to i32 790; CHECK-NEXT: br label [[DISPATCH:%.*]] 791; CHECK: dispatch: 792; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [ 793; CHECK-NEXT: i8 93, label [[TARGET93:%.*]] 794; CHECK-NEXT: i8 -111, label [[DISPATCH]] 795; CHECK-NEXT: ] 796; CHECK: target93: 797; CHECK-NEXT: ret i32 93 798; 799entry: 800 %b = zext i8 %a to i32 801 br label %dispatch 802 803dispatch: 804 switch i8 %a, label %dispatch [ 805 i8 93, label %target93 806 i8 -111, label %dispatch 807 ] 808 809target93: 810 ret i32 %b 811} 812 813define i8 @test19(i8 %a) { 814; CHECK-LABEL: @test19( 815; CHECK-NEXT: entry: 816; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], 3 817; CHECK-NEXT: br label [[DISPATCH:%.*]] 818; CHECK: dispatch: 819; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [ 820; CHECK-NEXT: i8 93, label [[TARGET93:%.*]] 821; CHECK-NEXT: i8 -111, label [[DISPATCH]] 822; CHECK-NEXT: ] 823; CHECK: target93: 824; CHECK-NEXT: ret i8 96 825; 826entry: 827 %c = add i8 %a, 3 828 br label %dispatch 829 830dispatch: 831 switch i8 %a, label %dispatch [ 832 i8 93, label %target93 833 i8 -111, label %dispatch 834 ] 835 836target93: 837 ret i8 %c 838} 839 840; Negative test. Shouldn't be incorrectly optimized to "ret i1 false". 841 842define i1 @test20(i64 %a) { 843; CHECK-LABEL: @test20( 844; CHECK-NEXT: entry: 845; CHECK-NEXT: [[B:%.*]] = and i64 [[A:%.*]], 7 846; CHECK-NEXT: br label [[DISPATCH:%.*]] 847; CHECK: dispatch: 848; CHECK-NEXT: switch i64 [[A]], label [[DEFAULT:%.*]] [ 849; CHECK-NEXT: i64 0, label [[EXIT2:%.*]] 850; CHECK-NEXT: i64 -2147483647, label [[EXIT2]] 851; CHECK-NEXT: ] 852; CHECK: default: 853; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[B]], 0 854; CHECK-NEXT: br label [[EXIT:%.*]] 855; CHECK: exit: 856; CHECK-NEXT: ret i1 [[C]] 857; CHECK: exit2: 858; CHECK-NEXT: ret i1 false 859; 860entry: 861 %b = and i64 %a, 7 862 br label %dispatch 863 864dispatch: 865 switch i64 %a, label %default [ 866 i64 0, label %exit2 867 i64 -2147483647, label %exit2 868 ] 869 870default: 871 %c = icmp eq i64 %b, 0 872 br label %exit 873 874exit: 875 ret i1 %c 876 877exit2: 878 ret i1 false 879} 880 881define i1 @slt(i8 %a, i8 %b) { 882; CHECK-LABEL: @slt( 883; CHECK-NEXT: entry: 884; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], [[B:%.*]] 885; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 886; CHECK-NEXT: ret i1 true 887; 888entry: 889 %cmp = icmp slt i8 %a, %b 890 call void @llvm.assume(i1 %cmp) 891 %res = icmp slt i8 %a, 127 892 ret i1 %res 893} 894 895define i1 @sgt(i8 %a, i8 %b) { 896; CHECK-LABEL: @sgt( 897; CHECK-NEXT: entry: 898; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]] 899; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 900; CHECK-NEXT: ret i1 true 901; 902entry: 903 %cmp = icmp sgt i8 %a, %b 904 call void @llvm.assume(i1 %cmp) 905 %res = icmp sgt i8 %a, -128 906 ret i1 %res 907} 908 909define i1 @ult(i8 %a, i8 %b) { 910; CHECK-LABEL: @ult( 911; CHECK-NEXT: entry: 912; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]] 913; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 914; CHECK-NEXT: ret i1 true 915; 916entry: 917 %cmp = icmp ult i8 %a, %b 918 call void @llvm.assume(i1 %cmp) 919 %res = icmp ult i8 %a, 255 920 ret i1 %res 921} 922 923define i1 @ugt(i8 %a, i8 %b) { 924; CHECK-LABEL: @ugt( 925; CHECK-NEXT: entry: 926; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 927; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 928; CHECK-NEXT: ret i1 true 929; 930entry: 931 %cmp = icmp ugt i8 %a, %b 932 call void @llvm.assume(i1 %cmp) 933 %res = icmp ugt i8 %a, 0 934 ret i1 %res 935} 936 937define i1 @intrinsic_range(i16 %x) { 938; CHECK-LABEL: @intrinsic_range( 939; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range [[RNG5:![0-9]+]] 940; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[CTLZ]] to i8 941; CHECK-NEXT: ret i1 true 942; 943 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false), !range !{i16 0, i16 8} 944 %trunc = trunc i16 %ctlz to i8 945 %res = icmp ult i8 %trunc, 8 946 ret i1 %res 947} 948 949declare i16 @llvm.ctlz.i16(i16, i1) 950declare void @llvm.assume(i1) 951