812 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define void @idom_sign_bit_check_edge_dominates(i64 %a) {5; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 08; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]9; CHECK: land.lhs.true:10; CHECK-NEXT: br label [[LOR_END:%.*]]11; CHECK: lor.rhs:12; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i64 [[A]], 013; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]14; CHECK: land.rhs:15; CHECK-NEXT: br label [[LOR_END]]16; CHECK: lor.end:17; CHECK-NEXT: ret void18;19entry:20 %cmp = icmp slt i64 %a, 021 br i1 %cmp, label %land.lhs.true, label %lor.rhs22 23land.lhs.true:24 br label %lor.end25 26lor.rhs:27 %cmp2 = icmp sgt i64 %a, 028 br i1 %cmp2, label %land.rhs, label %lor.end29 30land.rhs:31 br label %lor.end32 33lor.end:34 ret void35}36 37define void @idom_sign_bit_check_edge_not_dominates(i64 %a, i1 %c1) {38; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(39; CHECK-NEXT: entry:40; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 041; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]42; CHECK: land.lhs.true:43; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_END:%.*]], label [[LOR_RHS]]44; CHECK: lor.rhs:45; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[A]], 046; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]47; CHECK: land.rhs:48; CHECK-NEXT: br label [[LOR_END]]49; CHECK: lor.end:50; CHECK-NEXT: ret void51;52entry:53 %cmp = icmp slt i64 %a, 054 br i1 %cmp, label %land.lhs.true, label %lor.rhs55 56land.lhs.true:57 br i1 %c1, label %lor.end, label %lor.rhs58 59lor.rhs:60 %cmp2 = icmp sgt i64 %a, 061 br i1 %cmp2, label %land.rhs, label %lor.end62 63land.rhs:64 br label %lor.end65 66lor.end:67 ret void68}69 70define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {71; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(72; CHECK-NEXT: entry:73; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 574; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]75; CHECK: land.lhs.true:76; CHECK-NEXT: br label [[LOR_END:%.*]]77; CHECK: lor.rhs:78; CHECK-NEXT: [[CMP3_NOT:%.*]] = icmp eq i64 [[A]], [[B:%.*]]79; CHECK-NEXT: br i1 [[CMP3_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]80; CHECK: land.rhs:81; CHECK-NEXT: br label [[LOR_END]]82; CHECK: lor.end:83; CHECK-NEXT: ret void84;85entry:86 %cmp = icmp slt i64 %a, 587 br i1 %cmp, label %land.lhs.true, label %lor.rhs88 89land.lhs.true:90 br label %lor.end91 92lor.rhs:93 %cmp2 = icmp sgt i64 %a, 594 %select = select i1 %cmp2, i64 %a, i64 595 %cmp3 = icmp ne i64 %select, %b96 br i1 %cmp3, label %land.rhs, label %lor.end97 98land.rhs:99 br label %lor.end100 101lor.end:102 ret void103}104 105define void @idom_zbranch(i64 %a) {106; CHECK-LABEL: @idom_zbranch(107; CHECK-NEXT: entry:108; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0109; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]110; CHECK: lor.rhs:111; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[A]], 0112; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]113; CHECK: land.rhs:114; CHECK-NEXT: br label [[LOR_END]]115; CHECK: lor.end:116; CHECK-NEXT: ret void117;118entry:119 %cmp = icmp sgt i64 %a, 0120 br i1 %cmp, label %lor.end, label %lor.rhs121 122lor.rhs:123 %cmp2 = icmp slt i64 %a, 0124 br i1 %cmp2, label %land.rhs, label %lor.end125 126land.rhs:127 br label %lor.end128 129lor.end:130 ret void131}132 133define void @idom_not_zbranch(i32 %a, i32 %b) {134; CHECK-LABEL: @idom_not_zbranch(135; CHECK-NEXT: entry:136; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0137; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]138; CHECK: if.end:139; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i32 [[A]], [[B:%.*]]140; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[RETURN]], label [[IF_THEN3:%.*]]141; CHECK: if.then3:142; CHECK-NEXT: br label [[RETURN]]143; CHECK: return:144; CHECK-NEXT: ret void145;146entry:147 %cmp = icmp sgt i32 %a, 0148 br i1 %cmp, label %return, label %if.end149 150if.end:151 %cmp1 = icmp slt i32 %a, 0152 %a. = select i1 %cmp1, i32 %a, i32 0153 %cmp2 = icmp ne i32 %a., %b154 br i1 %cmp2, label %if.then3, label %return155 156if.then3:157 br label %return158 159return:160 ret void161}162 163define void @trueblock_cmp_eq(i32 %a, i32 %b) {164; CHECK-LABEL: @trueblock_cmp_eq(165; CHECK-NEXT: entry:166; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0167; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]168; CHECK: if.end:169; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 1170; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]]171; CHECK: if.then3:172; CHECK-NEXT: br label [[RETURN]]173; CHECK: return:174; CHECK-NEXT: ret void175;176entry:177 %cmp = icmp sgt i32 %a, 0178 br i1 %cmp, label %if.end, label %return179 180if.end:181 %cmp1 = icmp slt i32 %a, 2182 br i1 %cmp1, label %if.then3, label %return183 184if.then3:185 br label %return186 187return:188 ret void189}190 191define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {192; CHECK-LABEL: @trueblock_cmp_is_false(193; CHECK-NEXT: entry:194; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]195; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]196; CHECK: t:197; CHECK-NEXT: ret i1 false198; CHECK: f:199; CHECK-NEXT: ret i1 false200;201entry:202 %cmp = icmp sgt i32 %x, %y203 br i1 %cmp, label %t, label %f204t:205 %cmp2 = icmp slt i32 %x, %y206 ret i1 %cmp2207f:208 ret i1 %cmp209}210 211define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {212; CHECK-LABEL: @trueblock_cmp_is_false_commute(213; CHECK-NEXT: entry:214; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]215; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]216; CHECK: t:217; CHECK-NEXT: ret i1 false218; CHECK: f:219; CHECK-NEXT: ret i1 false220;221entry:222 %cmp = icmp eq i32 %x, %y223 br i1 %cmp, label %t, label %f224t:225 %cmp2 = icmp sgt i32 %y, %x226 ret i1 %cmp2227f:228 ret i1 %cmp229}230 231define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {232; CHECK-LABEL: @trueblock_cmp_is_true(233; CHECK-NEXT: entry:234; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]235; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]236; CHECK: t:237; CHECK-NEXT: ret i1 true238; CHECK: f:239; CHECK-NEXT: ret i1 false240;241entry:242 %cmp = icmp ult i32 %x, %y243 br i1 %cmp, label %t, label %f244t:245 %cmp2 = icmp ne i32 %x, %y246 ret i1 %cmp2247f:248 ret i1 %cmp249}250 251define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {252; CHECK-LABEL: @trueblock_cmp_is_true_commute(253; CHECK-NEXT: entry:254; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]255; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]256; CHECK: t:257; CHECK-NEXT: ret i1 true258; CHECK: f:259; CHECK-NEXT: ret i1 false260;261entry:262 %cmp = icmp ugt i32 %x, %y263 br i1 %cmp, label %t, label %f264t:265 %cmp2 = icmp ne i32 %y, %x266 ret i1 %cmp2267f:268 ret i1 %cmp269}270 271define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {272; CHECK-LABEL: @falseblock_cmp_is_false(273; CHECK-NEXT: entry:274; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]275; CHECK-NEXT: br i1 [[CMP_NOT]], label [[F:%.*]], label [[T:%.*]]276; CHECK: t:277; CHECK-NEXT: ret i1 true278; CHECK: f:279; CHECK-NEXT: ret i1 false280;281entry:282 %cmp = icmp sle i32 %x, %y283 br i1 %cmp, label %t, label %f284t:285 ret i1 %cmp286f:287 %cmp2 = icmp slt i32 %x, %y288 ret i1 %cmp2289}290 291define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {292; CHECK-LABEL: @falseblock_cmp_is_false_commute(293; CHECK-NEXT: entry:294; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]295; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]296; CHECK: t:297; CHECK-NEXT: ret i1 true298; CHECK: f:299; CHECK-NEXT: ret i1 false300;301entry:302 %cmp = icmp eq i32 %x, %y303 br i1 %cmp, label %t, label %f304t:305 ret i1 %cmp306f:307 %cmp2 = icmp eq i32 %y, %x308 ret i1 %cmp2309}310 311define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {312; CHECK-LABEL: @falseblock_cmp_is_true(313; CHECK-NEXT: entry:314; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]315; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]316; CHECK: t:317; CHECK-NEXT: ret i1 true318; CHECK: f:319; CHECK-NEXT: ret i1 true320;321entry:322 %cmp = icmp ult i32 %x, %y323 br i1 %cmp, label %t, label %f324t:325 ret i1 %cmp326f:327 %cmp2 = icmp uge i32 %x, %y328 ret i1 %cmp2329}330 331define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {332; CHECK-LABEL: @falseblock_cmp_is_true_commute(333; CHECK-NEXT: entry:334; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]335; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]336; CHECK: t:337; CHECK-NEXT: ret i1 true338; CHECK: f:339; CHECK-NEXT: ret i1 true340;341entry:342 %cmp = icmp sgt i32 %x, %y343 br i1 %cmp, label %t, label %f344t:345 ret i1 %cmp346f:347 %cmp2 = icmp sge i32 %y, %x348 ret i1 %cmp2349}350 351; This used to infinite loop because of a conflict352; with min/max canonicalization.353 354define i32 @PR48900(i32 %i, ptr %p) {355; CHECK-LABEL: @PR48900(356; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[I:%.*]], i32 1)357; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[UMAX]], 0358; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]359; CHECK: truelabel:360; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[UMAX]], i32 2)361; CHECK-NEXT: ret i32 [[SMIN]]362; CHECK: falselabel:363; CHECK-NEXT: ret i32 0364;365 %maxcmp = icmp ugt i32 %i, 1366 %umax = select i1 %maxcmp, i32 %i, i32 1367 %i4 = icmp sgt i32 %umax, 0368 br i1 %i4, label %truelabel, label %falselabel369 370truelabel:371 %mincmp = icmp ult i32 %umax, 2372 %smin = select i1 %mincmp, i32 %umax, i32 2373 ret i32 %smin374 375falselabel:376 ret i32 0377}378 379; This used to infinite loop because of a conflict380; with min/max canonicalization.381 382define i8 @PR48900_alt(i8 %i, ptr %p) {383; CHECK-LABEL: @PR48900_alt(384; CHECK-NEXT: [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[I:%.*]], i8 -127)385; CHECK-NEXT: [[I4:%.*]] = icmp ugt i8 [[SMAX]], -128386; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]387; CHECK: truelabel:388; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[SMAX]], i8 -126)389; CHECK-NEXT: ret i8 [[UMIN]]390; CHECK: falselabel:391; CHECK-NEXT: ret i8 0392;393 %maxcmp = icmp sgt i8 %i, -127394 %smax = select i1 %maxcmp, i8 %i, i8 -127395 %i4 = icmp ugt i8 %smax, 128396 br i1 %i4, label %truelabel, label %falselabel397 398truelabel:399 %mincmp = icmp slt i8 %smax, -126400 %umin = select i1 %mincmp, i8 %smax, i8 -126401 ret i8 %umin402 403falselabel:404 ret i8 0405}406 407define i1 @and_mask1_eq(i32 %conv) {408; CHECK-LABEL: @and_mask1_eq(409; CHECK-NEXT: entry:410; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1411; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0412; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]413; CHECK: then:414; CHECK-NEXT: ret i1 false415; CHECK: else:416; CHECK-NEXT: ret i1 false417;418entry:419 %and = and i32 %conv, 1420 %cmp = icmp eq i32 %and, 0421 br i1 %cmp, label %then, label %else422 423then:424 ret i1 0425 426else:427 %and1 = and i32 %conv, 3428 %cmp1 = icmp eq i32 %and1, 0429 ret i1 %cmp1430}431 432define i1 @and_mask1_ne(i32 %conv) {433; CHECK-LABEL: @and_mask1_ne(434; CHECK-NEXT: entry:435; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1436; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0437; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]438; CHECK: then:439; CHECK-NEXT: ret i1 false440; CHECK: else:441; CHECK-NEXT: ret i1 true442;443entry:444 %and = and i32 %conv, 1445 %cmp = icmp eq i32 %and, 0446 br i1 %cmp, label %then, label %else447 448then:449 ret i1 0450 451else:452 %and1 = and i32 %conv, 3453 %cmp1 = icmp ne i32 %and1, 0454 ret i1 %cmp1455}456 457define i1 @and_mask2(i32 %conv) {458; CHECK-LABEL: @and_mask2(459; CHECK-NEXT: entry:460; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4461; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0462; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]463; CHECK: then:464; CHECK-NEXT: ret i1 false465; CHECK: else:466; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3467; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0468; CHECK-NEXT: ret i1 [[CMP1]]469;470entry:471 %and = and i32 %conv, 4472 %cmp = icmp eq i32 %and, 0473 br i1 %cmp, label %then, label %else474 475then:476 ret i1 0477 478else:479 %and1 = and i32 %conv, 3480 %cmp1 = icmp eq i32 %and1, 0481 ret i1 %cmp1482}483 484; TODO: %cmp1 can be folded into false.485 486define i1 @and_mask3(i32 %conv) {487; CHECK-LABEL: @and_mask3(488; CHECK-NEXT: entry:489; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 3490; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0491; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]492; CHECK: then:493; CHECK-NEXT: ret i1 false494; CHECK: else:495; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 7496; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0497; CHECK-NEXT: ret i1 [[CMP1]]498;499entry:500 %and = and i32 %conv, 3501 %cmp = icmp eq i32 %and, 0502 br i1 %cmp, label %then, label %else503 504then:505 ret i1 0506 507else:508 %and1 = and i32 %conv, 7509 %cmp1 = icmp eq i32 %and1, 0510 ret i1 %cmp1511}512 513define i1 @and_mask4(i32 %conv) {514; CHECK-LABEL: @and_mask4(515; CHECK-NEXT: entry:516; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4517; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0518; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]519; CHECK: then:520; CHECK-NEXT: ret i1 false521; CHECK: else:522; CHECK-NEXT: ret i1 false523;524entry:525 %and = and i32 %conv, 4526 %cmp = icmp eq i32 %and, 0527 br i1 %cmp, label %then, label %else528 529then:530 ret i1 0531 532else:533 %and1 = and i32 %conv, 7534 %cmp1 = icmp eq i32 %and1, 0535 ret i1 %cmp1536}537 538define i1 @or_nonzero_from_nonequal(i8 %x, i8 %y) {539; CHECK-LABEL: @or_nonzero_from_nonequal(540; CHECK-NEXT: entry:541; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]542; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]543; CHECK: if.then:544; CHECK-NEXT: ret i1 false545; CHECK: if.else:546; CHECK-NEXT: ret i1 false547;548entry:549 %cond = icmp eq i8 %x, %y550 br i1 %cond, label %if.else, label %if.then551 552if.then:553 %or = or i8 %x, %y554 %cmp = icmp eq i8 %or, 0555 ret i1 %cmp556 557if.else:558 ret i1 false559}560 561define i1 @test_nonequal_domcond1(i64 %x, i64 %y, i64 %z, i64 %w) {562; CHECK-LABEL: @test_nonequal_domcond1(563; CHECK-NEXT: entry:564; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]565; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]566; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]567; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]568; CHECK: if.then:569; CHECK-NEXT: ret i1 false570; CHECK: if.end:571; CHECK-NEXT: ret i1 false572;573entry:574 %cond1 = icmp eq i64 %y, %x575 %cond2 = icmp eq i64 %w, %z576 %or.cond = select i1 %cond1, i1 true, i1 %cond2577 br i1 %or.cond, label %if.end, label %if.then578 579if.then:580 %sub1 = sub i64 %w, %z581 %sub2 = sub i64 %y, %x582 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)583 %cmp = icmp eq i64 %umin, 0584 ret i1 %cmp585 586if.end:587 ret i1 false588}589 590define i1 @test_nonequal_domcond2(i64 %x, i64 %y, i64 %z, i64 %w) {591; CHECK-LABEL: @test_nonequal_domcond2(592; CHECK-NEXT: entry:593; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]594; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]595; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false596; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]597; CHECK: if.then:598; CHECK-NEXT: ret i1 false599; CHECK: if.end:600; CHECK-NEXT: ret i1 false601;602entry:603 %cond1 = icmp ne i64 %y, %x604 %cond2 = icmp ne i64 %w, %z605 %or.cond = select i1 %cond1, i1 %cond2, i1 false606 br i1 %or.cond, label %if.then, label %if.end607 608if.then:609 %sub1 = sub i64 %w, %z610 %sub2 = sub i64 %y, %x611 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)612 %cmp = icmp eq i64 %umin, 0613 ret i1 %cmp614 615if.end:616 ret i1 false617}618 619define i1 @test_nonequal_assume(i64 %x, i64 %y, i64 %z, i64 %w) {620; CHECK-LABEL: @test_nonequal_assume(621; CHECK-NEXT: entry:622; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]623; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])624; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]625; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])626; CHECK-NEXT: ret i1 false627;628entry:629 %cond1 = icmp ne i64 %y, %x630 call void @llvm.assume(i1 %cond1)631 %cond2 = icmp ne i64 %w, %z632 call void @llvm.assume(i1 %cond2)633 634 %sub1 = sub i64 %w, %z635 %sub2 = sub i64 %y, %x636 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)637 %cmp = icmp eq i64 %umin, 0638 ret i1 %cmp639}640 641; Negative tests642 643define i1 @test_nonequal_invalid_domcond1(i64 %x, i64 %y, i64 %z, i64 %w) {644; CHECK-LABEL: @test_nonequal_invalid_domcond1(645; CHECK-NEXT: entry:646; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]647; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]648; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]649; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]650; CHECK: if.then:651; CHECK-NEXT: ret i1 true652; CHECK: if.end:653; CHECK-NEXT: ret i1 false654;655entry:656 %cond1 = icmp ne i64 %y, %x657 %cond2 = icmp eq i64 %w, %z658 %or.cond = select i1 %cond1, i1 true, i1 %cond2659 br i1 %or.cond, label %if.end, label %if.then660 661if.then:662 %sub1 = sub i64 %w, %z663 %sub2 = sub i64 %y, %x664 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)665 %cmp = icmp eq i64 %umin, 0666 ret i1 %cmp667 668if.end:669 ret i1 false670}671 672define i1 @test_nonequal_invalid_domcond2(i64 %x, i64 %y, i64 %z, i64 %w) {673; CHECK-LABEL: @test_nonequal_invalid_domcond2(674; CHECK-NEXT: entry:675; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]676; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]677; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]678; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]679; CHECK: if.then:680; CHECK-NEXT: br label [[IF_END]]681; CHECK: if.end:682; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]683; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]684; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])685; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0686; CHECK-NEXT: ret i1 [[CMP]]687;688entry:689 %cond1 = icmp eq i64 %y, %x690 %cond2 = icmp eq i64 %w, %z691 %or.cond = select i1 %cond1, i1 true, i1 %cond2692 br i1 %or.cond, label %if.then, label %if.end693 694if.then:695 br label %if.end696 697if.end:698 %sub1 = sub i64 %w, %z699 %sub2 = sub i64 %y, %x700 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)701 %cmp = icmp eq i64 %umin, 0702 ret i1 %cmp703}704 705define i1 @test_nonequal_invalid_assume(i64 %x, i64 %y, i64 %z, i64 %w) {706; CHECK-LABEL: @test_nonequal_invalid_assume(707; CHECK-NEXT: entry:708; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W:%.*]], [[Z:%.*]]709; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y:%.*]], [[X:%.*]]710; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])711; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0712; CHECK-NEXT: call void @side_effect()713; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y]], [[X]]714; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])715; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W]], [[Z]]716; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])717; CHECK-NEXT: ret i1 [[CMP]]718;719entry:720 %sub1 = sub i64 %w, %z721 %sub2 = sub i64 %y, %x722 %umin = call i64 @llvm.umin.i64(i64 %sub1, i64 %sub2)723 %cmp = icmp eq i64 %umin, 0724 725 call void @side_effect()726 %cond1 = icmp ne i64 %y, %x727 call void @llvm.assume(i1 %cond1)728 %cond2 = icmp ne i64 %w, %z729 call void @llvm.assume(i1 %cond2)730 ret i1 %cmp731}732 733; TODO: We can prove `%cond2` is always false734define void @test_nonequal_domcond_loop1(i32 %x0, i1 %x1) {735; CHECK-LABEL: @test_nonequal_domcond_loop1(736; CHECK-NEXT: entry:737; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]738; CHECK: loop.header:739; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X0:%.*]], [[LATCH:%.*]] ]740; CHECK-NEXT: br label [[LATCH]]741; CHECK: latch:742; CHECK-NEXT: br i1 [[X1:%.*]], label [[IF_THEN:%.*]], label [[LOOP_HEADER]]743; CHECK: if.then:744; CHECK-NEXT: [[AND:%.*]] = and i32 [[X0]], 1745; CHECK-NEXT: [[COND1:%.*]] = icmp eq i32 [[AND]], [[PHI]]746; CHECK-NEXT: br i1 [[COND1]], label [[IF_THEN2:%.*]], label [[LATCH]]747; CHECK: if.then2:748; CHECK-NEXT: br label [[BB:%.*]]749; CHECK: indirectbb:750; CHECK-NEXT: [[COND2:%.*]] = icmp eq i32 [[PHI]], 31751; CHECK-NEXT: br i1 [[COND2]], label [[EXIT:%.*]], label [[LATCH]]752; CHECK: exit:753; CHECK-NEXT: ret void754;755entry:756 br label %loop.header757 758loop.header:759 %phi = phi i32 [ 0, %entry ], [ %x0, %latch ]760 br label %latch761 762latch:763 br i1 %x1, label %if.then, label %loop.header764 765if.then:766 %and = and i32 %x0, 1767 %cond1 = icmp eq i32 %and, %phi768 br i1 %cond1, label %if.then2, label %latch769 770if.then2:771 br label %indirectbb772 773indirectbb:774 %cond2 = icmp eq i32 %phi, 31775 br i1 %cond2, label %exit, label %latch776 777exit:778 ret void779}780 781define void @test_nonequal_domcond_loop2(ptr %p) {782; CHECK-LABEL: @test_nonequal_domcond_loop2(783; CHECK-NEXT: entry:784; CHECK-NEXT: [[LOAD1:%.*]] = load volatile i8, ptr [[P:%.*]], align 1785; CHECK-NEXT: br label [[WHILE_COND:%.*]]786; CHECK: while.cond:787; CHECK-NEXT: [[LOAD2:%.*]] = load volatile i8, ptr [[P]], align 1788; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[LOAD2]], 0789; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i8 [[LOAD2]], [[LOAD1]]790; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]791; CHECK-NEXT: br i1 [[OR]], label [[WHILE_COND]], label [[FOR_BODY:%.*]]792; CHECK: for.body:793; CHECK-NEXT: br i1 false, label [[WHILE_COND]], label [[FOR_BODY]]794;795entry:796 %load1 = load volatile i8, ptr %p, align 1797 br label %while.cond798 799while.cond:800 %load2 = load volatile i8, ptr %p, align 1801 %cmp1 = icmp eq i8 %load2, 0802 %cmp2 = icmp uge i8 %load2, %load1803 %or = select i1 %cmp1, i1 true, i1 %cmp2804 br i1 %or, label %while.cond, label %for.body805 806for.body:807 %cond = icmp eq i8 %load1, %load2808 br i1 %cond, label %while.cond, label %for.body809}810 811declare void @side_effect()812