brintos

brintos / llvm-project-archived public Read only

0
0
Text · 39.4 KiB · bf999b9 Raw
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