brintos

brintos / llvm-project-archived public Read only

0
0
Text · 45.6 KiB · 04f309b Raw
1300 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S %s -passes='loop-mssa(licm)'  -verify-memoryssa  | FileCheck %s3 4; turn to %iv <u umin(inv_1, inv_2) and hoist it out of loop.5define i32 @test_ult(i32 %start, i32 %inv_1, i32 %inv_2) {6; CHECK-LABEL: @test_ult(7; CHECK-NEXT:  entry:8; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])9; CHECK-NEXT:    br label [[LOOP:%.*]]10; CHECK:       loop:11; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]12; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]13; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 114; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]15; CHECK:       exit:16; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]17; CHECK-NEXT:    ret i32 [[IV_LCSSA]]18;19entry:20  br label %loop21 22loop:23  %iv = phi i32 [%start, %entry], [%iv.next, %loop]24  %cmp_1 = icmp ult i32 %iv, %inv_125  %cmp_2 = icmp ult i32 %iv, %inv_226  %loop_cond = and i1 %cmp_1, %cmp_227  %iv.next = add i32 %iv, 128  br i1 %loop_cond, label %loop, label %exit29 30exit:31  ret i32 %iv32}33 34; Do not optimize: pointer types.35define ptr @test_ult_ptr_neg(ptr %start, ptr %inv_1, ptr %inv_2) {36; CHECK-LABEL: @test_ult_ptr_neg(37; CHECK-NEXT:  entry:38; CHECK-NEXT:    br label [[LOOP:%.*]]39; CHECK:       loop:40; CHECK-NEXT:    [[IV:%.*]] = phi ptr [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]41; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult ptr [[IV]], [[INV_1:%.*]]42; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult ptr [[IV]], [[INV_2:%.*]]43; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]44; CHECK-NEXT:    [[IV_NEXT]] = getelementptr i32, ptr [[IV]], i64 445; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]46; CHECK:       exit:47; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi ptr [ [[IV]], [[LOOP]] ]48; CHECK-NEXT:    ret ptr [[IV_LCSSA]]49;50entry:51  br label %loop52 53loop:54  %iv = phi ptr [%start, %entry], [%iv.next, %loop]55  %cmp_1 = icmp ult ptr %iv, %inv_156  %cmp_2 = icmp ult ptr %iv, %inv_257  %loop_cond = and i1 %cmp_1, %cmp_258  %iv.next = getelementptr i32, ptr %iv, i64 459  br i1 %loop_cond, label %loop, label %exit60 61exit:62  ret ptr %iv63}64 65; turn to %iv <=u umin(inv_1, inv_2) and hoist it out of loop.66define i32 @test_ule(i32 %start, i32 %inv_1, i32 %inv_2) {67; CHECK-LABEL: @test_ule(68; CHECK-NEXT:  entry:69; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])70; CHECK-NEXT:    br label [[LOOP:%.*]]71; CHECK:       loop:72; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]73; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ule i32 [[IV]], [[INVARIANT_UMIN]]74; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 175; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]76; CHECK:       exit:77; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]78; CHECK-NEXT:    ret i32 [[IV_LCSSA]]79;80entry:81  br label %loop82 83loop:84  %iv = phi i32 [%start, %entry], [%iv.next, %loop]85  %cmp_1 = icmp ule i32 %iv, %inv_186  %cmp_2 = icmp ule i32 %iv, %inv_287  %loop_cond = and i1 %cmp_1, %cmp_288  %iv.next = add i32 %iv, 189  br i1 %loop_cond, label %loop, label %exit90 91exit:92  ret i32 %iv93}94 95; turn to %iv <s smin(inv_1, inv_2) and hoist it out of loop.96define i32 @test_slt(i32 %start, i32 %inv_1, i32 %inv_2) {97; CHECK-LABEL: @test_slt(98; CHECK-NEXT:  entry:99; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])100; CHECK-NEXT:    br label [[LOOP:%.*]]101; CHECK:       loop:102; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]103; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[INVARIANT_SMIN]]104; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1105; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]106; CHECK:       exit:107; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]108; CHECK-NEXT:    ret i32 [[IV_LCSSA]]109;110entry:111  br label %loop112 113loop:114  %iv = phi i32 [%start, %entry], [%iv.next, %loop]115  %cmp_1 = icmp slt i32 %iv, %inv_1116  %cmp_2 = icmp slt i32 %iv, %inv_2117  %loop_cond = and i1 %cmp_1, %cmp_2118  %iv.next = add i32 %iv, 1119  br i1 %loop_cond, label %loop, label %exit120 121exit:122  ret i32 %iv123}124 125; turn to %iv <=s smin(inv_1, inv_2) and hoist it out of loop.126define i32 @test_sle(i32 %start, i32 %inv_1, i32 %inv_2) {127; CHECK-LABEL: @test_sle(128; CHECK-NEXT:  entry:129; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])130; CHECK-NEXT:    br label [[LOOP:%.*]]131; CHECK:       loop:132; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]133; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sle i32 [[IV]], [[INVARIANT_SMIN]]134; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1135; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]136; CHECK:       exit:137; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]138; CHECK-NEXT:    ret i32 [[IV_LCSSA]]139;140entry:141  br label %loop142 143loop:144  %iv = phi i32 [%start, %entry], [%iv.next, %loop]145  %cmp_1 = icmp sle i32 %iv, %inv_1146  %cmp_2 = icmp sle i32 %iv, %inv_2147  %loop_cond = and i1 %cmp_1, %cmp_2148  %iv.next = add i32 %iv, 1149  br i1 %loop_cond, label %loop, label %exit150 151exit:152  ret i32 %iv153}154 155; turn to %iv >u umax(inv_1, inv_2) and hoist it out of loop.156define i32 @test_ugt(i32 %start, i32 %inv_1, i32 %inv_2) {157; CHECK-LABEL: @test_ugt(158; CHECK-NEXT:  entry:159; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])160; CHECK-NEXT:    br label [[LOOP:%.*]]161; CHECK:       loop:162; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]163; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ugt i32 [[IV]], [[INVARIANT_UMAX]]164; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1165; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]166; CHECK:       exit:167; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]168; CHECK-NEXT:    ret i32 [[IV_LCSSA]]169;170entry:171  br label %loop172 173loop:174  %iv = phi i32 [%start, %entry], [%iv.next, %loop]175  %cmp_1 = icmp ugt i32 %iv, %inv_1176  %cmp_2 = icmp ugt i32 %iv, %inv_2177  %loop_cond = and i1 %cmp_1, %cmp_2178  %iv.next = add i32 %iv, 1179  br i1 %loop_cond, label %loop, label %exit180 181exit:182  ret i32 %iv183}184 185; turn to %iv >=u umax(inv_1, inv_2) and hoist it out of loop.186define i32 @test_uge(i32 %start, i32 %inv_1, i32 %inv_2) {187; CHECK-LABEL: @test_uge(188; CHECK-NEXT:  entry:189; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])190; CHECK-NEXT:    br label [[LOOP:%.*]]191; CHECK:       loop:192; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]193; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp uge i32 [[IV]], [[INVARIANT_UMAX]]194; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1195; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]196; CHECK:       exit:197; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]198; CHECK-NEXT:    ret i32 [[IV_LCSSA]]199;200entry:201  br label %loop202 203loop:204  %iv = phi i32 [%start, %entry], [%iv.next, %loop]205  %cmp_1 = icmp uge i32 %iv, %inv_1206  %cmp_2 = icmp uge i32 %iv, %inv_2207  %loop_cond = and i1 %cmp_1, %cmp_2208  %iv.next = add i32 %iv, 1209  br i1 %loop_cond, label %loop, label %exit210 211exit:212  ret i32 %iv213}214 215; turn to %iv >s smax(inv_1, inv_2) and hoist it out of loop.216define i32 @test_sgt(i32 %start, i32 %inv_1, i32 %inv_2) {217; CHECK-LABEL: @test_sgt(218; CHECK-NEXT:  entry:219; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])220; CHECK-NEXT:    br label [[LOOP:%.*]]221; CHECK:       loop:222; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]223; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sgt i32 [[IV]], [[INVARIANT_SMAX]]224; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1225; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]226; CHECK:       exit:227; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]228; CHECK-NEXT:    ret i32 [[IV_LCSSA]]229;230entry:231  br label %loop232 233loop:234  %iv = phi i32 [%start, %entry], [%iv.next, %loop]235  %cmp_1 = icmp sgt i32 %iv, %inv_1236  %cmp_2 = icmp sgt i32 %iv, %inv_2237  %loop_cond = and i1 %cmp_1, %cmp_2238  %iv.next = add i32 %iv, 1239  br i1 %loop_cond, label %loop, label %exit240 241exit:242  ret i32 %iv243}244 245define i32 @test_sgt_samesign(i32 %start, i32 %inv_1, i32 %inv_2) {246; CHECK-LABEL: @test_sgt_samesign(247; CHECK-NEXT:  entry:248; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])249; CHECK-NEXT:    br label [[LOOP:%.*]]250; CHECK:       loop:251; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]252; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sgt i32 [[IV]], [[INVARIANT_SMAX]]253; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1254; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]255; CHECK:       exit:256; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]257; CHECK-NEXT:    ret i32 [[IV_LCSSA]]258;259entry:260  br label %loop261 262loop:263  %iv = phi i32 [%start, %entry], [%iv.next, %loop]264  %cmp_1 = icmp samesign ugt i32 %iv, %inv_1265  %cmp_2 = icmp sgt i32 %iv, %inv_2266  %loop_cond = and i1 %cmp_1, %cmp_2267  %iv.next = add i32 %iv, 1268  br i1 %loop_cond, label %loop, label %exit269 270exit:271  ret i32 %iv272}273 274; turn to %iv >=s smax(inv_1, inv_2) and hoist it out of loop.275define i32 @test_sge(i32 %start, i32 %inv_1, i32 %inv_2) {276; CHECK-LABEL: @test_sge(277; CHECK-NEXT:  entry:278; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])279; CHECK-NEXT:    br label [[LOOP:%.*]]280; CHECK:       loop:281; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]282; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sge i32 [[IV]], [[INVARIANT_SMAX]]283; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1284; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]285; CHECK:       exit:286; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]287; CHECK-NEXT:    ret i32 [[IV_LCSSA]]288;289entry:290  br label %loop291 292loop:293  %iv = phi i32 [%start, %entry], [%iv.next, %loop]294  %cmp_1 = icmp sge i32 %iv, %inv_1295  %cmp_2 = icmp sge i32 %iv, %inv_2296  %loop_cond = and i1 %cmp_1, %cmp_2297  %iv.next = add i32 %iv, 1298  br i1 %loop_cond, label %loop, label %exit299 300exit:301  ret i32 %iv302}303 304define i32 @test_sge_samesign(i32 %start, i32 %inv_1, i32 %inv_2) {305; CHECK-LABEL: @test_sge_samesign(306; CHECK-NEXT:  entry:307; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])308; CHECK-NEXT:    br label [[LOOP:%.*]]309; CHECK:       loop:310; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]311; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sge i32 [[IV]], [[INVARIANT_SMAX]]312; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1313; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]314; CHECK:       exit:315; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]316; CHECK-NEXT:    ret i32 [[IV_LCSSA]]317;318entry:319  br label %loop320 321loop:322  %iv = phi i32 [%start, %entry], [%iv.next, %loop]323  %cmp_1 = icmp sge i32 %iv, %inv_1324  %cmp_2 = icmp samesign uge i32 %iv, %inv_2325  %loop_cond = and i1 %cmp_1, %cmp_2326  %iv.next = add i32 %iv, 1327  br i1 %loop_cond, label %loop, label %exit328 329exit:330  ret i32 %iv331}332 333; Turn OR to AND and handle accordingly.334define i32 @test_ult_inv(i32 %start, i32 %inv_1, i32 %inv_2) {335; CHECK-LABEL: @test_ult_inv(336; CHECK-NEXT:  entry:337; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])338; CHECK-NEXT:    br label [[LOOP:%.*]]339; CHECK:       loop:340; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]341; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMAX]]342; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1343; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]344; CHECK:       exit:345; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]346; CHECK-NEXT:    ret i32 [[IV_LCSSA]]347;348entry:349  br label %loop350 351loop:352  %iv = phi i32 [%start, %entry], [%iv.next, %loop]353  %cmp_1 = icmp ult i32 %iv, %inv_1354  %cmp_2 = icmp ult i32 %iv, %inv_2355  %loop_cond = or i1 %cmp_1, %cmp_2356  %iv.next = add i32 %iv, 1357  br i1 %loop_cond, label %loop, label %exit358 359exit:360  ret i32 %iv361}362 363; Turn OR to AND and handle accordingly.364define i32 @test_ule_inv(i32 %start, i32 %inv_1, i32 %inv_2) {365; CHECK-LABEL: @test_ule_inv(366; CHECK-NEXT:  entry:367; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])368; CHECK-NEXT:    br label [[LOOP:%.*]]369; CHECK:       loop:370; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]371; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ule i32 [[IV]], [[INVARIANT_UMAX]]372; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1373; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]374; CHECK:       exit:375; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]376; CHECK-NEXT:    ret i32 [[IV_LCSSA]]377;378entry:379  br label %loop380 381loop:382  %iv = phi i32 [%start, %entry], [%iv.next, %loop]383  %cmp_1 = icmp ule i32 %iv, %inv_1384  %cmp_2 = icmp ule i32 %iv, %inv_2385  %loop_cond = or i1 %cmp_1, %cmp_2386  %iv.next = add i32 %iv, 1387  br i1 %loop_cond, label %loop, label %exit388 389exit:390  ret i32 %iv391}392 393; Turn OR to AND and handle accordingly.394define i32 @test_slt_inv(i32 %start, i32 %inv_1, i32 %inv_2) {395; CHECK-LABEL: @test_slt_inv(396; CHECK-NEXT:  entry:397; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])398; CHECK-NEXT:    br label [[LOOP:%.*]]399; CHECK:       loop:400; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]401; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[INVARIANT_SMAX]]402; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1403; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]404; CHECK:       exit:405; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]406; CHECK-NEXT:    ret i32 [[IV_LCSSA]]407;408entry:409  br label %loop410 411loop:412  %iv = phi i32 [%start, %entry], [%iv.next, %loop]413  %cmp_1 = icmp slt i32 %iv, %inv_1414  %cmp_2 = icmp slt i32 %iv, %inv_2415  %loop_cond = or i1 %cmp_1, %cmp_2416  %iv.next = add i32 %iv, 1417  br i1 %loop_cond, label %loop, label %exit418 419exit:420  ret i32 %iv421}422 423; Turn OR to AND and handle accordingly.424define i32 @test_sle_inv(i32 %start, i32 %inv_1, i32 %inv_2) {425; CHECK-LABEL: @test_sle_inv(426; CHECK-NEXT:  entry:427; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])428; CHECK-NEXT:    br label [[LOOP:%.*]]429; CHECK:       loop:430; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]431; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sle i32 [[IV]], [[INVARIANT_SMAX]]432; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1433; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]434; CHECK:       exit:435; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]436; CHECK-NEXT:    ret i32 [[IV_LCSSA]]437;438entry:439  br label %loop440 441loop:442  %iv = phi i32 [%start, %entry], [%iv.next, %loop]443  %cmp_1 = icmp sle i32 %iv, %inv_1444  %cmp_2 = icmp sle i32 %iv, %inv_2445  %loop_cond = or i1 %cmp_1, %cmp_2446  %iv.next = add i32 %iv, 1447  br i1 %loop_cond, label %loop, label %exit448 449exit:450  ret i32 %iv451}452 453; Turn OR to AND and handle accordingly.454define i32 @test_ugt_inv(i32 %start, i32 %inv_1, i32 %inv_2) {455; CHECK-LABEL: @test_ugt_inv(456; CHECK-NEXT:  entry:457; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])458; CHECK-NEXT:    br label [[LOOP:%.*]]459; CHECK:       loop:460; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]461; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ugt i32 [[IV]], [[INVARIANT_UMIN]]462; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1463; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]464; CHECK:       exit:465; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]466; CHECK-NEXT:    ret i32 [[IV_LCSSA]]467;468entry:469  br label %loop470 471loop:472  %iv = phi i32 [%start, %entry], [%iv.next, %loop]473  %cmp_1 = icmp ugt i32 %iv, %inv_1474  %cmp_2 = icmp ugt i32 %iv, %inv_2475  %loop_cond = or i1 %cmp_1, %cmp_2476  %iv.next = add i32 %iv, 1477  br i1 %loop_cond, label %loop, label %exit478 479exit:480  ret i32 %iv481}482 483; Turn OR to AND and handle accordingly.484define i32 @test_uge_inv(i32 %start, i32 %inv_1, i32 %inv_2) {485; CHECK-LABEL: @test_uge_inv(486; CHECK-NEXT:  entry:487; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])488; CHECK-NEXT:    br label [[LOOP:%.*]]489; CHECK:       loop:490; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]491; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp uge i32 [[IV]], [[INVARIANT_UMIN]]492; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1493; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]494; CHECK:       exit:495; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]496; CHECK-NEXT:    ret i32 [[IV_LCSSA]]497;498entry:499  br label %loop500 501loop:502  %iv = phi i32 [%start, %entry], [%iv.next, %loop]503  %cmp_1 = icmp uge i32 %iv, %inv_1504  %cmp_2 = icmp uge i32 %iv, %inv_2505  %loop_cond = or i1 %cmp_1, %cmp_2506  %iv.next = add i32 %iv, 1507  br i1 %loop_cond, label %loop, label %exit508 509exit:510  ret i32 %iv511}512 513; Turn OR to AND and handle accordingly.514define i32 @test_sgt_inv(i32 %start, i32 %inv_1, i32 %inv_2) {515; CHECK-LABEL: @test_sgt_inv(516; CHECK-NEXT:  entry:517; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])518; CHECK-NEXT:    br label [[LOOP:%.*]]519; CHECK:       loop:520; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]521; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sgt i32 [[IV]], [[INVARIANT_SMIN]]522; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1523; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]524; CHECK:       exit:525; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]526; CHECK-NEXT:    ret i32 [[IV_LCSSA]]527;528entry:529  br label %loop530 531loop:532  %iv = phi i32 [%start, %entry], [%iv.next, %loop]533  %cmp_1 = icmp sgt i32 %iv, %inv_1534  %cmp_2 = icmp sgt i32 %iv, %inv_2535  %loop_cond = or i1 %cmp_1, %cmp_2536  %iv.next = add i32 %iv, 1537  br i1 %loop_cond, label %loop, label %exit538 539exit:540  ret i32 %iv541}542 543; Turn OR to AND and handle accordingly.544define i32 @test_sge_inv(i32 %start, i32 %inv_1, i32 %inv_2) {545; CHECK-LABEL: @test_sge_inv(546; CHECK-NEXT:  entry:547; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])548; CHECK-NEXT:    br label [[LOOP:%.*]]549; CHECK:       loop:550; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]551; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sge i32 [[IV]], [[INVARIANT_SMIN]]552; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1553; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]554; CHECK:       exit:555; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]556; CHECK-NEXT:    ret i32 [[IV_LCSSA]]557;558entry:559  br label %loop560 561loop:562  %iv = phi i32 [%start, %entry], [%iv.next, %loop]563  %cmp_1 = icmp sge i32 %iv, %inv_1564  %cmp_2 = icmp sge i32 %iv, %inv_2565  %loop_cond = or i1 %cmp_1, %cmp_2566  %iv.next = add i32 %iv, 1567  br i1 %loop_cond, label %loop, label %exit568 569exit:570  ret i32 %iv571}572 573; turn to %iv <u umin(inv_1, inv_2) and hoist it out of loop.574define i32 @test_ult_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {575; CHECK-LABEL: @test_ult_swapped(576; CHECK-NEXT:  entry:577; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])578; CHECK-NEXT:    br label [[LOOP:%.*]]579; CHECK:       loop:580; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]581; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]582; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1583; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]584; CHECK:       exit:585; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]586; CHECK-NEXT:    ret i32 [[IV_LCSSA]]587;588entry:589  br label %loop590 591loop:592  %iv = phi i32 [%start, %entry], [%iv.next, %loop]593  %cmp_1 = icmp ugt i32 %inv_1, %iv594  %cmp_2 = icmp ugt i32 %inv_2, %iv595  %loop_cond = and i1 %cmp_1, %cmp_2596  %iv.next = add i32 %iv, 1597  br i1 %loop_cond, label %loop, label %exit598 599exit:600  ret i32 %iv601}602 603; turn to %iv <=u umin(inv_1, inv_2) and hoist it out of loop.604define i32 @test_ule_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {605; CHECK-LABEL: @test_ule_swapped(606; CHECK-NEXT:  entry:607; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])608; CHECK-NEXT:    br label [[LOOP:%.*]]609; CHECK:       loop:610; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]611; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ule i32 [[IV]], [[INVARIANT_UMIN]]612; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1613; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]614; CHECK:       exit:615; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]616; CHECK-NEXT:    ret i32 [[IV_LCSSA]]617;618entry:619  br label %loop620 621loop:622  %iv = phi i32 [%start, %entry], [%iv.next, %loop]623  %cmp_1 = icmp uge i32 %inv_1, %iv624  %cmp_2 = icmp uge i32 %inv_2, %iv625  %loop_cond = and i1 %cmp_1, %cmp_2626  %iv.next = add i32 %iv, 1627  br i1 %loop_cond, label %loop, label %exit628 629exit:630  ret i32 %iv631}632 633; turn to %iv <s smin(inv_1, inv_2) and hoist it out of loop.634define i32 @test_slt_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {635; CHECK-LABEL: @test_slt_swapped(636; CHECK-NEXT:  entry:637; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])638; CHECK-NEXT:    br label [[LOOP:%.*]]639; CHECK:       loop:640; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]641; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[INVARIANT_SMIN]]642; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1643; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]644; CHECK:       exit:645; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]646; CHECK-NEXT:    ret i32 [[IV_LCSSA]]647;648entry:649  br label %loop650 651loop:652  %iv = phi i32 [%start, %entry], [%iv.next, %loop]653  %cmp_1 = icmp sgt i32 %inv_1, %iv654  %cmp_2 = icmp sgt i32 %inv_2, %iv655  %loop_cond = and i1 %cmp_1, %cmp_2656  %iv.next = add i32 %iv, 1657  br i1 %loop_cond, label %loop, label %exit658 659exit:660  ret i32 %iv661}662 663; turn to %iv <=s smin(inv_1, inv_2) and hoist it out of loop.664define i32 @test_sle_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {665; CHECK-LABEL: @test_sle_swapped(666; CHECK-NEXT:  entry:667; CHECK-NEXT:    [[INVARIANT_SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])668; CHECK-NEXT:    br label [[LOOP:%.*]]669; CHECK:       loop:670; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]671; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sle i32 [[IV]], [[INVARIANT_SMIN]]672; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1673; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]674; CHECK:       exit:675; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]676; CHECK-NEXT:    ret i32 [[IV_LCSSA]]677;678entry:679  br label %loop680 681loop:682  %iv = phi i32 [%start, %entry], [%iv.next, %loop]683  %cmp_1 = icmp sge i32 %inv_1, %iv684  %cmp_2 = icmp sge i32 %inv_2, %iv685  %loop_cond = and i1 %cmp_1, %cmp_2686  %iv.next = add i32 %iv, 1687  br i1 %loop_cond, label %loop, label %exit688 689exit:690  ret i32 %iv691}692 693; turn to %iv >u umax(inv_1, inv_2) and hoist it out of loop.694define i32 @test_ugt_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {695; CHECK-LABEL: @test_ugt_swapped(696; CHECK-NEXT:  entry:697; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])698; CHECK-NEXT:    br label [[LOOP:%.*]]699; CHECK:       loop:700; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]701; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ugt i32 [[IV]], [[INVARIANT_UMAX]]702; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1703; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]704; CHECK:       exit:705; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]706; CHECK-NEXT:    ret i32 [[IV_LCSSA]]707;708entry:709  br label %loop710 711loop:712  %iv = phi i32 [%start, %entry], [%iv.next, %loop]713  %cmp_1 = icmp ult i32 %inv_1, %iv714  %cmp_2 = icmp ult i32 %inv_2, %iv715  %loop_cond = and i1 %cmp_1, %cmp_2716  %iv.next = add i32 %iv, 1717  br i1 %loop_cond, label %loop, label %exit718 719exit:720  ret i32 %iv721}722 723; turn to %iv >=u umax(inv_1, inv_2) and hoist it out of loop.724define i32 @test_uge_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {725; CHECK-LABEL: @test_uge_swapped(726; CHECK-NEXT:  entry:727; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])728; CHECK-NEXT:    br label [[LOOP:%.*]]729; CHECK:       loop:730; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]731; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp uge i32 [[IV]], [[INVARIANT_UMAX]]732; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1733; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]734; CHECK:       exit:735; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]736; CHECK-NEXT:    ret i32 [[IV_LCSSA]]737;738entry:739  br label %loop740 741loop:742  %iv = phi i32 [%start, %entry], [%iv.next, %loop]743  %cmp_1 = icmp ule i32 %inv_1, %iv744  %cmp_2 = icmp ule i32 %inv_2, %iv745  %loop_cond = and i1 %cmp_1, %cmp_2746  %iv.next = add i32 %iv, 1747  br i1 %loop_cond, label %loop, label %exit748 749exit:750  ret i32 %iv751}752 753; turn to %iv >s smax(inv_1, inv_2) and hoist it out of loop.754define i32 @test_sgt_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {755; CHECK-LABEL: @test_sgt_swapped(756; CHECK-NEXT:  entry:757; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])758; CHECK-NEXT:    br label [[LOOP:%.*]]759; CHECK:       loop:760; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]761; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sgt i32 [[IV]], [[INVARIANT_SMAX]]762; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1763; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]764; CHECK:       exit:765; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]766; CHECK-NEXT:    ret i32 [[IV_LCSSA]]767;768entry:769  br label %loop770 771loop:772  %iv = phi i32 [%start, %entry], [%iv.next, %loop]773  %cmp_1 = icmp slt i32 %inv_1, %iv774  %cmp_2 = icmp slt i32 %inv_2, %iv775  %loop_cond = and i1 %cmp_1, %cmp_2776  %iv.next = add i32 %iv, 1777  br i1 %loop_cond, label %loop, label %exit778 779exit:780  ret i32 %iv781}782 783; turn to %iv >=s smax(inv_1, inv_2) and hoist it out of loop.784define i32 @test_sge_swapped(i32 %start, i32 %inv_1, i32 %inv_2) {785; CHECK-LABEL: @test_sge_swapped(786; CHECK-NEXT:  entry:787; CHECK-NEXT:    [[INVARIANT_SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])788; CHECK-NEXT:    br label [[LOOP:%.*]]789; CHECK:       loop:790; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]791; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp sge i32 [[IV]], [[INVARIANT_SMAX]]792; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1793; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]794; CHECK:       exit:795; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]796; CHECK-NEXT:    ret i32 [[IV_LCSSA]]797;798entry:799  br label %loop800 801loop:802  %iv = phi i32 [%start, %entry], [%iv.next, %loop]803  %cmp_1 = icmp sle i32 %inv_1, %iv804  %cmp_2 = icmp sle i32 %inv_2, %iv805  %loop_cond = and i1 %cmp_1, %cmp_2806  %iv.next = add i32 %iv, 1807  br i1 %loop_cond, label %loop, label %exit808 809exit:810  ret i32 %iv811}812 813; inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.814; Counter-example: %cmp_1 = false, %inv_2 = poison.815define i32 @test_logical_and_ult_needs_freeze(i32 %start, i32 %inv_1, i32 %inv_2) {816; CHECK-LABEL: @test_logical_and_ult_needs_freeze(817; CHECK-NEXT:  entry:818; CHECK-NEXT:    [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]819; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])820; CHECK-NEXT:    br label [[LOOP:%.*]]821; CHECK:       loop:822; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]823; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]824; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1825; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]826; CHECK:       exit:827; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]828; CHECK-NEXT:    ret i32 [[IV_LCSSA]]829;830entry:831  br label %loop832 833loop:834  %iv = phi i32 [%start, %entry], [%iv.next, %loop]835  %cmp_1 = icmp ult i32 %iv, %inv_1836  %cmp_2 = icmp ult i32 %iv, %inv_2837  %loop_cond = select i1 %cmp_1, i1 %cmp_2, i1 false838  %iv.next = add i32 %iv, 1839  br i1 %loop_cond, label %loop, label %exit840 841exit:842  ret i32 %iv843}844 845; turn to %iv <u umin(inv_1, inv_2) and hoist it out of loop.846; https://alive2.llvm.org/ce/z/mhKGtT847define i32 @test_logical_and_ult_pos(i32 %start, i32 %inv_1, i32 noundef %inv_2) {848; CHECK-LABEL: @test_logical_and_ult_pos(849; CHECK-NEXT:  entry:850; CHECK-NEXT:    [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]851; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])852; CHECK-NEXT:    br label [[LOOP:%.*]]853; CHECK:       loop:854; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]855; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]856; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1857; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]858; CHECK:       exit:859; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]860; CHECK-NEXT:    ret i32 [[IV_LCSSA]]861;862entry:863  br label %loop864 865loop:866  %iv = phi i32 [%start, %entry], [%iv.next, %loop]867  %cmp_1 = icmp ult i32 %iv, %inv_1868  %cmp_2 = icmp ult i32 %iv, %inv_2869  %loop_cond = select i1 %cmp_1, i1 %cmp_2, i1 false870  %iv.next = add i32 %iv, 1871  br i1 %loop_cond, label %loop, label %exit872 873exit:874  ret i32 %iv875}876 877; inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.878define i32 @test_logical_or_ult_inv_needs_freeze(i32 %start, i32 %inv_1, i32 %inv_2) {879; CHECK-LABEL: @test_logical_or_ult_inv_needs_freeze(880; CHECK-NEXT:  entry:881; CHECK-NEXT:    [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]882; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])883; CHECK-NEXT:    br label [[LOOP:%.*]]884; CHECK:       loop:885; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]886; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMAX]]887; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1888; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]889; CHECK:       exit:890; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]891; CHECK-NEXT:    ret i32 [[IV_LCSSA]]892;893entry:894  br label %loop895 896loop:897  %iv = phi i32 [%start, %entry], [%iv.next, %loop]898  %cmp_1 = icmp ult i32 %iv, %inv_1899  %cmp_2 = icmp ult i32 %iv, %inv_2900  %loop_cond = select i1 %cmp_1, i1 true, i1 %cmp_2901  %iv.next = add i32 %iv, 1902  br i1 %loop_cond, label %loop, label %exit903 904exit:905  ret i32 %iv906}907 908; turn to %iv <u umax(inv_1, inv_2) and hoist it out of loop.909; https://alive2.llvm.org/ce/z/zgyG5N910define i32 @test_logical_or_ult_inv_pos(i32 %start, i32 %inv_1, i32 noundef %inv_2) {911; CHECK-LABEL: @test_logical_or_ult_inv_pos(912; CHECK-NEXT:  entry:913; CHECK-NEXT:    [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]914; CHECK-NEXT:    [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])915; CHECK-NEXT:    br label [[LOOP:%.*]]916; CHECK:       loop:917; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]918; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMAX]]919; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1920; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]921; CHECK:       exit:922; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]923; CHECK-NEXT:    ret i32 [[IV_LCSSA]]924;925entry:926  br label %loop927 928loop:929  %iv = phi i32 [%start, %entry], [%iv.next, %loop]930  %cmp_1 = icmp ult i32 %iv, %inv_1931  %cmp_2 = icmp ult i32 %iv, %inv_2932  %loop_cond = select i1 %cmp_1, i1 true, i1 %cmp_2933  %iv.next = add i32 %iv, 1934  br i1 %loop_cond, label %loop, label %exit935 936exit:937  ret i32 %iv938}939 940; Mismatched predicates, do not optimize.941define i32 @test_mismatched_predicates_neg(i32 %start, i32 %inv_1, i32 %inv_2) {942; CHECK-LABEL: @test_mismatched_predicates_neg(943; CHECK-NEXT:  entry:944; CHECK-NEXT:    br label [[LOOP:%.*]]945; CHECK:       loop:946; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]947; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]948; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ule i32 [[IV]], [[INV_2:%.*]]949; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]950; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1951; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]952; CHECK:       exit:953; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]954; CHECK-NEXT:    ret i32 [[IV_LCSSA]]955;956entry:957  br label %loop958 959loop:960  %iv = phi i32 [%start, %entry], [%iv.next, %loop]961  %cmp_1 = icmp ult i32 %iv, %inv_1962  %cmp_2 = icmp ule i32 %iv, %inv_2963  %loop_cond = and i1 %cmp_1, %cmp_2964  %iv.next = add i32 %iv, 1965  br i1 %loop_cond, label %loop, label %exit966 967exit:968  ret i32 %iv969}970 971; TODO: Turn ule against constant into ult against constant, then do the same as in test_ult.972; https://alive2.llvm.org/ce/z/rucunQ973define i32 @test_mismatched_predicates_constant_pos_1(i32 %start, i32 %inv_1, i32 %inv_2) {974; CHECK-LABEL: @test_mismatched_predicates_constant_pos_1(975; CHECK-NEXT:  entry:976; CHECK-NEXT:    br label [[LOOP:%.*]]977; CHECK:       loop:978; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]979; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]980; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ule i32 [[IV]], 100981; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]982; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1983; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]984; CHECK:       exit:985; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]986; CHECK-NEXT:    ret i32 [[IV_LCSSA]]987;988entry:989  br label %loop990 991loop:992  %iv = phi i32 [%start, %entry], [%iv.next, %loop]993  %cmp_1 = icmp ult i32 %iv, %inv_1994  %cmp_2 = icmp ule i32 %iv, 100995  %loop_cond = and i1 %cmp_1, %cmp_2996  %iv.next = add i32 %iv, 1997  br i1 %loop_cond, label %loop, label %exit998 999exit:1000  ret i32 %iv1001}1002 1003; TODO: Turn ult against a constant into ule, then do the same as in test_ule.1004; https://alive2.llvm.org/ce/z/-ht-pU1005define i32 @test_mismatched_predicates_constant_pos_2(i32 %start, i32 %inv_1, i32 %inv_2) {1006; CHECK-LABEL: @test_mismatched_predicates_constant_pos_2(1007; CHECK-NEXT:  entry:1008; CHECK-NEXT:    br label [[LOOP:%.*]]1009; CHECK:       loop:1010; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1011; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], 1001012; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ule i32 [[IV]], [[INV_2:%.*]]1013; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1014; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11015; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1016; CHECK:       exit:1017; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1018; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1019;1020entry:1021  br label %loop1022 1023loop:1024  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1025  %cmp_1 = icmp ult i32 %iv, 1001026  %cmp_2 = icmp ule i32 %iv, %inv_21027  %loop_cond = and i1 %cmp_1, %cmp_21028  %iv.next = add i32 %iv, 11029  br i1 %loop_cond, label %loop, label %exit1030 1031exit:1032  ret i32 %iv1033}1034 1035; Do not optimize: `ule -1` cannot be turned into `ult 0` because of overflow.1036; However, this condition is trivially true anyways, so do not bother about it.1037define i32 @test_mismatched_predicates_constant_neg(i32 %start, i32 %inv_1, i32 %inv_2) {1038; CHECK-LABEL: @test_mismatched_predicates_constant_neg(1039; CHECK-NEXT:  entry:1040; CHECK-NEXT:    br label [[LOOP:%.*]]1041; CHECK:       loop:1042; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1043; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]1044; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ule i32 [[IV]], -11045; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1046; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11047; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1048; CHECK:       exit:1049; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1050; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1051;1052entry:1053  br label %loop1054 1055loop:1056  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1057  %cmp_1 = icmp ult i32 %iv, %inv_11058  %cmp_2 = icmp ule i32 %iv, -11059  %loop_cond = and i1 %cmp_1, %cmp_21060  %iv.next = add i32 %iv, 11061  br i1 %loop_cond, label %loop, label %exit1062 1063exit:1064  ret i32 %iv1065}1066 1067; Do not optimize: predicate eq.1068define i32 @test_eq_neg(i32 %start, i32 %inv_1, i32 %inv_2) {1069; CHECK-LABEL: @test_eq_neg(1070; CHECK-NEXT:  entry:1071; CHECK-NEXT:    br label [[LOOP:%.*]]1072; CHECK:       loop:1073; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1074; CHECK-NEXT:    [[CMP_1:%.*]] = icmp eq i32 [[IV]], [[INV_1:%.*]]1075; CHECK-NEXT:    [[CMP_2:%.*]] = icmp eq i32 [[IV]], [[INV_2:%.*]]1076; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1077; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11078; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1079; CHECK:       exit:1080; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1081; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1082;1083entry:1084  br label %loop1085 1086loop:1087  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1088  %cmp_1 = icmp eq i32 %iv, %inv_11089  %cmp_2 = icmp eq i32 %iv, %inv_21090  %loop_cond = and i1 %cmp_1, %cmp_21091  %iv.next = add i32 %iv, 11092  br i1 %loop_cond, label %loop, label %exit1093 1094exit:1095  ret i32 %iv1096}1097 1098; Do not optimize: predicate ne.1099define i32 @test_ne_neg(i32 %start, i32 %inv_1, i32 %inv_2) {1100; CHECK-LABEL: @test_ne_neg(1101; CHECK-NEXT:  entry:1102; CHECK-NEXT:    br label [[LOOP:%.*]]1103; CHECK:       loop:1104; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1105; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ne i32 [[IV]], [[INV_1:%.*]]1106; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ne i32 [[IV]], [[INV_2:%.*]]1107; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1108; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11109; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1110; CHECK:       exit:1111; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1112; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1113;1114entry:1115  br label %loop1116 1117loop:1118  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1119  %cmp_1 = icmp ne i32 %iv, %inv_11120  %cmp_2 = icmp ne i32 %iv, %inv_21121  %loop_cond = and i1 %cmp_1, %cmp_21122  %iv.next = add i32 %iv, 11123  br i1 %loop_cond, label %loop, label %exit1124 1125exit:1126  ret i32 %iv1127}1128 1129; Do not optimize: extra use.1130define i32 @test_ult_extra_use_1_neg(i32 %start, i32 %inv_1, i32 %inv_2) {1131; CHECK-LABEL: @test_ult_extra_use_1_neg(1132; CHECK-NEXT:  entry:1133; CHECK-NEXT:    br label [[LOOP:%.*]]1134; CHECK:       loop:1135; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1136; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]1137; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]1138; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1139; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11140; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1141; CHECK:       exit:1142; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1143; CHECK-NEXT:    [[CMP_1_LCSSA:%.*]] = phi i1 [ [[CMP_1]], [[LOOP]] ]1144; CHECK-NEXT:    call void @use(i1 [[CMP_1_LCSSA]])1145; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1146;1147entry:1148  br label %loop1149 1150loop:1151  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1152  %cmp_1 = icmp ult i32 %iv, %inv_11153  %cmp_2 = icmp ult i32 %iv, %inv_21154  %loop_cond = and i1 %cmp_1, %cmp_21155  %iv.next = add i32 %iv, 11156  br i1 %loop_cond, label %loop, label %exit1157 1158exit:1159  call void @use(i1 %cmp_1)1160  ret i32 %iv1161}1162 1163define i32 @test_ult_extra_use_2_neg(i32 %start, i32 %inv_1, i32 %inv_2) {1164; CHECK-LABEL: @test_ult_extra_use_2_neg(1165; CHECK-NEXT:  entry:1166; CHECK-NEXT:    br label [[LOOP:%.*]]1167; CHECK:       loop:1168; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1169; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]1170; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]1171; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1172; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11173; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1174; CHECK:       exit:1175; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1176; CHECK-NEXT:    [[CMP_2_LCSSA:%.*]] = phi i1 [ [[CMP_2]], [[LOOP]] ]1177; CHECK-NEXT:    call void @use(i1 [[CMP_2_LCSSA]])1178; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1179;1180entry:1181  br label %loop1182 1183loop:1184  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1185  %cmp_1 = icmp ult i32 %iv, %inv_11186  %cmp_2 = icmp ult i32 %iv, %inv_21187  %loop_cond = and i1 %cmp_1, %cmp_21188  %iv.next = add i32 %iv, 11189  br i1 %loop_cond, label %loop, label %exit1190 1191exit:1192  call void @use(i1 %cmp_2)1193  ret i32 %iv1194}1195 1196; This can be optimized, despite the fact that loop_cond has other uses.1197define i32 @test_ult_extra_use_result_pos(i32 %start, i32 %inv_1, i32 %inv_2) {1198; CHECK-LABEL: @test_ult_extra_use_result_pos(1199; CHECK-NEXT:  entry:1200; CHECK-NEXT:    [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2:%.*]])1201; CHECK-NEXT:    br label [[LOOP:%.*]]1202; CHECK:       loop:1203; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]1204; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]1205; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 11206; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1207; CHECK:       exit:1208; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP]] ]1209; CHECK-NEXT:    [[LOOP_COND_LCSSA:%.*]] = phi i1 [ [[LOOP_COND]], [[LOOP]] ]1210; CHECK-NEXT:    call void @use(i1 [[LOOP_COND_LCSSA]])1211; CHECK-NEXT:    ret i32 [[IV_LCSSA]]1212;1213entry:1214  br label %loop1215 1216loop:1217  %iv = phi i32 [%start, %entry], [%iv.next, %loop]1218  %cmp_1 = icmp ult i32 %iv, %inv_11219  %cmp_2 = icmp ult i32 %iv, %inv_21220  %loop_cond = and i1 %cmp_1, %cmp_21221  %iv.next = add i32 %iv, 11222  br i1 %loop_cond, label %loop, label %exit1223 1224exit:1225  call void @use(i1 %loop_cond)1226  ret i32 %iv1227}1228 1229; Do not optimize: comparison against different variant values.1230define i32 @test_ult_different_variants_neg(i32 %start_1, i32 %start_2, i32 %inv_1, i32 %inv_2) {1231; CHECK-LABEL: @test_ult_different_variants_neg(1232; CHECK-NEXT:  entry:1233; CHECK-NEXT:    br label [[LOOP:%.*]]1234; CHECK:       loop:1235; CHECK-NEXT:    [[IV_1:%.*]] = phi i32 [ [[START_1:%.*]], [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP]] ]1236; CHECK-NEXT:    [[IV_2:%.*]] = phi i32 [ [[START_2:%.*]], [[ENTRY]] ], [ [[IV_2_NEXT:%.*]], [[LOOP]] ]1237; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV_1]], [[INV_1:%.*]]1238; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i32 [[IV_2]], [[INV_2:%.*]]1239; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1240; CHECK-NEXT:    [[IV_1_NEXT]] = add i32 [[IV_1]], 11241; CHECK-NEXT:    [[IV_2_NEXT]] = add i32 [[IV_2]], 11242; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1243; CHECK:       exit:1244; CHECK-NEXT:    [[IV_1_LCSSA:%.*]] = phi i32 [ [[IV_1]], [[LOOP]] ]1245; CHECK-NEXT:    ret i32 [[IV_1_LCSSA]]1246;1247entry:1248  br label %loop1249 1250loop:1251  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %loop]1252  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %loop]1253  %cmp_1 = icmp ult i32 %iv_1, %inv_11254  %cmp_2 = icmp ult i32 %iv_2, %inv_21255  %loop_cond = and i1 %cmp_1, %cmp_21256  %iv_1.next = add i32 %iv_1, 11257  %iv_2.next = add i32 %iv_2, 11258  br i1 %loop_cond, label %loop, label %exit1259 1260exit:1261  ret i32 %iv_11262}1263 1264; Do not optimize: one of comparisons is against loop-variant.1265define i32 @test_ult_compare_against_variant_neg(i32 %start_1, i32 %start_2, i32 %inv_1, i32 %inv_2) {1266; CHECK-LABEL: @test_ult_compare_against_variant_neg(1267; CHECK-NEXT:  entry:1268; CHECK-NEXT:    br label [[LOOP:%.*]]1269; CHECK:       loop:1270; CHECK-NEXT:    [[IV_1:%.*]] = phi i32 [ [[START_1:%.*]], [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP]] ]1271; CHECK-NEXT:    [[IV_2:%.*]] = phi i32 [ [[START_2:%.*]], [[ENTRY]] ], [ [[IV_2_NEXT:%.*]], [[LOOP]] ]1272; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ult i32 [[IV_1]], [[INV_1:%.*]]1273; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i32 [[IV_1]], [[IV_2]]1274; CHECK-NEXT:    [[LOOP_COND:%.*]] = and i1 [[CMP_1]], [[CMP_2]]1275; CHECK-NEXT:    [[IV_1_NEXT]] = add i32 [[IV_1]], 11276; CHECK-NEXT:    [[IV_2_NEXT]] = add i32 [[IV_2]], 11277; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]1278; CHECK:       exit:1279; CHECK-NEXT:    [[IV_1_LCSSA:%.*]] = phi i32 [ [[IV_1]], [[LOOP]] ]1280; CHECK-NEXT:    ret i32 [[IV_1_LCSSA]]1281;1282entry:1283  br label %loop1284 1285loop:1286  %iv_1 = phi i32 [%start_1, %entry], [%iv_1.next, %loop]1287  %iv_2 = phi i32 [%start_2, %entry], [%iv_2.next, %loop]1288  %cmp_1 = icmp ult i32 %iv_1, %inv_11289  %cmp_2 = icmp ult i32 %iv_1, %iv_21290  %loop_cond = and i1 %cmp_1, %cmp_21291  %iv_1.next = add i32 %iv_1, 11292  %iv_2.next = add i32 %iv_2, 11293  br i1 %loop_cond, label %loop, label %exit1294 1295exit:1296  ret i32 %iv_11297}1298 1299declare void @use(i1)1300