1542 lines · plain
1; RUN: opt -S -passes=licm < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED2; RUN: opt -S -passes=licm -licm-control-flow-hoisting=1 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED3; RUN: opt -S -passes=licm -licm-control-flow-hoisting=0 < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED4; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED5 6; RUN: opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=1 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-ENABLED7; Enable run below when adding promotion. e.g. "store i32 %phi, ptr %p" is promoted to phi.lcssa.8; opt -passes='require<opt-remark-emit>,loop-mssa(licm)' -licm-control-flow-hoisting=0 -verify-memoryssa -S < %s | FileCheck %s -check-prefixes=CHECK,CHECK-DISABLED9 10 11; CHECK-LABEL: @triangle_phi12define void @triangle_phi(i32 %x, ptr %p) {13; CHECK-LABEL: entry:14; CHECK: %cmp1 = icmp sgt i32 %x, 015; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]16entry:17 br label %loop18 19; CHECK-ENABLED: [[IF_LICM]]:20; CHECK: %add = add i32 %x, 121; CHECK-ENABLED: br label %[[THEN_LICM]]22 23; CHECK-ENABLED: [[THEN_LICM]]:24; CHECK-ENABLED: phi i32 [ %add, %[[IF_LICM]] ], [ %x, %entry ]25; CHECK-ENABLED: store i32 %phi, ptr %p26; CHECK-ENABLED: %cmp2 = icmp ne i32 %phi, 027; CHECK: br label %loop28 29loop:30 %cmp1 = icmp sgt i32 %x, 031 br i1 %cmp1, label %if, label %then32 33if:34 %add = add i32 %x, 135 br label %then36 37; CHECK-LABEL: then:38; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %x, %loop ]39; CHECK-DISABLED: %cmp2 = icmp ne i32 %phi, 040then:41 %phi = phi i32 [ %add, %if ], [ %x, %loop ]42 store i32 %phi, ptr %p43 %cmp2 = icmp ne i32 %phi, 044 br i1 %cmp2, label %loop, label %end45 46; CHECK-LABEL: end:47; CHECK-DISABLED: %[[PHI_LCSSA:.*]] = phi i32 [ %phi, %then ]48; CHECK-DISABLED: store i32 %[[PHI_LCSSA]], ptr %p49end:50 ret void51}52 53; CHECK-LABEL: @diamond_phi54define void @diamond_phi(i32 %x, ptr %p) {55; CHECK-LABEL: entry:56; CHECK: %cmp1 = icmp sgt i32 %x, 057; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]58entry:59 br label %loop60 61; CHECK-ENABLED: [[IF_LICM]]:62; CHECK-DAG: %add = add i32 %x, 163; CHECK-ENABLED: br label %[[THEN_LICM:.*]]64 65; CHECK-ENABLED: [[ELSE_LICM]]:66; CHECK-DAG: %sub = sub i32 %x, 167; CHECK-ENABLED: br label %[[THEN_LICM]]68 69; CHECK-ENABLED: [[THEN_LICM]]70; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]71; CHECK-ENABLED: store i32 %phi, ptr %p72; CHECK-ENABLED: %cmp2 = icmp ne i32 %phi, 073; CHECK: br label %loop74 75loop:76 %cmp1 = icmp sgt i32 %x, 077 br i1 %cmp1, label %if, label %else78 79if:80 %add = add i32 %x, 181 br label %then82 83else:84 %sub = sub i32 %x, 185 br label %then86 87; CHECK-LABEL: then:88; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]89; CHECK-DISABLED: %cmp2 = icmp ne i32 %phi, 090then:91 %phi = phi i32 [ %add, %if ], [ %sub, %else ]92 store i32 %phi, ptr %p93 %cmp2 = icmp ne i32 %phi, 094 br i1 %cmp2, label %loop, label %end95 96; CHECK-LABEL: end:97; CHECK-DISABLED: %[[PHI_LCSSA:.*]] = phi i32 [ %phi, %then ]98; CHECK-DISABLED: store i32 %[[PHI_LCSSA]], ptr %p99end:100 ret void101}102 103; TODO: This is currently too complicated for us to be able to hoist the phi.104; CHECK-LABEL: @three_way_phi105define void @three_way_phi(i32 %x, ptr %p) {106; CHECK-LABEL: entry:107; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0108; CHECK-DAG: %add = add i32 %x, 1109; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0110; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]111 112; CHECK-ENABLED: [[IF_LICM]]:113; CHECK-ENABLED: br label %[[THEN_LICM:.*]]114 115; CHECK-ENABLED: [[THEN_LICM]]:116; CHECK: %sub = sub i32 %x, 1117; CHECK: br label %loop118 119entry:120 br label %loop121 122loop:123 %cmp1 = icmp sgt i32 %x, 0124 br i1 %cmp1, label %if, label %then125 126if:127 %add = add i32 %x, 1128 %cmp2 = icmp sgt i32 %add, 0129 br i1 %cmp2, label %if.if, label %then130 131if.if:132 %sub = sub i32 %x, 1133 br label %then134 135then:136 %phi = phi i32 [ 0, %loop ], [ %add, %if ], [ %sub, %if.if ]137 store i32 %phi, ptr %p138 %cmp3 = icmp ne i32 %phi, 0139 br i1 %cmp3, label %loop, label %end140 141end:142 ret void143}144 145; TODO: This is currently too complicated for us to be able to hoist the phi.146; CHECK-LABEL: @tree_phi147define void @tree_phi(i32 %x, ptr %p) {148; CHECK-LABEL: entry:149; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0150; CHECK-DAG: %add = add i32 %x, 1151; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0152; CHECK-DAG: %sub = sub i32 %x, 1153; CHECK: br label %loop154 155entry:156 br label %loop157 158loop:159 %cmp1 = icmp sgt i32 %x, 0160 br i1 %cmp1, label %if, label %else161 162if:163 %add = add i32 %x, 1164 %cmp2 = icmp sgt i32 %add, 0165 br i1 %cmp2, label %if.if, label %if.else166 167if.if:168 br label %then169 170if.else:171 br label %then172 173else:174 %sub = sub i32 %x, 1175 br label %then176 177then:178 %phi = phi i32 [ %add, %if.if ], [ 0, %if.else ], [ %sub, %else ]179 store i32 %phi, ptr %p180 %cmp3 = icmp ne i32 %phi, 0181 br i1 %cmp3, label %loop, label %end182 183end:184 ret void185}186 187; TODO: We can hoist the first phi, but not the second.188; CHECK-LABEL: @phi_phi189define void @phi_phi(i32 %x, ptr %p) {190; CHECK-LABEL: entry:191; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0192; CHECK-DAG: %add = add i32 %x, 1193; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0194; CHECK-DAG: %sub = sub i32 %x, 1195; CHECK-ENABLED: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]196 197; CHECK-ENABLED: [[IF_IF_LICM]]:198; CHECK-ENABLED: br label %[[IF_THEN_LICM:.*]]199 200; CHECK-ENABLED: [[IF_ELSE_LICM]]:201; CHECK-ENABLED: br label %[[IF_THEN_LICM]]202 203; CHECK-ENABLED: [[IF_THEN_LICM]]:204; CHECK-ENABLED: %phi1 = phi i32 [ %add, %[[IF_IF_LICM]] ], [ 0, %[[IF_ELSE_LICM]] ]205; CHECK: br label %loop206 207entry:208 br label %loop209 210loop:211 %cmp1 = icmp sgt i32 %x, 0212 br i1 %cmp1, label %if, label %else213 214if:215 %add = add i32 %x, 1216 %cmp2 = icmp sgt i32 %add, 0217 br i1 %cmp2, label %if.if, label %if.else218 219if.if:220 br label %if.then221 222if.else:223 br label %if.then224 225; CHECK-LABEL: if.then:226; CHECK-DISABLED: %phi1 = phi i32 [ %add, %if.if ], [ 0, %if.else ]227if.then:228 %phi1 = phi i32 [ %add, %if.if ], [ 0, %if.else ]229 br label %then230 231else:232 %sub = sub i32 %x, 1233 br label %then234 235; CHECK-LABEL: then:236; CHECK: %phi2 = phi i32 [ %phi1, %if.then ], [ %sub, %else ]237then:238 %phi2 = phi i32 [ %phi1, %if.then ], [ %sub, %else ]239 store i32 %phi2, ptr %p240 %cmp3 = icmp ne i32 %phi2, 0241 br i1 %cmp3, label %loop, label %end242 243end:244 ret void245}246 247; Check that we correctly duplicate empty control flow.248; CHECK-LABEL: @empty_triangle_phi249define i8 @empty_triangle_phi(i32 %x, i32 %y) {250; CHECK-LABEL: entry:251; CHECK: %cmp1 = icmp eq i32 %x, 0252; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]253entry:254 br label %loop255 256; CHECK-ENABLED: [[IF_LICM]]:257; CHECK-ENABLED: br label %[[THEN_LICM]]258 259; CHECK-ENABLED: [[THEN_LICM]]:260; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]261; CHECK: %cmp2 = icmp eq i32 %y, 0262; CHECK: br label %loop263 264loop:265 %cmp1 = icmp eq i32 %x, 0266 br i1 %cmp1, label %if, label %then267 268if:269 br label %then270 271; CHECK-LABEL: then:272; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %loop ]273then:274 %phi = phi i8 [ 0, %if ], [ 1, %loop ]275 %cmp2 = icmp eq i32 %y, 0276 br i1 %cmp2, label %end, label %loop277 278end:279 ret i8 %phi280}281 282; CHECK-LABEL: @empty_diamond_phi283define i8 @empty_diamond_phi(i32 %x, i32 %y) {284; CHECK-LABEL: entry:285; CHECK: %cmp1 = icmp eq i32 %x, 0286; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]287entry:288 br label %loop289 290; CHECK-ENABLED: [[IF_LICM]]:291; CHECK-ENABLED: br label %[[THEN_LICM:.*]]292 293; CHECK-ENABLED: [[ELSE_LICM]]:294; CHECK-ENABLED: br label %[[THEN_LICM]]295 296; CHECK-ENABLED: [[THEN_LICM]]:297; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]298; CHECK: %cmp2 = icmp eq i32 %y, 0299; CHECK: br label %loop300 301loop:302 %cmp1 = icmp eq i32 %x, 0303 br i1 %cmp1, label %if, label %else304 305if:306 br label %then307 308else:309 br label %then310 311; CHECK-LABEL: then:312; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]313then:314 %phi = phi i8 [ 0, %if ], [ 1, %else ]315 %cmp2 = icmp eq i32 %y, 0316 br i1 %cmp2, label %end, label %loop317 318end:319 ret i8 %phi320}321 322; Check that we correctly handle the case that the first thing we try to hoist is a phi.323; CHECK-LABEL: @empty_triangle_phi_first324define i8 @empty_triangle_phi_first(i32 %x, i1 %cond) {325; CHECK-LABEL: entry:326; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]327entry:328 br label %loop329 330; CHECK-ENABLED: [[IF_LICM]]:331; CHECK-ENABLED: br label %[[THEN_LICM]]332 333; CHECK-ENABLED: [[THEN_LICM]]:334; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]335; CHECK: %cmp = icmp eq i32 %x, 0336; CHECK: br label %loop337 338loop:339 br i1 %cond, label %if, label %then340 341if:342 br label %then343 344; CHECK-LABEL: then:345; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %loop ]346then:347 %phi = phi i8 [ 0, %if ], [ 1, %loop ]348 %cmp = icmp eq i32 %x, 0349 br i1 %cmp, label %end, label %loop350 351end:352 ret i8 %phi353}354 355; CHECK-LABEL: @empty_diamond_phi356define i8 @empty_diamond_phi_first(i32 %x, i1 %cond) {357; CHECK-LABEL: entry:358; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]359entry:360 br label %loop361 362; CHECK-ENABLED: [[IF_LICM]]:363; CHECK-ENABLED: br label %[[THEN_LICM:.*]]364 365; CHECK-ENABLED: [[ELSE_LICM]]:366; CHECK-ENABLED: br label %[[THEN_LICM]]367 368; CHECK-ENABLED: [[THEN_LICM]]:369; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]370; CHECK: %cmp = icmp eq i32 %x, 0371; CHECK: br label %loop372 373loop:374 br i1 %cond, label %if, label %else375 376if:377 br label %then378 379else:380 br label %then381 382; CHECK-LABEL: then:383; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]384then:385 %phi = phi i8 [ 0, %if ], [ 1, %else ]386 %cmp = icmp eq i32 %x, 0387 br i1 %cmp, label %end, label %loop388 389end:390 ret i8 %phi391}392 393; CHECK-LABEL: @empty_triangle_phi_first394define i8 @empty_triangle_phi_first_empty_loop_head(i32 %x, i1 %cond) {395; CHECK-LABEL: entry:396; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]397entry:398 br label %loop399 400; CHECK-ENABLED: [[IF_LICM]]:401; CHECK-ENABLED: br label %[[THEN_LICM]]402 403; CHECK-ENABLED: [[THEN_LICM]]:404; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]405; CHECK: %cmp = icmp eq i32 %x, 0406; CHECK: br label %loop407 408loop:409 br label %test410 411test:412 br i1 %cond, label %if, label %then413 414if:415 br label %then416 417; CHECK-LABEL: then:418; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %test ]419then:420 %phi = phi i8 [ 0, %if ], [ 1, %test ]421 %cmp = icmp eq i32 %x, 0422 br i1 %cmp, label %end, label %loop423 424end:425 ret i8 %phi426}427 428; CHECK-LABEL: @empty_diamond_phi_first_empty_loop_head429define i8 @empty_diamond_phi_first_empty_loop_head(i32 %x, i1 %cond) {430; CHECK-LABEL: entry:431; CHECK-ENABLED: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]432entry:433 br label %loop434 435; CHECK-ENABLED: [[IF_LICM]]:436; CHECK-ENABLED: br label %[[THEN_LICM:.*]]437 438; CHECK-ENABLED: [[ELSE_LICM]]:439; CHECK-ENABLED: br label %[[THEN_LICM]]440 441; CHECK-ENABLED: [[THEN_LICM]]:442; CHECK-ENABLED: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]443; CHECK: %cmp = icmp eq i32 %x, 0444; CHECK: br label %loop445 446loop:447 br label %test448 449test:450 br i1 %cond, label %if, label %else451 452if:453 br label %then454 455else:456 br label %then457 458; CHECK-LABEL: then:459; CHECK-DISABLED: %phi = phi i8 [ 0, %if ], [ 1, %else ]460then:461 %phi = phi i8 [ 0, %if ], [ 1, %else ]462 %cmp = icmp eq i32 %x, 0463 br i1 %cmp, label %end, label %loop464 465end:466 ret i8 %phi467}468 469; The phi is on one branch of a diamond while simultaneously at the end of a470; triangle. Check that we duplicate the triangle and not the diamond.471; CHECK-LABEL: @triangle_diamond472define void @triangle_diamond(ptr %ptr, i32 %x, i32 %y) {473; CHECK-LABEL: entry:474; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0475; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0476; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]477entry:478 br label %loop479 480; CHECK-ENABLED: [[IF_LICM]]:481; CHECK-ENABLED: br label %[[THEN_LICM]]482 483; CHECK-ENABLED: [[THEN_LICM]]:484; CHECK-ENABLED: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]485; CHECK: br label %loop486 487loop:488 %cmp1 = icmp ne i32 %x, 0489 br i1 %cmp1, label %if, label %then490 491if:492 %cmp2 = icmp ne i32 %y, 0493 br i1 %cmp2, label %if.then, label %then494 495; CHECK-LABEL: then:496; CHECK-DISABLED: %phi = phi i32 [ 0, %if ], [ 127, %loop ]497then:498 %phi = phi i32 [ 0, %if ], [ 127, %loop ]499 store i32 %phi, ptr %ptr500 br label %end501 502if.then:503 br label %end504 505end:506 br label %loop507}508 509; As the previous, but the end of the diamond is the head of the loop.510; CHECK-LABEL: @triangle_diamond_backedge511define void @triangle_diamond_backedge(ptr %ptr, i32 %x, i32 %y) {512; CHECK-LABEL: entry:513; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0514; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0515; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]516entry:517 br label %loop518 519; CHECK-ENABLED: [[IF_LICM]]:520; CHECK-ENABLED: br label %[[THEN_LICM]]521 522; CHECK-ENABLED: [[THEN_LICM]]:523; CHECK-ENABLED: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]524; CHECK: br label %loop525 526loop:527 %cmp1 = icmp ne i32 %x, 0528 br i1 %cmp1, label %if, label %then529 530if:531 %cmp2 = icmp ne i32 %y, 0532 br i1 %cmp2, label %backedge, label %then533 534; CHECK-LABEL: then:535; CHECK-DISABLED: %phi = phi i32 [ 0, %if ], [ 127, %loop ]536then:537 %phi = phi i32 [ 0, %if ], [ 127, %loop ]538 store i32 %phi, ptr %ptr539 br label %loop540 541backedge:542 br label %loop543}544 545; TODO: The inner diamonds can be hoisted, but not currently the outer diamond546; CHECK-LABEL: @diamonds_inside_diamond547define void @diamonds_inside_diamond(i32 %x, ptr %p) {548; CHECK-LABEL: entry:549; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0550; CHECK-DAG: %cmp3 = icmp slt i32 %x, -10551; CHECK-ENABLED: br i1 %cmp3, label %[[ELSE_IF_LICM:.*]], label %[[ELSE_ELSE_LICM:.*]]552entry:553 br label %loop554 555; CHECK-ENABLED: [[ELSE_IF_LICM]]:556; CHECK-ENABLED: br label %[[ELSE_THEN_LICM:.*]]557 558; CHECK-ENABLED: [[ELSE_ELSE_LICM]]:559; CHECK-ENABLED: br label %[[ELSE_THEN_LICM]]560 561; CHECK-ENABLED: [[ELSE_THEN_LICM]]:562; CHECK-ENABLED: %phi2 = phi i32 [ 2, %[[ELSE_IF_LICM]] ], [ 3, %[[ELSE_ELSE_LICM]] ]563; CHECK: %cmp2 = icmp sgt i32 %x, 10564; CHECK-ENABLED: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]565 566; CHECK-ENABLED: [[IF_IF_LICM]]:567; CHECK-ENABLED: br label %[[IF_THEN_LICM:.*]]568 569; CHECK-ENABLED: [[IF_ELSE_LICM]]:570; CHECK-ENABLED: br label %[[IF_THEN_LICM]]571 572; CHECK-ENABLED: [[IF_THEN_LICM]]:573; CHECK-ENABLED: %phi1 = phi i32 [ 0, %[[IF_IF_LICM]] ], [ 1, %[[IF_ELSE_LICM]] ]574; CHECK: br label %loop575 576loop:577 %cmp1 = icmp sgt i32 %x, 0578 br i1 %cmp1, label %if, label %else579 580if:581 %cmp2 = icmp sgt i32 %x, 10582 br i1 %cmp2, label %if.if, label %if.else583 584if.if:585 br label %if.then586 587if.else:588 br label %if.then589 590; CHECK-LABEL: if.then:591; CHECK-DISABLED: %phi1 = phi i32 [ 0, %if.if ], [ 1, %if.else ]592if.then:593 %phi1 = phi i32 [ 0, %if.if ], [ 1, %if.else ]594 br label %then595 596else:597 %cmp3 = icmp slt i32 %x, -10598 br i1 %cmp3, label %else.if, label %else.else599 600else.if:601 br label %else.then602 603else.else:604 br label %else.then605 606; CHECK-LABEL: else.then:607; CHECK-DISABLED: %phi2 = phi i32 [ 2, %else.if ], [ 3, %else.else ]608else.then:609 %phi2 = phi i32 [ 2, %else.if ], [ 3, %else.else ]610 br label %then611 612; CHECK-LABEL: then:613; CHECK: %phi3 = phi i32 [ %phi1, %if.then ], [ %phi2, %else.then ]614; CHECK: %cmp4 = icmp ne i32 %phi3, 0615then:616 %phi3 = phi i32 [ %phi1, %if.then ], [ %phi2, %else.then ]617 store i32 %phi3, ptr %p618 %cmp4 = icmp ne i32 %phi3, 0619 br i1 %cmp4, label %loop, label %end620 621end:622 ret void623}624 625; We can hoist blocks that contain an edge that exits the loop by ignoring that626; edge in the hoisted block.627define void @triangle_phi_loopexit(i32 %x, ptr %p) {628; CHECK-DISABLED-LABEL: @triangle_phi_loopexit(629; CHECK-DISABLED-NEXT: entry:630; CHECK-DISABLED-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1631; CHECK-DISABLED-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], 0632; CHECK-DISABLED-NEXT: [[CMP2:%.*]] = icmp sgt i32 10, [[ADD]]633; CHECK-DISABLED-NEXT: br label [[LOOP:%.*]]634; CHECK-DISABLED: loop:635; CHECK-DISABLED-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[THEN:%.*]]636; CHECK-DISABLED: if:637; CHECK-DISABLED-NEXT: br i1 [[CMP2]], label [[THEN]], label [[END:%.*]]638; CHECK-DISABLED: then:639; CHECK-DISABLED-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD]], [[IF]] ], [ [[X]], [[LOOP]] ]640; CHECK-DISABLED-NEXT: store i32 [[PHI]], ptr [[P:%.*]], align 4641; CHECK-DISABLED-NEXT: [[CMP3:%.*]] = icmp ne i32 [[PHI]], 0642; CHECK-DISABLED-NEXT: br i1 [[CMP3]], label [[LOOP]], label [[END]]643; CHECK-DISABLED: end:644; CHECK-DISABLED-NEXT: ret void645;646; CHECK-ENABLED-LABEL: @triangle_phi_loopexit(647; CHECK-ENABLED-NEXT: entry:648; CHECK-ENABLED-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1649; CHECK-ENABLED-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], 0650; CHECK-ENABLED-NEXT: [[CMP2:%.*]] = icmp sgt i32 10, [[ADD]]651; CHECK-ENABLED-NEXT: br i1 [[CMP1]], label [[IF_LICM:%.*]], label [[THEN_LICM:%.*]]652; CHECK-ENABLED: if.licm:653; CHECK-ENABLED-NEXT: br label [[THEN_LICM]]654; CHECK-ENABLED: then.licm:655; CHECK-ENABLED-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD]], [[IF_LICM]] ], [ [[X]], [[ENTRY:%.*]] ]656; CHECK-ENABLED-NEXT: [[CMP3:%.*]] = icmp ne i32 [[PHI]], 0657; CHECK-ENABLED-NEXT: br label [[LOOP:%.*]]658; CHECK-ENABLED: loop:659; CHECK-ENABLED-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[THEN:%.*]]660; CHECK-ENABLED: if:661; CHECK-ENABLED-NEXT: br i1 [[CMP2]], label [[THEN]], label [[END:%.*]]662; CHECK-ENABLED: then:663; CHECK-ENABLED-NEXT: store i32 [[PHI]], ptr [[P:%.*]], align 4664; CHECK-ENABLED-NEXT: br i1 [[CMP3]], label [[LOOP]], label [[END]]665; CHECK-ENABLED: end:666; CHECK-ENABLED-NEXT: ret void667;668entry:669 br label %loop670 671loop:672 %cmp1 = icmp sgt i32 %x, 0673 br i1 %cmp1, label %if, label %then674 675if:676 %add = add i32 %x, 1677 %cmp2 = icmp sgt i32 10, %add678 br i1 %cmp2, label %then, label %end679 680then:681 %phi = phi i32 [ %add, %if ], [ %x, %loop ]682 store i32 %phi, ptr %p683 %cmp3 = icmp ne i32 %phi, 0684 br i1 %cmp3, label %loop, label %end685 686end:687 ret void688}689 690; CHECK-LABEL: @diamond_phi_oneloopexit691define void @diamond_phi_oneloopexit(i32 %x, ptr %p) {692; CHECK-LABEL: entry:693; CHECK-DAG: %add = add i32 %x, 1694; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0695; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add696; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]697entry:698 br label %loop699 700; CHECK-ENABLED: [[IF_LICM]]:701; CHECK-ENABLED: br label %[[THEN_LICM:.*]]702 703; CHECK-ENABLED: [[ELSE_LICM]]:704; CHECK-DAG: %sub = sub i32 %x, 1705; CHECK-ENABLED: br label %[[THEN_LICM]]706 707; CHECK-ENABLED: [[THEN_LICM]]708; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]709; CHECK-ENABLED: %cmp3 = icmp ne i32 %phi, 0710; CHECK: br label %loop711 712loop:713 %cmp1 = icmp sgt i32 %x, 0714 br i1 %cmp1, label %if, label %else715 716if:717 %add = add i32 %x, 1718 %cmp2 = icmp sgt i32 10, %add719 br i1 %cmp2, label %then, label %end720 721else:722 %sub = sub i32 %x, 1723 br label %then724 725; CHECK-LABEL: then:726; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]727then:728 %phi = phi i32 [ %add, %if ], [ %sub, %else ]729 store i32 %phi, ptr %p730 %cmp3 = icmp ne i32 %phi, 0731 br i1 %cmp3, label %loop, label %end732 733end:734 ret void735}736 737; CHECK-LABEL: @diamond_phi_twoloopexit738define void @diamond_phi_twoloopexit(i32 %x, ptr %p) {739; CHECK-LABEL: entry:740; CHECK-DAG: %sub = sub i32 %x, 1741; CHECK-DAG: %add = add i32 %x, 1742; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0743; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add744; CHECK-DAG: %cmp3 = icmp sgt i32 10, %sub745; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]746entry:747 br label %loop748 749; CHECK-ENABLED: [[IF_LICM]]:750; CHECK-ENABLED: br label %[[THEN_LICM:.*]]751 752; CHECK-ENABLED: [[ELSE_LICM]]:753; CHECK-ENABLED: br label %[[THEN_LICM]]754 755; CHECK-ENABLED: [[THEN_LICM]]756; CHECK-ENABLED: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]757; CHECK-ENABLED: %cmp4 = icmp ne i32 %phi, 0758; CHECK: br label %loop759 760loop:761 %cmp1 = icmp sgt i32 %x, 0762 br i1 %cmp1, label %if, label %else763 764if:765 %add = add i32 %x, 1766 %cmp2 = icmp sgt i32 10, %add767 br i1 %cmp2, label %then, label %end768 769else:770 %sub = sub i32 %x, 1771 %cmp3 = icmp sgt i32 10, %sub772 br i1 %cmp3, label %then, label %end773 774; CHECK-LABEL: then:775; CHECK-DISABLED: %phi = phi i32 [ %add, %if ], [ %sub, %else ]776; CHECK-DISABLED: %cmp4 = icmp ne i32 %phi, 0777then:778 %phi = phi i32 [ %add, %if ], [ %sub, %else ]779 store i32 %phi, ptr %p780 %cmp4 = icmp ne i32 %phi, 0781 br i1 %cmp4, label %loop, label %end782 783end:784 ret void785}786 787; The store cannot be hoisted, so add and shr cannot be hoisted into a788; conditional block.789; CHECK-LABEL: @conditional_use790define void @conditional_use(i32 %x, ptr %p) {791; CHECK-LABEL: entry:792; CHECK-DAG: %cond = icmp ugt i32 %x, 0793; CHECK-DAG: %add = add i32 %x, 5794; CHECK-DAG: %shr = ashr i32 %add, 1795; CHECK: br label %loop796entry:797 br label %loop798 799loop:800 %cond = icmp ugt i32 %x, 0801 br i1 %cond, label %if, label %else802 803; CHECK-LABEL: if:804; CHECK: store i32 %shr, ptr %p, align 4805if:806 %add = add i32 %x, 5807 %shr = ashr i32 %add, 1808 store i32 %shr, ptr %p, align 4809 br label %then810 811else:812 br label %then813 814then:815 br label %loop816}817 818; A diamond with two triangles on the left and one on the right. This test is819; to check that we have a unique loop preheader when we hoist the store (and so820; don't fail an assertion).821; CHECK-LABEL: @triangles_in_diamond822define void @triangles_in_diamond(ptr %ptr, i1 %arg) {823; CHECK-LABEL: entry:824; CHECK: store i32 0, ptr %ptr, align 4825; CHECK: br label %loop826entry:827 br label %loop828 829loop:830 br i1 %arg, label %left_triangle_1, label %right_triangle831 832left_triangle_1:833 br i1 %arg, label %left_triangle_1_if, label %left_triangle_2834 835left_triangle_1_if:836 br label %left_triangle_2837 838left_triangle_2:839 br i1 %arg, label %left_triangle_2_if, label %left_triangle_2_then840 841left_triangle_2_if:842 br label %left_triangle_2_then843 844left_triangle_2_then:845 br label %loop.end846 847right_triangle:848 br i1 %arg, label %right_triangle.if, label %right_triangle.then849 850right_triangle.if:851 br label %right_triangle.then852 853right_triangle.then:854 br label %loop.end855 856loop.end:857 store i32 0, ptr %ptr, align 4858 br label %loop859}860 861; %cmp dominates its used after being hoisted, but not after %brmerge is rehoisted862; CHECK-LABEL: @rehoist863define void @rehoist(ptr %this, i32 %x, i1 %arg) {864; CHECK-LABEL: entry:865; CHECK-DAG: %sub = add nsw i32 %x, -1866; CHECK-DAG: %cmp = icmp eq i32 0, %sub867; CHECK-DAG: %brmerge = or i1 %cmp, true868entry:869 %sub = add nsw i32 %x, -1870 br label %loop871 872loop:873 br i1 %arg, label %if1, label %else1874 875if1:876 call void %this(ptr %this)877 br label %then1878 879else1:880 br label %then1881 882then1:883 %cmp = icmp eq i32 0, %sub884 br i1 %cmp, label %end, label %else2885 886else2:887 %brmerge = or i1 %cmp, true888 br i1 %brmerge, label %if3, label %end889 890if3:891 br label %end892 893end:894 br label %loop895}896 897; A test case that uses empty blocks in a way that can cause control flow898; hoisting to get confused.899; CHECK-LABEL: @empty_blocks_multiple_conditional_branches900define void @empty_blocks_multiple_conditional_branches(float %arg, ptr %ptr, i1 %arg2) {901; CHECK-LABEL: entry902; CHECK-DAG: %div1 = fmul float %arg, 4.000000e+00903; CHECK-DAG: %div2 = fmul float %arg, 2.000000e+00904entry:905 br label %loop906 907; The exact path to the phi isn't checked here, because it depends on whether908; cond2 or cond3 is hoisted first909; CHECK-ENABLED: %phi = phi float [ 0.000000e+00, %{{.*}} ], [ %div1, %{{.*}} ]910; CHECK: br label %loop911 912loop:913 br i1 %arg2, label %backedge2, label %cond1914 915cond1:916 br i1 %arg2, label %cond1.if, label %cond1.else917 918cond1.else:919 br label %cond3920 921cond1.if:922 br label %cond1.if.next923 924cond1.if.next:925 br label %cond2926 927cond2:928 %div1 = fmul float %arg, 4.000000e+00929 br i1 %arg2, label %cond2.if, label %cond2.then930 931cond2.if:932 br label %cond2.then933 934; CHECK-LABEL: cond2.then:935; CHECK-DISABLED: %phi = phi float [ 0.000000e+00, %cond2 ], [ %div1, %cond2.if ]936cond2.then:937 %phi = phi float [ 0.000000e+00, %cond2 ], [ %div1, %cond2.if ]938 store float %phi, ptr %ptr939 br label %backedge2940 941cond3:942 br i1 %arg2, label %cond3.then, label %cond3.if943 944cond3.if:945 %div2 = fmul float %arg, 2.000000e+00946 store float %div2, ptr %ptr947 br label %cond3.then948 949cond3.then:950 br label %loop951 952backedge2:953 br label %loop954}955 956; We can't do much here, so mainly just check that we don't crash.957; CHECK-LABEL: @many_path_phi958define void @many_path_phi(ptr %ptr1, ptr %ptr2, i1 %arg) {959; CHECK-LABEL: entry:960; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %ptr2, i32 2961; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr2, i32 2962; CHECK: br label %loop963entry:964 br label %loop965 966loop:967 %phi1 = phi i32 [ 0, %entry ], [ %phi2, %end ]968 %cmp1 = icmp ugt i32 %phi1, 3969 br i1 %cmp1, label %cond2, label %cond1970 971cond1:972 br i1 %arg, label %end, label %cond1.else973 974cond1.else:975 %gep2 = getelementptr inbounds i32, ptr %ptr2, i32 2976 %val2 = load i32, ptr %gep2, align 4977 %cmp2 = icmp eq i32 %val2, 13978 br i1 %cmp2, label %cond1.end, label %end979 980cond1.end:981 br label %end982 983cond2:984 br i1 %arg, label %end, label %cond2.else985 986cond2.else:987 %gep3 = getelementptr inbounds i32, ptr %ptr2, i32 2988 %val3 = load i32, ptr %gep3, align 4989 %cmp3 = icmp eq i32 %val3, 13990 br i1 %cmp3, label %cond2.end, label %end991 992cond2.end:993 br label %end994 995end:996 %phi2 = phi i32 [ 1, %cond1 ], [ 2, %cond1.else ], [ 3, %cond1.end ], [ 4, %cond2 ], [ 5, %cond2.else ], [ 6, %cond2.end ]997 br label %loop998}999 1000; Check that we correctly handle the hoisting of %gep when theres a critical1001; edge that branches to the preheader.1002; CHECK-LABEL: @crit_edge1003define void @crit_edge(ptr %ptr, i32 %idx, i1 %cond1, i1 %cond2, i1 %arg) {1004; CHECK-LABEL: entry:1005; CHECK: %gep = getelementptr inbounds i32, ptr %ptr, i32 %idx1006; CHECK: br label %preheader1007entry:1008 br label %preheader1009 1010preheader:1011 br label %loop1012 1013loop:1014 br i1 %cond1, label %then, label %if1015 1016if:1017 %gep = getelementptr inbounds i32, ptr %ptr, i32 %idx1018 %val = load i32, ptr %gep1019 br label %then1020 1021then:1022 %phi = phi i32 [ %val, %if ], [ 0, %loop ]1023 store i32 %phi, ptr %ptr1024 br i1 %cond2, label %loop, label %crit_edge1025 1026crit_edge:1027 br label %preheader1028}1029 1030; Check that the conditional sub is correctly hoisted from the inner loop to the1031; preheader of the outer loop.1032; CHECK-LABEL: @hoist_from_innermost_loop1033define void @hoist_from_innermost_loop(i32 %nx, ptr %ptr, i1 %arg) {1034; CHECK-LABEL: entry:1035; CHECK-DAG: %sub = sub nsw i32 0, %nx1036; CHECK: br label %outer_loop1037entry:1038 br label %outer_loop1039 1040outer_loop:1041 br label %middle_loop1042 1043middle_loop:1044 br label %inner_loop1045 1046inner_loop:1047 br i1 %arg, label %inner_loop_end, label %if1048 1049if:1050 %sub = sub nsw i32 0, %nx1051 store i32 %sub, ptr %ptr, align 41052 br label %inner_loop_end1053 1054inner_loop_end:1055 br i1 %arg, label %inner_loop, label %middle_loop_end1056 1057middle_loop_end:1058 br i1 %arg, label %middle_loop, label %outer_loop_end1059 1060outer_loop_end:1061 br label %outer_loop1062}1063 1064; We have a diamond starting from %if, but %if.if is also reachable from %loop,1065; so %gep should not be conditionally hoisted.1066; CHECK-LABEL: @diamond_with_extra_in_edge1067define void @diamond_with_extra_in_edge(ptr %ptr1, ptr %ptr2, i32 %arg) {1068; CHECK-LABEL: entry:1069; CHECK-DAG: %cmp2 = icmp ne i32 0, %arg1070; CHECK-DAG: %gep = getelementptr i32, ptr %ptr1, i32 41071; CHECK: br label %loop1072entry:1073 br label %loop1074 1075loop:1076 %phi1 = phi i32 [ 0, %entry ], [ %phi2, %then ]1077 %cmp1 = icmp ugt i32 16, %phi11078 br i1 %cmp1, label %if, label %if.if1079 1080if:1081 %cmp2 = icmp ne i32 0, %arg1082 br i1 %cmp2, label %if.if, label %if.else1083 1084if.if:1085 %gep = getelementptr i32, ptr %ptr1, i32 41086 %val = load i32, ptr %gep, align 41087 br label %then1088 1089if.else:1090 br label %then1091 1092then:1093 %phi2 = phi i32 [ %val, %if.if ], [ %phi1, %if.else ]1094 store i32 %phi2, ptr %ptr2, align 41095 br label %loop1096}1097 1098; %loop/%if/%then form a triangle, but %loop/%if/%then/%end also form a diamond.1099; The triangle should be picked for conditional hoisting.1100; CHECK-LABEL: @both_triangle_and_diamond1101define void @both_triangle_and_diamond(ptr %ptr1, ptr %ptr2, i32 %arg) {1102; CHECK-LABEL: entry:1103; CHECK-DAG: %cmp1 = icmp ne i32 0, %arg1104; CHECK-DAG: %gep = getelementptr i32, ptr %ptr1, i32 41105; CHECK-ENABLED: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]1106entry:1107 br label %loop1108 1109; CHECK-ENABLED: [[IF_LICM]]:1110; CHECK-ENABLED: br label %[[THEN_LICM]]1111 1112; CHECK-ENABLED: [[THEN_LICM]]:1113; CHECK-ENABLED: %phi2 = phi i32 [ 0, %[[IF_LICM]] ], [ 1, %entry ]1114; CHECK: br label %loop1115 1116loop:1117 %phi1 = phi i32 [ 0, %entry ], [ %phi3, %end ]1118 %cmp1 = icmp ne i32 0, %arg1119 br i1 %cmp1, label %if, label %then1120 1121if:1122 %gep = getelementptr i32, ptr %ptr1, i32 41123 %val = load i32, ptr %gep, align 41124 %cmp2 = icmp ugt i32 16, %phi11125 br i1 %cmp2, label %end, label %then1126 1127; CHECK-LABEL: then:1128; CHECK-DISABLED: %phi2 = phi i32 [ 0, %if ], [ 1, %loop ]1129then:1130 %phi2 = phi i32 [ 0, %if ], [ 1, %loop ]1131 br label %end1132 1133end:1134 %phi3 = phi i32 [ %phi2, %then ], [ %val, %if ]1135 store i32 %phi3, ptr %ptr2, align 41136 br label %loop1137}1138 1139; We shouldn't duplicate the branch at the end of %loop and should instead hoist1140; %val to %entry.1141; CHECK-LABEL: @same_destination_branch1142define i32 @same_destination_branch(i32 %arg1, i32 %arg2) {1143; CHECK-LABEL: entry:1144; CHECK-DAG: %cmp1 = icmp ne i32 %arg2, 01145; CHECK-DAG: %val = add i32 %arg1, 11146; CHECK: br label %loop1147entry:1148 br label %loop1149 1150; CHECK-LABEL: loop:1151; CHECK: %phi = phi i32 [ 0, %entry ], [ %add, %then ]1152loop:1153 %phi = phi i32 [ 0, %entry ], [ %add, %then ]1154 %add = add i32 %phi, 11155 %cmp1 = icmp ne i32 %arg2, 01156 br i1 %cmp1, label %if, label %if1157 1158if:1159 %val = add i32 %arg1, 11160 br label %then1161 1162then:1163 %cmp2 = icmp ne i32 %val, %phi1164 br i1 %cmp2, label %loop, label %end1165 1166end:1167 ret i32 %val1168}1169 1170; Diamond-like control flow but the left/right blocks actually have the same1171; destinations.1172; TODO: We could potentially hoist all of phi2-4, but currently only hoist phi2.1173; CHECK-LABEL: @diamond_like_same_destinations1174define i32 @diamond_like_same_destinations(i32 %arg1, i32 %arg2) {1175; CHECK-LABEL: entry:1176; CHECK-DAG: %cmp1 = icmp ne i32 %arg1, 01177; CHECK-DAG: %cmp2 = icmp ugt i32 %arg2, 11178; CHECK-DAG: %cmp3 = icmp ugt i32 %arg2, 21179; CHECK-ENABLED: br i1 %cmp1, label %[[LEFT1_LICM:.*]], label %[[RIGHT1_LICM:.*]]1180entry:1181 br label %loop1182 1183; CHECK-ENABLED: [[LEFT1_LICM]]:1184; CHECK-ENABLED: br label %[[LEFT2_LICM:.*]]1185 1186; CHECK-ENABLED: [[RIGHT1_LICM]]:1187; CHECK-ENABLED: br label %[[LEFT2_LICM]]1188 1189; CHECK-ENABLED: [[LEFT2_LICM]]:1190; CHECK-ENABLED: %phi2 = phi i32 [ 0, %[[LEFT1_LICM]] ], [ 1, %[[RIGHT1_LICM]] ]1191; CHECK: br label %loop1192 1193loop:1194 %phi1 = phi i32 [ 0, %entry ], [ %add, %loopend ]1195 %add = add i32 %phi1, 11196 %cmp1 = icmp ne i32 %arg1, 01197 br i1 %cmp1, label %left1, label %right11198 1199left1:1200 %cmp2 = icmp ugt i32 %arg2, 11201 br i1 %cmp2, label %left2, label %right21202 1203right1:1204 %cmp3 = icmp ugt i32 %arg2, 21205 br i1 %cmp3, label %left2, label %right21206 1207; CHECK-LABEL: left2:1208; CHECK-DISABLED: %phi2 = phi i32 [ 0, %left1 ], [ 1, %right1 ]1209left2:1210 %phi2 = phi i32 [ 0, %left1 ], [ 1, %right1 ]1211 br label %loopend1212 1213; CHECK-LABEL: right2:1214; CHECK: %phi3 = phi i32 [ 2, %left1 ], [ 3, %right1 ]1215right2:1216 %phi3 = phi i32 [ 2, %left1 ], [ 3, %right1 ]1217 br label %loopend1218 1219; CHECK-LABEL: loopend:1220; CHECK: %phi4 = phi i32 [ %phi2, %left2 ], [ %phi3, %right2 ]1221loopend:1222 %phi4 = phi i32 [ %phi2, %left2 ], [ %phi3, %right2 ]1223 %cmp4 = icmp ne i32 %phi1, 321224 br i1 %cmp4, label %loop, label %end1225 1226end:1227 ret i32 %phi41228}1229 1230; A phi with multiple incoming values for the same block due to a branch with1231; two destinations that are actually the same. We can't hoist this.1232; TODO: This could be hoisted by erasing one of the incoming values.1233; CHECK-LABEL: @phi_multiple_values_same_block1234define i32 @phi_multiple_values_same_block(i32 %arg, i1 %arg2) {1235; CHECK-LABEL: entry:1236; CHECK: %cmp = icmp sgt i32 %arg, 41237; CHECK-NOT: phi1238; CHECK: br label %loop1239entry:1240 br label %loop1241 1242loop:1243 %cmp = icmp sgt i32 %arg, 41244 br i1 %cmp, label %if, label %then1245 1246if:1247 br i1 %arg2, label %then, label %then1248 1249then:1250 %phi = phi i32 [ %arg, %loop ], [ 1, %if ], [ 1, %if ]1251 br i1 %arg2, label %exit, label %loop1252 1253exit:1254 ret i32 %phi1255}1256 1257; %phi is conditionally used in %d, and the store that %d is used in cannot be1258; hoisted. This means that we have to rehoist %d, but have to make sure to1259; rehoist it after %phi.1260; CHECK-LABEL: @phi_conditional_use1261define i64 @phi_conditional_use(i32 %f, ptr %g) {1262; CHECK-LABEL: entry:1263; CHECK: %cmp1 = icmp eq i32 %f, 11264; CHECK: %cmp2 = icmp eq i32 %f, 01265; CHECK-ENABLED: br i1 %cmp1, label %[[IF_END_LICM:.*]], label %[[IF_THEN_LICM:.*]]1266entry:1267 %cmp1 = icmp eq i32 %f, 11268 %cmp2 = icmp eq i32 %f, 01269 br label %loop1270 1271; CHECK-ENABLED: [[IF_THEN_LICM]]:1272; CHECK-ENABLED: br label %[[IF_END_LICM]]1273 1274; CHECK-ENABLED: [[IF_END_LICM]]:1275; CHECK-ENABLED: %phi = phi i64 [ 0, %entry ], [ 1, %[[IF_THEN_LICM]] ]1276; CHECK-ENABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi1277; CHECK-ENABLED: i1 %cmp2, label %[[LOOP_BACKEDGE_LICM:.*]], label %[[IF_THEN2_LICM:.*]]1278 1279; CHECK-ENABLED: [[IF_THEN2_LICM]]:1280; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]1281 1282; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:1283; CHECK: br label %loop1284 1285loop:1286 br i1 %cmp1, label %if.end, label %if.then1287 1288if.then:1289 br label %if.end1290 1291; CHECK-LABEL: if.end:1292; CHECK-DISABLED: %phi = phi i64 [ 0, %loop ], [ 1, %if.then ]1293if.end:1294 %phi = phi i64 [ 0, %loop ], [ 1, %if.then ]1295 br i1 %cmp2, label %loop.backedge, label %if.then21296 1297; CHECK-LABEL: if.then2:1298; CHECK-DISABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi1299if.then2:1300 %d = getelementptr inbounds i32, ptr %g, i64 %phi1301 store i32 1, ptr %d, align 41302 br label %loop.backedge1303 1304loop.backedge:1305 br label %loop1306}1307 1308; As above, but we have two such phis1309; CHECK-LABEL: @phi_conditional_use_twice1310define i64 @phi_conditional_use_twice(i32 %f, ptr %g) {1311; CHECK-LABEL: entry:1312; CHECK: %cmp1 = icmp eq i32 %f, 11313; CHECK: %cmp2 = icmp eq i32 %f, 01314; CHECK-ENABLED: br i1 %cmp1, label %[[IF_END_LICM:.*]], label %[[IF_THEN_LICM:.*]]1315entry:1316 %cmp1 = icmp eq i32 %f, 11317 %cmp2 = icmp eq i32 %f, 01318 %cmp3 = icmp sgt i32 %f, 01319 br label %loop1320 1321; CHECK-ENABLED: [[IF_THEN_LICM]]:1322; CHECK-ENABLED: br label %[[IF_END_LICM]]1323 1324; CHECK-ENABLED: [[IF_END_LICM]]:1325; CHECK-ENABLED: %phi1 = phi i64 [ 0, %entry ], [ 1, %[[IF_THEN_LICM]] ]1326; CHECK-ENABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi11327; CHECK-ENABLED: i1 %cmp2, label %[[IF_END2_LICM:.*]], label %[[IF_THEN2_LICM:.*]]1328 1329; CHECK-ENABLED: [[IF_THEN2_LICM]]:1330; CHECK-ENABLED: br label %[[IF_END2_LICM]]1331 1332; CHECK-ENABLED: [[IF_END2_LICM]]:1333; CHECK-ENABLED: %phi2 = phi i64 [ 2, %[[IF_END_LICM]] ], [ 3, %[[IF_THEN2_LICM]] ]1334; CHECK-ENABLED: %e = getelementptr inbounds i32, ptr %g, i64 %phi21335; CHECK-ENABLED: i1 %cmp3, label %[[LOOP_BACKEDGE_LICM:.*]], label %[[IF_THEN3_LICM:.*]]1336 1337; CHECK-ENABLED: [[IF_THEN3_LICM]]:1338; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]1339 1340; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:1341; CHECK: br label %loop1342 1343loop:1344 br i1 %cmp1, label %if.end, label %if.then1345 1346if.then:1347 br label %if.end1348 1349; CHECK-LABEL: if.end:1350; CHECK-DISABLED: %phi1 = phi i64 [ 0, %loop ], [ 1, %if.then ]1351if.end:1352 %phi1 = phi i64 [ 0, %loop ], [ 1, %if.then ]1353 br i1 %cmp2, label %if.end2, label %if.then21354 1355; CHECK-LABEL: if.then2:1356; CHECK-DISABLED: %d = getelementptr inbounds i32, ptr %g, i64 %phi11357if.then2:1358 %d = getelementptr inbounds i32, ptr %g, i64 %phi11359 store i32 1, ptr %d, align 41360 br label %if.end21361 1362; CHECK-LABEL: if.end2:1363; CHECK-DISABLED: %phi2 = phi i64 [ 2, %if.end ], [ 3, %if.then2 ]1364if.end2:1365 %phi2 = phi i64 [ 2, %if.end ], [ 3, %if.then2 ]1366 br i1 %cmp3, label %loop.backedge, label %if.then31367 1368; CHECK-LABEL: if.then3:1369; CHECK-DISABLED: %e = getelementptr inbounds i32, ptr %g, i64 %phi21370if.then3:1371 %e = getelementptr inbounds i32, ptr %g, i64 %phi21372 store i32 1, ptr %e, align 41373 br label %loop.backedge1374 1375loop.backedge:1376 br label %loop1377}1378 1379; The order that we hoist instructions from the loop is different to the textual1380; order in the function. Check that we can rehoist this correctly.1381; CHECK-LABEL: @rehoist_wrong_order_11382define void @rehoist_wrong_order_1(ptr %ptr, i1 %arg) {1383; CHECK-LABEL: entry1384; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21385; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %ptr, i64 31386; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11387; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]1388entry:1389 br label %loop1390 1391; CHECK-ENABLED: [[IF1_LICM]]:1392; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]1393 1394; CHECK-ENABLED: [[ELSE1_LICM]]:1395; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]1396 1397; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:1398; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]1399 1400; CHECK-ENABLED: [[IF3_LICM]]:1401; CHECK-ENABLED: br label %[[END_LICM]]1402 1403; CHECK-ENABLED: [[END_LICM]]:1404; CHECK: br label %loop1405 1406loop:1407 br i1 %arg, label %if1, label %else11408 1409if1:1410 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11411 store i32 0, ptr %gep1, align 41412 br label %loop.backedge1413 1414else1:1415 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21416 store i32 0, ptr %gep2, align 41417 br i1 %arg, label %if2, label %loop.backedge1418 1419if2:1420 br i1 %arg, label %if3, label %end1421 1422if3:1423 %gep3 = getelementptr inbounds i32, ptr %ptr, i64 31424 store i32 0, ptr %gep3, align 41425 br label %end1426 1427end:1428 br label %loop.backedge1429 1430loop.backedge:1431 br label %loop1432 1433}1434 1435; CHECK-LABEL: @rehoist_wrong_order_21436define void @rehoist_wrong_order_2(ptr %ptr, i1 %arg) {1437; CHECK-LABEL: entry1438; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21439; CHECK-DAG: %gep3 = getelementptr inbounds i32, ptr %gep2, i64 31440; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11441; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]1442entry:1443 br label %loop1444 1445; CHECK-ENABLED: [[IF1_LICM]]:1446; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]1447 1448; CHECK-ENABLED: [[ELSE1_LICM]]:1449; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]1450 1451; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:1452; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]1453 1454; CHECK-ENABLED: [[IF3_LICM]]:1455; CHECK-ENABLED: br label %[[END_LICM]]1456 1457; CHECK-ENABLED: [[END_LICM]]:1458; CHECK: br label %loop1459 1460loop:1461 br i1 %arg, label %if1, label %else11462 1463if1:1464 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11465 store i32 0, ptr %gep1, align 41466 br label %loop.backedge1467 1468else1:1469 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21470 store i32 0, ptr %gep2, align 41471 br i1 %arg, label %if2, label %loop.backedge1472 1473if2:1474 br i1 %arg, label %if3, label %end1475 1476if3:1477 %gep3 = getelementptr inbounds i32, ptr %gep2, i64 31478 store i32 0, ptr %gep3, align 41479 br label %end1480 1481end:1482 br label %loop.backedge1483 1484loop.backedge:1485 br label %loop1486}1487 1488; CHECK-LABEL: @rehoist_wrong_order_31489define void @rehoist_wrong_order_3(ptr %ptr, i1 %arg) {1490; CHECK-LABEL: entry1491; CHECK-DAG: %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21492; CHECK-DAG: %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11493; CHECK-ENABLED: br i1 %arg, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]1494entry:1495 br label %loop1496 1497; CHECK-ENABLED: [[IF1_LICM]]:1498; CHECK-ENABLED: br label %[[IF2_LICM:.*]]1499 1500; CHECK-ENABLED: [[ELSE1_LICM]]:1501; CHECK-ENABLED: br label %[[IF2_LICM]]1502 1503; CHECK-ENABLED: [[IF2_LICM]]:1504; CHECK-ENABLED: %phi = phi ptr [ %gep1, %[[IF1_LICM]] ], [ %gep2, %[[ELSE1_LICM]] ]1505; CHECK-ENABLED: %gep3 = getelementptr inbounds i32, ptr %phi, i64 31506; CHECK-ENABLED: br i1 %arg, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]1507 1508; CHECK-ENABLED: [[IF3_LICM]]:1509; CHECK-ENABLED: br label %[[END_LICM]]1510 1511; CHECK-ENABLED: [[END_LICM]]:1512; CHECK: br label %loop1513 1514loop:1515 br i1 %arg, label %if1, label %else11516 1517if1:1518 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 11519 store i32 0, ptr %gep1, align 41520 br label %if21521 1522else1:1523 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 21524 store i32 0, ptr %gep2, align 41525 br i1 %arg, label %if2, label %loop.backedge1526 1527if2:1528 %phi = phi ptr [ %gep1, %if1 ], [ %gep2, %else1 ]1529 br i1 %arg, label %if3, label %end1530 1531if3:1532 %gep3 = getelementptr inbounds i32, ptr %phi, i64 31533 store i32 0, ptr %gep3, align 41534 br label %end1535 1536end:1537 br label %loop.backedge1538 1539loop.backedge:1540 br label %loop1541}1542