brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.9 KiB · a72b5e0 Raw
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