1371 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes=correlated-propagation -S < %s | FileCheck %s3 4declare i32 @foo()5 6define i32 @test1(i32 %a) nounwind {7; CHECK-LABEL: define range(i32 1, 3) i32 @test1(8; CHECK-SAME: i32 [[A:%.*]]) #[[ATTR0:[0-9]+]] {9; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -810; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 811; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]12; CHECK: [[THEN]]:13; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]14; CHECK: [[ELSE]]:15; CHECK-NEXT: ret i32 116; CHECK: [[END]]:17; CHECK-NEXT: ret i32 218;19 %a.off = add i32 %a, -820 %cmp = icmp ult i32 %a.off, 821 br i1 %cmp, label %then, label %else22 23then:24 %dead = icmp eq i32 %a, 725 br i1 %dead, label %end, label %else26 27else:28 ret i32 129 30end:31 ret i32 232}33 34define i32 @test2(i32 %a) nounwind {35; CHECK-LABEL: define range(i32 1, 3) i32 @test2(36; CHECK-SAME: i32 [[A:%.*]]) #[[ATTR0]] {37; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -838; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 839; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]40; CHECK: [[THEN]]:41; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]42; CHECK: [[ELSE]]:43; CHECK-NEXT: ret i32 144; CHECK: [[END]]:45; CHECK-NEXT: ret i32 246;47 %a.off = add i32 %a, -848 %cmp = icmp ult i32 %a.off, 849 br i1 %cmp, label %then, label %else50 51then:52 %dead = icmp ugt i32 %a, 1553 br i1 %dead, label %end, label %else54 55else:56 ret i32 157 58end:59 ret i32 260}61 62define i32 @test3(i32 %c) nounwind {63; CHECK-LABEL: define range(i32 1, 5) i32 @test3(64; CHECK-SAME: i32 [[C:%.*]]) #[[ATTR0]] {65; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 266; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]67; CHECK: [[IF_THEN]]:68; CHECK-NEXT: ret i32 169; CHECK: [[IF_END]]:70; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ult i32 [[C]], 371; CHECK-NEXT: br i1 [[CMP1]], label %[[IF_THEN2:.*]], label %[[IF_END8:.*]]72; CHECK: [[IF_THEN2]]:73; CHECK-NEXT: br i1 true, label %[[IF_THEN4:.*]], label %[[IF_END6:.*]]74; CHECK: [[IF_END6]]:75; CHECK-NEXT: ret i32 276; CHECK: [[IF_THEN4]]:77; CHECK-NEXT: ret i32 378; CHECK: [[IF_END8]]:79; CHECK-NEXT: ret i32 480;81 %cmp = icmp slt i32 %c, 282 br i1 %cmp, label %if.then, label %if.end83 84if.then:85 ret i32 186 87if.end:88 %cmp1 = icmp slt i32 %c, 389 br i1 %cmp1, label %if.then2, label %if.end890 91if.then2:92 %cmp2 = icmp eq i32 %c, 293 br i1 %cmp2, label %if.then4, label %if.end694 95if.end6:96 ret i32 297 98if.then4:99 ret i32 3100 101if.end8:102 ret i32 4103}104 105define i32 @test4(i32 %c) nounwind {106; CHECK-LABEL: define range(i32 4, 43) i32 @test4(107; CHECK-SAME: i32 [[C:%.*]]) #[[ATTR0]] {108; CHECK-NEXT: switch i32 [[C]], label %[[SW_DEFAULT:.*]] [109; CHECK-NEXT: i32 1, label %[[SW_BB:.*]]110; CHECK-NEXT: i32 2, label %[[SW_BB]]111; CHECK-NEXT: i32 4, label %[[SW_BB]]112; CHECK-NEXT: ]113; CHECK: [[SW_BB]]:114; CHECK-NEXT: br i1 true, label %[[IF_THEN:.*]], label %[[IF_END:.*]]115; CHECK: [[IF_THEN]]:116; CHECK-NEXT: br label %[[RETURN:.*]]117; CHECK: [[IF_END]]:118; CHECK-NEXT: br label %[[RETURN]]119; CHECK: [[SW_DEFAULT]]:120; CHECK-NEXT: br label %[[RETURN]]121; CHECK: [[RETURN]]:122; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 42, %[[SW_DEFAULT]] ], [ 4, %[[IF_THEN]] ], [ 9, %[[IF_END]] ]123; CHECK-NEXT: ret i32 [[RETVAL_0]]124;125 switch i32 %c, label %sw.default [126 i32 1, label %sw.bb127 i32 2, label %sw.bb128 i32 4, label %sw.bb129 ]130 131sw.bb:132 %cmp = icmp sge i32 %c, 1133 br i1 %cmp, label %if.then, label %if.end134 135if.then:136 br label %return137 138if.end:139 br label %return140 141sw.default:142 br label %return143 144return:145 %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]146 ret i32 %retval.0147}148 149define i1 @test5(i32 %c) nounwind {150; CHECK-LABEL: define i1 @test5(151; CHECK-SAME: i32 [[C:%.*]]) #[[ATTR0]] {152; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 5153; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]154; CHECK: [[IF_THEN]]:155; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[C]], 4156; CHECK-NEXT: br i1 [[CMP1]], label %[[IF_END]], label %[[IF_END8:.*]]157; CHECK: [[IF_END]]:158; CHECK-NEXT: ret i1 true159; CHECK: [[IF_END8]]:160; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[C]], 3161; CHECK-NEXT: [[OR:%.*]] = or i1 false, false162; CHECK-NEXT: ret i1 [[CMP2]]163;164 %cmp = icmp slt i32 %c, 5165 br i1 %cmp, label %if.then, label %if.end166 167if.then:168 %cmp1 = icmp eq i32 %c, 4169 br i1 %cmp1, label %if.end, label %if.end8170 171if.end:172 ret i1 true173 174if.end8:175 %cmp2 = icmp eq i32 %c, 3176 %cmp3 = icmp eq i32 %c, 4177 %cmp4 = icmp eq i32 %c, 6178 %or = or i1 %cmp3, %cmp4179 ret i1 %cmp2180}181 182define i1 @test6(i32 %c) nounwind {183; CHECK-LABEL: define i1 @test6(184; CHECK-SAME: i32 [[C:%.*]]) #[[ATTR0]] {185; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[C]], 7186; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]187; CHECK: [[IF_THEN]]:188; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[C]], 6189; CHECK-NEXT: br i1 [[COND]], label %[[SW_BB:.*]], label %[[IF_END]]190; CHECK: [[IF_END]]:191; CHECK-NEXT: ret i1 true192; CHECK: [[SW_BB]]:193; CHECK-NEXT: ret i1 true194;195 %cmp = icmp ule i32 %c, 7196 br i1 %cmp, label %if.then, label %if.end197 198if.then:199 switch i32 %c, label %if.end [200 i32 6, label %sw.bb201 i32 8, label %sw.bb202 ]203 204if.end:205 ret i1 true206 207sw.bb:208 %cmp2 = icmp eq i32 %c, 6209 ret i1 %cmp2210}211 212define i1 @test7(i32 %c) nounwind {213; CHECK-LABEL: define i1 @test7(214; CHECK-SAME: i32 [[C:%.*]]) #[[ATTR0]] {215; CHECK-NEXT: [[ENTRY:.*:]]216; CHECK-NEXT: switch i32 [[C]], label %[[SW_DEFAULT:.*]] [217; CHECK-NEXT: i32 6, label %[[SW_BB:.*]]218; CHECK-NEXT: i32 7, label %[[SW_BB]]219; CHECK-NEXT: ]220; CHECK: [[SW_BB]]:221; CHECK-NEXT: ret i1 true222; CHECK: [[SW_DEFAULT]]:223; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[C]], 5224; CHECK-NEXT: [[CMP8:%.*]] = icmp eq i32 [[C]], 8225; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP5]], false226; CHECK-NEXT: [[OR2:%.*]] = or i1 false, [[CMP8]]227; CHECK-NEXT: ret i1 false228;229entry:230 switch i32 %c, label %sw.default [231 i32 6, label %sw.bb232 i32 7, label %sw.bb233 ]234 235sw.bb:236 ret i1 true237 238sw.default:239 %cmp5 = icmp eq i32 %c, 5240 %cmp6 = icmp eq i32 %c, 6241 %cmp7 = icmp eq i32 %c, 7242 %cmp8 = icmp eq i32 %c, 8243 %or = or i1 %cmp5, %cmp6244 %or2 = or i1 %cmp7, %cmp8245 ret i1 false246}247 248define i1 @test8(ptr %p) {249; CHECK-LABEL: define i1 @test8(250; CHECK-SAME: ptr [[P:%.*]]) {251; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]252; CHECK-NEXT: ret i1 false253;254 %a = load i64, ptr %p, !range !{i64 4, i64 255}255 %res = icmp eq i64 %a, 0256 ret i1 %res257}258 259define i1 @test9(ptr %p) {260; CHECK-LABEL: define i1 @test9(261; CHECK-SAME: ptr [[P:%.*]]) {262; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P]], align 4, !range [[RNG1:![0-9]+]]263; CHECK-NEXT: ret i1 true264;265 %a = load i64, ptr %p, !range !{i64 0, i64 1}266 %res = icmp eq i64 %a, 0267 ret i1 %res268}269 270define i1 @test10(ptr %p) {271; CHECK-LABEL: define i1 @test10(272; CHECK-SAME: ptr [[P:%.*]]) {273; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P]], align 4, !range [[RNG2:![0-9]+]]274; CHECK-NEXT: ret i1 false275;276 %a = load i64, ptr %p, !range !{i64 4, i64 8, i64 15, i64 20}277 %res = icmp eq i64 %a, 0278 ret i1 %res279}280 281@g = external global i32282 283define i1 @test11() {284; CHECK-LABEL: define i1 @test11() {285; CHECK-NEXT: [[POSITIVE:%.*]] = load i32, ptr @g, align 4, !range [[RNG3:![0-9]+]]286; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[POSITIVE]], 1287; CHECK-NEXT: br label %[[NEXT:.*]]288; CHECK: [[NEXT]]:289; CHECK-NEXT: ret i1 true290;291 %positive = load i32, ptr @g, !range !{i32 1, i32 2048}292 %add = add i32 %positive, 1293 %test = icmp sgt i32 %add, 0294 br label %next295 296next:297 ret i1 %test298}299 300define i32 @test12(i32 %a, i32 %b) {301; CHECK-LABEL: define range(i32 1, 3) i32 @test12(302; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {303; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]304; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]305; CHECK: [[THEN]]:306; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]307; CHECK: [[ELSE]]:308; CHECK-NEXT: ret i32 1309; CHECK: [[END]]:310; CHECK-NEXT: ret i32 2311;312 %cmp = icmp ult i32 %a, %b313 br i1 %cmp, label %then, label %else314 315then:316 %dead = icmp eq i32 %a, -1317 br i1 %dead, label %end, label %else318 319else:320 ret i32 1321 322end:323 ret i32 2324}325 326define i32 @test12_swap(i32 %a, i32 %b) {327; CHECK-LABEL: define range(i32 1, 3) i32 @test12_swap(328; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {329; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B]], [[A]]330; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]331; CHECK: [[THEN]]:332; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]333; CHECK: [[ELSE]]:334; CHECK-NEXT: ret i32 1335; CHECK: [[END]]:336; CHECK-NEXT: ret i32 2337;338 %cmp = icmp ugt i32 %b, %a339 br i1 %cmp, label %then, label %else340 341then:342 %dead = icmp eq i32 %a, -1343 br i1 %dead, label %end, label %else344 345else:346 ret i32 1347 348end:349 ret i32 2350}351 352; The same as @test12 but the second check is on the false path353 354define i32 @test12_neg(i32 %a, i32 %b) {355; CHECK-LABEL: define range(i32 1, 3) i32 @test12_neg(356; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {357; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]358; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]359; CHECK: [[ELSE]]:360; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], -1361; CHECK-NEXT: br i1 [[ALIVE]], label %[[END:.*]], label %[[THEN]]362; CHECK: [[THEN]]:363; CHECK-NEXT: ret i32 1364; CHECK: [[END]]:365; CHECK-NEXT: ret i32 2366;367 %cmp = icmp ult i32 %a, %b368 br i1 %cmp, label %then, label %else369 370else:371 %alive = icmp eq i32 %a, -1372 br i1 %alive, label %end, label %then373 374then:375 ret i32 1376 377end:378 ret i32 2379}380 381; The same as @test12 but with signed comparison382 383define i32 @test12_signed(i32 %a, i32 %b) {384; CHECK-LABEL: define range(i32 1, 3) i32 @test12_signed(385; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {386; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]387; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]388; CHECK: [[THEN]]:389; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]390; CHECK: [[ELSE]]:391; CHECK-NEXT: ret i32 1392; CHECK: [[END]]:393; CHECK-NEXT: ret i32 2394;395 %cmp = icmp slt i32 %a, %b396 br i1 %cmp, label %then, label %else397 398then:399 %dead = icmp eq i32 %a, 2147483647400 br i1 %dead, label %end, label %else401 402else:403 ret i32 1404 405end:406 ret i32 2407}408 409define i32 @test13(i32 %a, i32 %b) {410; CHECK-LABEL: define range(i32 1, 3) i32 @test13(411; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {412; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8413; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], [[B]]414; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]415; CHECK: [[THEN]]:416; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]417; CHECK: [[ELSE]]:418; CHECK-NEXT: ret i32 1419; CHECK: [[END]]:420; CHECK-NEXT: ret i32 2421;422 %a.off = add i32 %a, -8423 %cmp = icmp ult i32 %a.off, %b424 br i1 %cmp, label %then, label %else425 426then:427 %dead = icmp eq i32 %a, 7428 br i1 %dead, label %end, label %else429 430else:431 ret i32 1432 433end:434 ret i32 2435}436 437define i32 @test13_swap(i32 %a, i32 %b) {438; CHECK-LABEL: define range(i32 1, 3) i32 @test13_swap(439; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {440; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8441; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B]], [[A_OFF]]442; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]443; CHECK: [[THEN]]:444; CHECK-NEXT: br i1 false, label %[[END:.*]], label %[[ELSE]]445; CHECK: [[ELSE]]:446; CHECK-NEXT: ret i32 1447; CHECK: [[END]]:448; CHECK-NEXT: ret i32 2449;450 %a.off = add i32 %a, -8451 %cmp = icmp ugt i32 %b, %a.off452 br i1 %cmp, label %then, label %else453 454then:455 %dead = icmp eq i32 %a, 7456 br i1 %dead, label %end, label %else457 458else:459 ret i32 1460 461end:462 ret i32 2463}464 465define i1 @test14_slt(i32 %a) {466; CHECK-LABEL: define i1 @test14_slt(467; CHECK-SAME: i32 [[A:%.*]]) {468; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8469; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A_OFF]], 8470; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]471; CHECK: [[THEN]]:472; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false473; CHECK-NEXT: ret i1 false474; CHECK: [[ELSE]]:475; CHECK-NEXT: ret i1 false476;477 %a.off = add i32 %a, -8478 %cmp = icmp slt i32 %a.off, 8479 br i1 %cmp, label %then, label %else480 481then:482 %dead.1 = icmp eq i32 %a, -2147483641483 %dead.2 = icmp eq i32 %a, 16484 %result = or i1 %dead.1, %dead.2485 ret i1 %result486 487else:488 ret i1 false489}490 491define i1 @test14_sle(i32 %a) {492; CHECK-LABEL: define i1 @test14_sle(493; CHECK-SAME: i32 [[A:%.*]]) {494; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8495; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A_OFF]], 8496; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]497; CHECK: [[THEN]]:498; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16499; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]500; CHECK-NEXT: ret i1 [[RESULT]]501; CHECK: [[ELSE]]:502; CHECK-NEXT: ret i1 false503;504 %a.off = add i32 %a, -8505 %cmp = icmp sle i32 %a.off, 8506 br i1 %cmp, label %then, label %else507 508then:509 %dead = icmp eq i32 %a, -2147483641510 %alive = icmp eq i32 %a, 16511 %result = or i1 %dead, %alive512 ret i1 %result513 514else:515 ret i1 false516}517 518define i1 @test14_sgt(i32 %a) {519; CHECK-LABEL: define i1 @test14_sgt(520; CHECK-SAME: i32 [[A:%.*]]) {521; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8522; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A_OFF]], 8523; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]524; CHECK: [[THEN]]:525; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false526; CHECK-NEXT: ret i1 false527; CHECK: [[ELSE]]:528; CHECK-NEXT: ret i1 false529;530 %a.off = add i32 %a, -8531 %cmp = icmp sgt i32 %a.off, 8532 br i1 %cmp, label %then, label %else533 534then:535 %dead.1 = icmp eq i32 %a, -2147483640536 %dead.2 = icmp eq i32 %a, 16537 %result = or i1 %dead.1, %dead.2538 ret i1 %result539 540else:541 ret i1 false542}543 544define i1 @test14_sge(i32 %a) {545; CHECK-LABEL: define i1 @test14_sge(546; CHECK-SAME: i32 [[A:%.*]]) {547; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8548; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A_OFF]], 8549; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]550; CHECK: [[THEN]]:551; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16552; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]553; CHECK-NEXT: ret i1 [[RESULT]]554; CHECK: [[ELSE]]:555; CHECK-NEXT: ret i1 false556;557 %a.off = add i32 %a, -8558 %cmp = icmp sge i32 %a.off, 8559 br i1 %cmp, label %then, label %else560 561then:562 %dead = icmp eq i32 %a, -2147483640563 %alive = icmp eq i32 %a, 16564 %result = or i1 %dead, %alive565 ret i1 %result566 567else:568 ret i1 false569}570 571define i1 @test14_ule(i32 %a) {572; CHECK-LABEL: define i1 @test14_ule(573; CHECK-SAME: i32 [[A:%.*]]) {574; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8575; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A_OFF]], 8576; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]577; CHECK: [[THEN]]:578; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16579; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]580; CHECK-NEXT: ret i1 [[RESULT]]581; CHECK: [[ELSE]]:582; CHECK-NEXT: ret i1 false583;584 %a.off = add i32 %a, -8585 %cmp = icmp ule i32 %a.off, 8586 br i1 %cmp, label %then, label %else587 588then:589 %dead = icmp eq i32 %a, 7590 %alive = icmp eq i32 %a, 16591 %result = or i1 %dead, %alive592 ret i1 %result593 594else:595 ret i1 false596}597 598define i1 @test14_ugt(i32 %a) {599; CHECK-LABEL: define i1 @test14_ugt(600; CHECK-SAME: i32 [[A:%.*]]) {601; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8602; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8603; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]604; CHECK: [[THEN]]:605; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false606; CHECK-NEXT: ret i1 false607; CHECK: [[ELSE]]:608; CHECK-NEXT: ret i1 false609;610 %a.off = add i32 %a, -8611 %cmp = icmp ugt i32 %a.off, 8612 br i1 %cmp, label %then, label %else613 614then:615 %dead.1 = icmp eq i32 %a, 8616 %dead.2 = icmp eq i32 %a, 16617 %result = or i1 %dead.1, %dead.2618 ret i1 %result619 620else:621 ret i1 false622}623 624define i1 @test14_uge(i32 %a) {625; CHECK-LABEL: define i1 @test14_uge(626; CHECK-SAME: i32 [[A:%.*]]) {627; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8628; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A_OFF]], 8629; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]630; CHECK: [[THEN]]:631; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16632; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]633; CHECK-NEXT: ret i1 [[RESULT]]634; CHECK: [[ELSE]]:635; CHECK-NEXT: ret i1 false636;637 %a.off = add i32 %a, -8638 %cmp = icmp uge i32 %a.off, 8639 br i1 %cmp, label %then, label %else640 641then:642 %dead = icmp eq i32 %a, 8643 %alive = icmp eq i32 %a, 16644 %result = or i1 %dead, %alive645 ret i1 %result646 647else:648 ret i1 false649}650 651define i1 @test14_ugt_and(i32 %a) {652; CHECK-LABEL: define i1 @test14_ugt_and(653; CHECK-SAME: i32 [[A:%.*]]) {654; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A]], -8655; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8656; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]657; CHECK: [[THEN]]:658; CHECK-NEXT: [[RESULT:%.*]] = and i1 false, false659; CHECK-NEXT: ret i1 false660; CHECK: [[ELSE]]:661; CHECK-NEXT: ret i1 false662;663 %a.off = add i32 %a, -8664 %cmp = icmp ugt i32 %a.off, 8665 br i1 %cmp, label %then, label %else666 667then:668 %dead.1 = icmp eq i32 %a, 8669 %dead.2 = icmp eq i32 %a, 16670 %result = and i1 %dead.1, %dead.2671 ret i1 %result672 673else:674 ret i1 false675}676 677@limit = external global i32678define i1 @test15(i32 %a) {679; CHECK-LABEL: define i1 @test15(680; CHECK-SAME: i32 [[A:%.*]]) {681; CHECK-NEXT: [[LIMIT:%.*]] = load i32, ptr @limit, align 4, !range [[RNG4:![0-9]+]]682; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[LIMIT]]683; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]684; CHECK: [[THEN]]:685; CHECK-NEXT: ret i1 false686; CHECK: [[ELSE]]:687; CHECK-NEXT: ret i1 false688;689 %limit = load i32, ptr @limit, !range !{i32 0, i32 256}690 %cmp = icmp ult i32 %a, %limit691 br i1 %cmp, label %then, label %else692 693then:694 %result = icmp eq i32 %a, 255695 ret i1 %result696 697else:698 ret i1 false699}700 701define i32 @test16(i8 %a) {702; CHECK-LABEL: define i32 @test16(703; CHECK-SAME: i8 [[A:%.*]]) {704; CHECK-NEXT: [[ENTRY:.*:]]705; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i32706; CHECK-NEXT: br label %[[DISPATCH:.*]]707; CHECK: [[DISPATCH]]:708; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93709; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET93:.*]], label %[[DISPATCH]]710; CHECK: [[TARGET93]]:711; CHECK-NEXT: ret i32 93712;713entry:714 %b = zext i8 %a to i32715 br label %dispatch716 717dispatch:718 %cmp = icmp eq i8 %a, 93719 br i1 %cmp, label %target93, label %dispatch720 721target93:722 ret i32 %b723}724 725define i32 @test16_i1(i1 %a) {726; CHECK-LABEL: define i32 @test16_i1(727; CHECK-SAME: i1 [[A:%.*]]) {728; CHECK-NEXT: [[ENTRY:.*:]]729; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32730; CHECK-NEXT: br label %[[DISPATCH:.*]]731; CHECK: [[DISPATCH]]:732; CHECK-NEXT: br i1 [[A]], label %[[TRUE:.*]], label %[[DISPATCH]]733; CHECK: [[TRUE]]:734; CHECK-NEXT: ret i32 1735;736entry:737 %b = zext i1 %a to i32738 br label %dispatch739 740dispatch:741 br i1 %a, label %true, label %dispatch742 743true:744 ret i32 %b745}746 747define i8 @test17(i8 %a) {748; CHECK-LABEL: define i8 @test17(749; CHECK-SAME: i8 [[A:%.*]]) {750; CHECK-NEXT: [[ENTRY:.*:]]751; CHECK-NEXT: [[C:%.*]] = add i8 [[A]], 3752; CHECK-NEXT: br label %[[DISPATCH:.*]]753; CHECK: [[DISPATCH]]:754; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93755; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET93:.*]], label %[[DISPATCH]]756; CHECK: [[TARGET93]]:757; CHECK-NEXT: ret i8 96758;759entry:760 %c = add i8 %a, 3761 br label %dispatch762 763dispatch:764 %cmp = icmp eq i8 %a, 93765 br i1 %cmp, label %target93, label %dispatch766 767target93:768 ret i8 %c769}770 771define i8 @test17_2(i8 %a) {772; CHECK-LABEL: define i8 @test17_2(773; CHECK-SAME: i8 [[A:%.*]]) {774; CHECK-NEXT: [[ENTRY:.*:]]775; CHECK-NEXT: [[C:%.*]] = add i8 [[A]], [[A]]776; CHECK-NEXT: br label %[[DISPATCH:.*]]777; CHECK: [[DISPATCH]]:778; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93779; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET93:.*]], label %[[DISPATCH]]780; CHECK: [[TARGET93]]:781; CHECK-NEXT: ret i8 -70782;783entry:784 %c = add i8 %a, %a785 br label %dispatch786 787dispatch:788 %cmp = icmp eq i8 %a, 93789 br i1 %cmp, label %target93, label %dispatch790 791target93:792 ret i8 %c793}794 795define i1 @test17_i1(i1 %a) {796; CHECK-LABEL: define i1 @test17_i1(797; CHECK-SAME: i1 [[A:%.*]]) {798; CHECK-NEXT: [[ENTRY:.*:]]799; CHECK-NEXT: br label %[[DISPATCH:.*]]800; CHECK: [[DISPATCH]]:801; CHECK-NEXT: br i1 [[A]], label %[[TRUE:.*]], label %[[DISPATCH]]802; CHECK: [[TRUE]]:803; CHECK-NEXT: ret i1 true804;805entry:806 %c = and i1 %a, true807 br label %dispatch808 809dispatch:810 br i1 %a, label %true, label %dispatch811 812true:813 ret i1 %c814}815 816define i32 @test18(i8 %a) {817; CHECK-LABEL: define i32 @test18(818; CHECK-SAME: i8 [[A:%.*]]) {819; CHECK-NEXT: [[ENTRY:.*:]]820; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i32821; CHECK-NEXT: br label %[[DISPATCH:.*]]822; CHECK: [[DISPATCH]]:823; CHECK-NEXT: switch i8 [[A]], label %[[DISPATCH]] [824; CHECK-NEXT: i8 93, label %[[TARGET93:.*]]825; CHECK-NEXT: i8 -111, label %[[DISPATCH]]826; CHECK-NEXT: ]827; CHECK: [[TARGET93]]:828; CHECK-NEXT: ret i32 93829;830entry:831 %b = zext i8 %a to i32832 br label %dispatch833 834dispatch:835 switch i8 %a, label %dispatch [836 i8 93, label %target93837 i8 -111, label %dispatch838 ]839 840target93:841 ret i32 %b842}843 844define i8 @test19(i8 %a) {845; CHECK-LABEL: define i8 @test19(846; CHECK-SAME: i8 [[A:%.*]]) {847; CHECK-NEXT: [[ENTRY:.*:]]848; CHECK-NEXT: [[C:%.*]] = add i8 [[A]], 3849; CHECK-NEXT: br label %[[DISPATCH:.*]]850; CHECK: [[DISPATCH]]:851; CHECK-NEXT: switch i8 [[A]], label %[[DISPATCH]] [852; CHECK-NEXT: i8 93, label %[[TARGET93:.*]]853; CHECK-NEXT: i8 -111, label %[[DISPATCH]]854; CHECK-NEXT: ]855; CHECK: [[TARGET93]]:856; CHECK-NEXT: ret i8 96857;858entry:859 %c = add i8 %a, 3860 br label %dispatch861 862dispatch:863 switch i8 %a, label %dispatch [864 i8 93, label %target93865 i8 -111, label %dispatch866 ]867 868target93:869 ret i8 %c870}871 872; Negative test. Shouldn't be incorrectly optimized to "ret i1 false".873 874define i1 @test20(i64 %a) {875; CHECK-LABEL: define i1 @test20(876; CHECK-SAME: i64 [[A:%.*]]) {877; CHECK-NEXT: [[ENTRY:.*:]]878; CHECK-NEXT: [[B:%.*]] = and i64 [[A]], 7879; CHECK-NEXT: br label %[[DISPATCH:.*]]880; CHECK: [[DISPATCH]]:881; CHECK-NEXT: switch i64 [[A]], label %[[DEFAULT:.*]] [882; CHECK-NEXT: i64 0, label %[[EXIT2:.*]]883; CHECK-NEXT: i64 -2147483647, label %[[EXIT2]]884; CHECK-NEXT: ]885; CHECK: [[DEFAULT]]:886; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[B]], 0887; CHECK-NEXT: br label %[[EXIT:.*]]888; CHECK: [[EXIT]]:889; CHECK-NEXT: ret i1 [[C]]890; CHECK: [[EXIT2]]:891; CHECK-NEXT: ret i1 false892;893entry:894 %b = and i64 %a, 7895 br label %dispatch896 897dispatch:898 switch i64 %a, label %default [899 i64 0, label %exit2900 i64 -2147483647, label %exit2901 ]902 903default:904 %c = icmp eq i64 %b, 0905 br label %exit906 907exit:908 ret i1 %c909 910exit2:911 ret i1 false912}913 914define i1 @slt(i8 %a, i8 %b) {915; CHECK-LABEL: define i1 @slt(916; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {917; CHECK-NEXT: [[ENTRY:.*:]]918; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A]], [[B]]919; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])920; CHECK-NEXT: ret i1 true921;922entry:923 %cmp = icmp slt i8 %a, %b924 call void @llvm.assume(i1 %cmp)925 %res = icmp slt i8 %a, 127926 ret i1 %res927}928 929define i1 @sgt(i8 %a, i8 %b) {930; CHECK-LABEL: define i1 @sgt(931; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {932; CHECK-NEXT: [[ENTRY:.*:]]933; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]]934; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])935; CHECK-NEXT: ret i1 true936;937entry:938 %cmp = icmp sgt i8 %a, %b939 call void @llvm.assume(i1 %cmp)940 %res = icmp sgt i8 %a, -128941 ret i1 %res942}943 944define i1 @ult(i8 %a, i8 %b) {945; CHECK-LABEL: define i1 @ult(946; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {947; CHECK-NEXT: [[ENTRY:.*:]]948; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A]], [[B]]949; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])950; CHECK-NEXT: ret i1 true951;952entry:953 %cmp = icmp ult i8 %a, %b954 call void @llvm.assume(i1 %cmp)955 %res = icmp ult i8 %a, 255956 ret i1 %res957}958 959define i1 @ugt(i8 %a, i8 %b) {960; CHECK-LABEL: define i1 @ugt(961; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {962; CHECK-NEXT: [[ENTRY:.*:]]963; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A]], [[B]]964; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])965; CHECK-NEXT: ret i1 true966;967entry:968 %cmp = icmp ugt i8 %a, %b969 call void @llvm.assume(i1 %cmp)970 %res = icmp ugt i8 %a, 0971 ret i1 %res972}973 974define i1 @ctlz_with_range_metadata(i16 %x) {975; CHECK-LABEL: define i1 @ctlz_with_range_metadata(976; CHECK-SAME: i16 [[X:%.*]]) {977; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false), !range [[RNG5:![0-9]+]]978; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw nsw i16 [[CTLZ]] to i8979; CHECK-NEXT: ret i1 true980;981 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false), !range !{i16 0, i16 8}982 %trunc = trunc i16 %ctlz to i8983 %res = icmp ult i8 %trunc, 8984 ret i1 %res985}986 987define i1 @abs_with_range_metadata(i16 %x) {988; CHECK-LABEL: define i1 @abs_with_range_metadata(989; CHECK-SAME: i16 [[X:%.*]]) {990; CHECK-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X]], i1 false), !range [[RNG5]]991; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw nsw i16 [[ABS]] to i8992; CHECK-NEXT: ret i1 true993;994 %abs = call i16 @llvm.abs.i16(i16 %x, i1 false), !range !{i16 0, i16 8}995 %trunc = trunc i16 %abs to i8996 %res = icmp ult i8 %trunc, 8997 ret i1 %res998}999 1000define i1 @ctlz_fold(i16 %x) {1001; CHECK-LABEL: define i1 @ctlz_fold(1002; CHECK-SAME: i16 [[X:%.*]]) {1003; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561004; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1005; CHECK: [[IF]]:1006; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)1007; CHECK-NEXT: ret i1 true1008; CHECK: [[ELSE]]:1009; CHECK-NEXT: [[CTLZ2:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)1010; CHECK-NEXT: ret i1 true1011;1012 %cmp = icmp ult i16 %x, 2561013 br i1 %cmp, label %if, label %else1014 1015if:1016 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false)1017 %res = icmp uge i16 %ctlz, 81018 ret i1 %res1019 1020else:1021 %ctlz2 = call i16 @llvm.ctlz.i16(i16 %x, i1 false)1022 %res2 = icmp ult i16 %ctlz2, 81023 ret i1 %res21024}1025 1026define i1 @ctlz_nofold(i16 %x) {1027; CHECK-LABEL: define i1 @ctlz_nofold(1028; CHECK-SAME: i16 [[X:%.*]]) {1029; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561030; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1031; CHECK: [[IF]]:1032; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)1033; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTLZ]], 91034; CHECK-NEXT: ret i1 [[RES]]1035; CHECK: [[ELSE]]:1036; CHECK-NEXT: [[CTLZ2:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)1037; CHECK-NEXT: [[RES2:%.*]] = icmp samesign ult i16 [[CTLZ2]], 71038; CHECK-NEXT: ret i1 [[RES2]]1039;1040 %cmp = icmp ult i16 %x, 2561041 br i1 %cmp, label %if, label %else1042 1043if:1044 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false)1045 %res = icmp uge i16 %ctlz, 91046 ret i1 %res1047 1048else:1049 %ctlz2 = call i16 @llvm.ctlz.i16(i16 %x, i1 false)1050 %res2 = icmp ult i16 %ctlz2, 71051 ret i1 %res21052}1053 1054define i1 @cttz_fold(i16 %x) {1055; CHECK-LABEL: define i1 @cttz_fold(1056; CHECK-SAME: i16 [[X:%.*]]) {1057; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561058; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1059; CHECK: [[IF]]:1060; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 true)1061; CHECK-NEXT: ret i1 false1062; CHECK: [[ELSE]]:1063; CHECK-NEXT: ret i1 false1064;1065 %cmp = icmp ult i16 %x, 2561066 br i1 %cmp, label %if, label %else1067 1068if:1069 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 true)1070 %res = icmp uge i16 %cttz, 81071 ret i1 %res1072 1073else:1074 ret i1 false1075}1076 1077define i1 @cttz_nofold1(i16 %x) {1078; CHECK-LABEL: define i1 @cttz_nofold1(1079; CHECK-SAME: i16 [[X:%.*]]) {1080; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561081; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1082; CHECK: [[IF]]:1083; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 true)1084; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTTZ]], 71085; CHECK-NEXT: ret i1 [[RES]]1086; CHECK: [[ELSE]]:1087; CHECK-NEXT: ret i1 false1088;1089 %cmp = icmp ult i16 %x, 2561090 br i1 %cmp, label %if, label %else1091 1092if:1093 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 true)1094 %res = icmp uge i16 %cttz, 71095 ret i1 %res1096 1097else:1098 ret i1 false1099}1100 1101define i1 @cttz_nofold2(i16 %x) {1102; CHECK-LABEL: define i1 @cttz_nofold2(1103; CHECK-SAME: i16 [[X:%.*]]) {1104; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561105; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1106; CHECK: [[IF]]:1107; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 false)1108; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTTZ]], 81109; CHECK-NEXT: ret i1 [[RES]]1110; CHECK: [[ELSE]]:1111; CHECK-NEXT: ret i1 false1112;1113 %cmp = icmp ult i16 %x, 2561114 br i1 %cmp, label %if, label %else1115 1116if:1117 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 false)1118 %res = icmp uge i16 %cttz, 81119 ret i1 %res1120 1121else:1122 ret i1 false1123}1124 1125define i1 @ctpop_fold(i16 %x) {1126; CHECK-LABEL: define i1 @ctpop_fold(1127; CHECK-SAME: i16 [[X:%.*]]) {1128; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561129; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1130; CHECK: [[IF]]:1131; CHECK-NEXT: [[CTPOP:%.*]] = call i16 @llvm.ctpop.i16(i16 [[X]])1132; CHECK-NEXT: ret i1 true1133; CHECK: [[ELSE]]:1134; CHECK-NEXT: ret i1 true1135;1136 %cmp = icmp ult i16 %x, 2561137 br i1 %cmp, label %if, label %else1138 1139if:1140 %ctpop = call i16 @llvm.ctpop.i16(i16 %x)1141 %res = icmp ule i16 %ctpop, 81142 ret i1 %res1143 1144else:1145 ret i1 true1146}1147 1148define i1 @ctpop_nofold(i16 %x) {1149; CHECK-LABEL: define i1 @ctpop_nofold(1150; CHECK-SAME: i16 [[X:%.*]]) {1151; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 2561152; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]]1153; CHECK: [[IF]]:1154; CHECK-NEXT: [[CTPOP:%.*]] = call i16 @llvm.ctpop.i16(i16 [[X]])1155; CHECK-NEXT: [[RES:%.*]] = icmp samesign ule i16 [[CTPOP]], 71156; CHECK-NEXT: ret i1 [[RES]]1157; CHECK: [[ELSE]]:1158; CHECK-NEXT: ret i1 true1159;1160 %cmp = icmp ult i16 %x, 2561161 br i1 %cmp, label %if, label %else1162 1163if:1164 %ctpop = call i16 @llvm.ctpop.i16(i16 %x)1165 %res = icmp ule i16 %ctpop, 71166 ret i1 %res1167 1168else:1169 ret i1 true1170}1171 1172define i1 @icmp_eq_range_attr(i8 range(i8 1, 0) %i) {1173; CHECK-LABEL: define i1 @icmp_eq_range_attr(1174; CHECK-SAME: i8 range(i8 1, 0) [[I:%.*]]) {1175; CHECK-NEXT: ret i1 false1176;1177 %cmp = icmp eq i8 %i, 01178 ret i1 %cmp1179}1180 1181define i1 @neg_icmp_eq_range_attr(i8 range(i8 -1, 1) %i) {1182; CHECK-LABEL: define i1 @neg_icmp_eq_range_attr(1183; CHECK-SAME: i8 range(i8 -1, 1) [[I:%.*]]) {1184; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 01185; CHECK-NEXT: ret i1 [[CMP]]1186;1187 %cmp = icmp eq i8 %i, 01188 ret i1 %cmp1189}1190 1191declare range(i8 1, 0) i8 @returns_non_zero_range_helper()1192declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper()1193 1194define i1 @icmp_eq_range_return() {1195; CHECK-LABEL: define i1 @icmp_eq_range_return() {1196; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_zero_range_helper()1197; CHECK-NEXT: ret i1 false1198;1199 %i = call i8 @returns_non_zero_range_helper()1200 %cmp = icmp eq i8 %i, 01201 ret i1 %cmp1202}1203 1204define i1 @neg_icmp_eq_range_return() {1205; CHECK-LABEL: define i1 @neg_icmp_eq_range_return() {1206; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_zero_range_helper()1207; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 01208; CHECK-NEXT: ret i1 [[CMP]]1209;1210 %i = call i8 @returns_contain_zero_range_helper()1211 %cmp = icmp eq i8 %i, 01212 ret i1 %cmp1213}1214 1215declare i8 @returns_i8_helper()1216 1217define i1 @icmp_eq_range_call() {1218; CHECK-LABEL: define i1 @icmp_eq_range_call() {1219; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()1220; CHECK-NEXT: ret i1 false1221;1222 %i = call range(i8 1, 0) i8 @returns_i8_helper()1223 %cmp = icmp eq i8 %i, 01224 ret i1 %cmp1225}1226 1227define i1 @neg_icmp_eq_range_call() {1228; CHECK-LABEL: define i1 @neg_icmp_eq_range_call() {1229; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper()1230; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 01231; CHECK-NEXT: ret i1 [[CMP]]1232;1233 %i = call range(i8 0, 11) i8 @returns_i8_helper()1234 %cmp = icmp eq i8 %i, 01235 ret i1 %cmp1236}1237 1238define i16 @return_range_for_edge_value_zext(i8 %a) {1239; CHECK-LABEL: define range(i16 0, 98) i16 @return_range_for_edge_value_zext(1240; CHECK-SAME: i8 [[A:%.*]]) {1241; CHECK-NEXT: [[ENTRY:.*:]]1242; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i161243; CHECK-NEXT: br label %[[DISPATCH:.*]]1244; CHECK: [[DISPATCH]]:1245; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A]], 981246; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]1247; CHECK: [[TARGET]]:1248; CHECK-NEXT: ret i16 [[B]]1249;1250entry:1251 %b = zext i8 %a to i161252 br label %dispatch1253 1254dispatch:1255 %cmp = icmp ult i8 %a, 981256 br i1 %cmp, label %target, label %dispatch1257 1258target:1259 ret i16 %b1260}1261 1262define i16 @return_range_for_edge_value_sext(i8 %a) {1263; CHECK-LABEL: define range(i16 -55, 0) i16 @return_range_for_edge_value_sext(1264; CHECK-SAME: i8 [[A:%.*]]) {1265; CHECK-NEXT: [[ENTRY:.*:]]1266; CHECK-NEXT: [[B:%.*]] = sext i8 [[A]] to i161267; CHECK-NEXT: br label %[[DISPATCH:.*]]1268; CHECK: [[DISPATCH]]:1269; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A]], -561270; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]1271; CHECK: [[TARGET]]:1272; CHECK-NEXT: ret i16 [[B]]1273;1274entry:1275 %b = sext i8 %a to i161276 br label %dispatch1277 1278dispatch:1279 %cmp = icmp ugt i8 %a, -561280 br i1 %cmp, label %target, label %dispatch1281 1282target:1283 ret i16 %b1284}1285 1286define i8 @return_range_for_edge_value_trunc(i16 %a) {1287; CHECK-LABEL: define range(i8 0, 98) i8 @return_range_for_edge_value_trunc(1288; CHECK-SAME: i16 [[A:%.*]]) {1289; CHECK-NEXT: [[ENTRY:.*:]]1290; CHECK-NEXT: [[B:%.*]] = trunc i16 [[A]] to i81291; CHECK-NEXT: br label %[[DISPATCH:.*]]1292; CHECK: [[DISPATCH]]:1293; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[A]], 981294; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]1295; CHECK: [[TARGET]]:1296; CHECK-NEXT: ret i8 [[B]]1297;1298entry:1299 %b = trunc i16 %a to i81300 br label %dispatch1301 1302dispatch:1303 %cmp = icmp ult i16 %a, 981304 br i1 %cmp, label %target, label %dispatch1305 1306target:1307 ret i8 %b1308}1309 1310define i8 @neg_return_range_for_edge_value_trunc(i16 %a) {1311; CHECK-LABEL: define i8 @neg_return_range_for_edge_value_trunc(1312; CHECK-SAME: i16 [[A:%.*]]) {1313; CHECK-NEXT: [[ENTRY:.*:]]1314; CHECK-NEXT: [[B:%.*]] = trunc i16 [[A]] to i81315; CHECK-NEXT: br label %[[DISPATCH:.*]]1316; CHECK: [[DISPATCH]]:1317; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[A]], 2001318; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]1319; CHECK: [[TARGET]]:1320; CHECK-NEXT: ret i8 [[B]]1321;1322entry:1323 %b = trunc i16 %a to i81324 br label %dispatch1325 1326dispatch:1327 %cmp = icmp ugt i16 %a, 2001328 br i1 %cmp, label %target, label %dispatch1329 1330target:1331 ret i8 %b1332}1333 1334define i8 @return_range_for_edge_value_trunc_nuw(i16 %a) {1335; CHECK-LABEL: define range(i8 -55, 0) i8 @return_range_for_edge_value_trunc_nuw(1336; CHECK-SAME: i16 [[A:%.*]]) {1337; CHECK-NEXT: [[ENTRY:.*:]]1338; CHECK-NEXT: [[B:%.*]] = trunc nuw i16 [[A]] to i81339; CHECK-NEXT: br label %[[DISPATCH:.*]]1340; CHECK: [[DISPATCH]]:1341; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[A]], 2001342; CHECK-NEXT: br i1 [[CMP]], label %[[TARGET:.*]], label %[[DISPATCH]]1343; CHECK: [[TARGET]]:1344; CHECK-NEXT: ret i8 [[B]]1345;1346entry:1347 %b = trunc nuw i16 %a to i81348 br label %dispatch1349 1350dispatch:1351 %cmp = icmp ugt i16 %a, 2001352 br i1 %cmp, label %target, label %dispatch1353 1354target:1355 ret i8 %b1356}1357 1358declare i16 @llvm.ctlz.i16(i16, i1)1359declare i16 @llvm.cttz.i16(i16, i1)1360declare i16 @llvm.ctpop.i16(i16)1361declare i16 @llvm.abs.i16(i16, i1)1362declare void @llvm.assume(i1)1363;.1364; CHECK: [[RNG0]] = !{i64 4, i64 255}1365; CHECK: [[RNG1]] = !{i64 0, i64 1}1366; CHECK: [[RNG2]] = !{i64 4, i64 8, i64 15, i64 20}1367; CHECK: [[RNG3]] = !{i32 1, i32 2048}1368; CHECK: [[RNG4]] = !{i32 0, i32 256}1369; CHECK: [[RNG5]] = !{i16 0, i16 8}1370;.1371