brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.5 KiB · 4cd2e47 Raw
640 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -aa-pipeline=basic-aa -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s --check-prefixes=CHECK,MDEP3; RUN: opt -aa-pipeline=basic-aa -enable-load-pre -enable-pre -passes='gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA4 5declare void @side_effect()6declare i1 @side_effect_cond()7 8declare i32 @personality_function()9 10; TODO: We can PRE the load away from the hot path.11define i32 @test_load_on_cold_path(ptr %p) {12; CHECK-LABEL: @test_load_on_cold_path(13; CHECK-NEXT:  entry:14; CHECK-NEXT:    br label [[LOOP:%.*]]15; CHECK:       loop:16; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]17; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 418; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 019; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]20; CHECK:       hot_path:21; CHECK-NEXT:    br label [[BACKEDGE]]22; CHECK:       cold_path:23; CHECK-NEXT:    call void @side_effect()24; CHECK-NEXT:    br label [[BACKEDGE]]25; CHECK:       backedge:26; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]27; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100028; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]29; CHECK:       exit:30; CHECK-NEXT:    ret i32 [[X]]31;32entry:33  br label %loop34 35loop:36  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]37  %x = load i32, ptr %p38  %cond = icmp ne i32 %x, 039  br i1 %cond, label %hot_path, label %cold_path40 41hot_path:42  br label %backedge43 44cold_path:45  call void @side_effect()46  br label %backedge47 48backedge:49  %iv.next = add i32 %iv, %x50  %loop.cond = icmp ult i32 %iv.next, 100051  br i1 %loop.cond, label %loop, label %exit52 53exit:54  ret i32 %x55}56 57; PRE here is meaningless, so we should not do it.58define i32 @test_load_on_both_paths(ptr %p) {59; CHECK-LABEL: @test_load_on_both_paths(60; CHECK-NEXT:  entry:61; CHECK-NEXT:    br label [[LOOP:%.*]]62; CHECK:       loop:63; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]64; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 465; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 066; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]67; CHECK:       hot_path:68; CHECK-NEXT:    call void @side_effect()69; CHECK-NEXT:    br label [[BACKEDGE]]70; CHECK:       cold_path:71; CHECK-NEXT:    call void @side_effect()72; CHECK-NEXT:    br label [[BACKEDGE]]73; CHECK:       backedge:74; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]75; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100076; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]77; CHECK:       exit:78; CHECK-NEXT:    ret i32 [[X]]79;80entry:81  br label %loop82 83loop:84  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]85  %x = load i32, ptr %p86  %cond = icmp ne i32 %x, 087  br i1 %cond, label %hot_path, label %cold_path88 89hot_path:90  call void @side_effect()91  br label %backedge92 93cold_path:94  call void @side_effect()95  br label %backedge96 97backedge:98  %iv.next = add i32 %iv, %x99  %loop.cond = icmp ult i32 %iv.next, 1000100  br i1 %loop.cond, label %loop, label %exit101 102exit:103  ret i32 %x104}105 106 107; We could PRE here, but it doesn't seem very profitable.108define i32 @test_load_on_backedge(ptr %p) {109; CHECK-LABEL: @test_load_on_backedge(110; CHECK-NEXT:  entry:111; CHECK-NEXT:    br label [[LOOP:%.*]]112; CHECK:       loop:113; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]114; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4115; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0116; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]117; CHECK:       hot_path:118; CHECK-NEXT:    br label [[BACKEDGE]]119; CHECK:       cold_path:120; CHECK-NEXT:    br label [[BACKEDGE]]121; CHECK:       backedge:122; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]123; CHECK-NEXT:    call void @side_effect()124; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000125; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]126; CHECK:       exit:127; CHECK-NEXT:    ret i32 [[X]]128;129entry:130  br label %loop131 132loop:133  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]134  %x = load i32, ptr %p135  %cond = icmp ne i32 %x, 0136  br i1 %cond, label %hot_path, label %cold_path137 138hot_path:139  br label %backedge140 141cold_path:142  br label %backedge143 144backedge:145  %iv.next = add i32 %iv, %x146  call void @side_effect()147  %loop.cond = icmp ult i32 %iv.next, 1000148  br i1 %loop.cond, label %loop, label %exit149 150exit:151  ret i32 %x152}153 154; TODO: We can PRE via splitting of the critical edge in the cold path.155define i32 @test_load_on_exiting_cold_path_01(ptr %p) {156; CHECK-LABEL: @test_load_on_exiting_cold_path_01(157; CHECK-NEXT:  entry:158; CHECK-NEXT:    br label [[LOOP:%.*]]159; CHECK:       loop:160; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]161; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4162; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0163; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]164; CHECK:       hot_path:165; CHECK-NEXT:    br label [[BACKEDGE]]166; CHECK:       cold_path:167; CHECK-NEXT:    [[SIDE_COND:%.*]] = call i1 @side_effect_cond()168; CHECK-NEXT:    br i1 [[SIDE_COND]], label [[BACKEDGE]], label [[COLD_EXIT:%.*]]169; CHECK:       backedge:170; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]171; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000172; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]173; CHECK:       exit:174; CHECK-NEXT:    ret i32 [[X]]175; CHECK:       cold_exit:176; CHECK-NEXT:    ret i32 -1177;178entry:179  br label %loop180 181loop:182  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]183  %x = load i32, ptr %p184  %cond = icmp ne i32 %x, 0185  br i1 %cond, label %hot_path, label %cold_path186 187hot_path:188  br label %backedge189 190cold_path:191  %side_cond = call i1 @side_effect_cond()192  br i1 %side_cond, label %backedge, label %cold_exit193 194backedge:195  %iv.next = add i32 %iv, %x196  %loop.cond = icmp ult i32 %iv.next, 1000197  br i1 %loop.cond, label %loop, label %exit198 199exit:200  ret i32 %x201 202cold_exit:203  ret i32 -1204}205 206; TODO: We can PRE via splitting of the critical edge in the cold path.207define i32 @test_load_on_exiting_cold_path_02(ptr %p) gc "statepoint-example" personality ptr @personality_function {208; CHECK-LABEL: @test_load_on_exiting_cold_path_02(209; CHECK-NEXT:  entry:210; CHECK-NEXT:    br label [[LOOP:%.*]]211; CHECK:       loop:212; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]213; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4214; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0215; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]216; CHECK:       hot_path:217; CHECK-NEXT:    br label [[BACKEDGE]]218; CHECK:       cold_path:219; CHECK-NEXT:    invoke void @side_effect()220; CHECK-NEXT:            to label [[BACKEDGE]] unwind label [[COLD_EXIT:%.*]]221; CHECK:       backedge:222; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]223; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000224; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]225; CHECK:       exit:226; CHECK-NEXT:    ret i32 [[X]]227; CHECK:       cold_exit:228; CHECK-NEXT:    [[LANDING_PAD:%.*]] = landingpad token229; CHECK-NEXT:            cleanup230; CHECK-NEXT:    ret i32 -1231;232entry:233  br label %loop234 235loop:236  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]237  %x = load i32, ptr %p238  %cond = icmp ne i32 %x, 0239  br i1 %cond, label %hot_path, label %cold_path240 241hot_path:242  br label %backedge243 244cold_path:245  invoke void @side_effect() to label %backedge unwind label %cold_exit246 247backedge:248  %iv.next = add i32 %iv, %x249  %loop.cond = icmp ult i32 %iv.next, 1000250  br i1 %loop.cond, label %loop, label %exit251 252exit:253  ret i32 %x254 255cold_exit:256  %landing_pad = landingpad token257  cleanup258  ret i32 -1259}260 261; Make sure we do not insert load into both cold path & backedge.262define i32 @test_load_on_cold_path_and_backedge(ptr %p) {263; CHECK-LABEL: @test_load_on_cold_path_and_backedge(264; CHECK-NEXT:  entry:265; CHECK-NEXT:    br label [[LOOP:%.*]]266; CHECK:       loop:267; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]268; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4269; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0270; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]271; CHECK:       hot_path:272; CHECK-NEXT:    br label [[BACKEDGE]]273; CHECK:       cold_path:274; CHECK-NEXT:    call void @side_effect()275; CHECK-NEXT:    br label [[BACKEDGE]]276; CHECK:       backedge:277; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]278; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000279; CHECK-NEXT:    call void @side_effect()280; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]281; CHECK:       exit:282; CHECK-NEXT:    ret i32 [[X]]283;284entry:285  br label %loop286 287loop:288  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]289  %x = load i32, ptr %p290  %cond = icmp ne i32 %x, 0291  br i1 %cond, label %hot_path, label %cold_path292 293hot_path:294  br label %backedge295 296cold_path:297  call void @side_effect()298  br label %backedge299 300backedge:301  %iv.next = add i32 %iv, %x302  %loop.cond = icmp ult i32 %iv.next, 1000303  call void @side_effect()304  br i1 %loop.cond, label %loop, label %exit305 306exit:307  ret i32 %x308}309 310; TODO: We can PRE the load away from the hot path. Make sure we only insert 1 load.311define i32 @test_load_multi_block_cold_path(ptr %p) {312; CHECK-LABEL: @test_load_multi_block_cold_path(313; CHECK-NEXT:  entry:314; CHECK-NEXT:    br label [[LOOP:%.*]]315; CHECK:       loop:316; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]317; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4318; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0319; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH_1:%.*]]320; CHECK:       hot_path:321; CHECK-NEXT:    br label [[BACKEDGE]]322; CHECK:       cold_path.1:323; CHECK-NEXT:    call void @side_effect()324; CHECK-NEXT:    call void @side_effect()325; CHECK-NEXT:    call void @side_effect()326; CHECK-NEXT:    br label [[BACKEDGE]]327; CHECK:       backedge:328; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]329; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000330; CHECK-NEXT:    call void @side_effect()331; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]332; CHECK:       exit:333; CHECK-NEXT:    ret i32 [[X]]334;335entry:336  br label %loop337 338loop:339  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]340  %x = load i32, ptr %p341  %cond = icmp ne i32 %x, 0342  br i1 %cond, label %hot_path, label %cold_path.1343 344hot_path:345  br label %backedge346 347cold_path.1:348  call void @side_effect()349  br label %cold_path.2350 351cold_path.2:352  call void @side_effect()353  br label %cold_path.3354 355cold_path.3:356  call void @side_effect()357  br label %backedge358 359backedge:360  %iv.next = add i32 %iv, %x361  %loop.cond = icmp ult i32 %iv.next, 1000362  call void @side_effect()363  br i1 %loop.cond, label %loop, label %exit364 365exit:366  ret i32 %x367}368 369; TODO: We can PRE via splitting of the critical edge in the cold path. Make sure we only insert 1 load.370define i32 @test_load_on_multi_exiting_cold_path(ptr %p) {371; CHECK-LABEL: @test_load_on_multi_exiting_cold_path(372; CHECK-NEXT:  entry:373; CHECK-NEXT:    br label [[LOOP:%.*]]374; CHECK:       loop:375; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]376; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4377; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0378; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH_1:%.*]]379; CHECK:       hot_path:380; CHECK-NEXT:    br label [[BACKEDGE]]381; CHECK:       cold_path.1:382; CHECK-NEXT:    [[SIDE_COND_1:%.*]] = call i1 @side_effect_cond()383; CHECK-NEXT:    br i1 [[SIDE_COND_1]], label [[COLD_PATH_2:%.*]], label [[COLD_EXIT:%.*]]384; CHECK:       cold_path.2:385; CHECK-NEXT:    [[SIDE_COND_2:%.*]] = call i1 @side_effect_cond()386; CHECK-NEXT:    br i1 [[SIDE_COND_2]], label [[COLD_PATH_3:%.*]], label [[COLD_EXIT]]387; CHECK:       cold_path.3:388; CHECK-NEXT:    [[SIDE_COND_3:%.*]] = call i1 @side_effect_cond()389; CHECK-NEXT:    br i1 [[SIDE_COND_3]], label [[BACKEDGE]], label [[COLD_EXIT]]390; CHECK:       backedge:391; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]392; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000393; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]394; CHECK:       exit:395; CHECK-NEXT:    ret i32 [[X]]396; CHECK:       cold_exit:397; CHECK-NEXT:    ret i32 -1398;399entry:400  br label %loop401 402loop:403  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]404  %x = load i32, ptr %p405  %cond = icmp ne i32 %x, 0406  br i1 %cond, label %hot_path, label %cold_path.1407 408hot_path:409  br label %backedge410 411cold_path.1:412  %side_cond.1 = call i1 @side_effect_cond()413  br i1 %side_cond.1, label %cold_path.2, label %cold_exit414 415cold_path.2:416  %side_cond.2 = call i1 @side_effect_cond()417  br i1 %side_cond.2, label %cold_path.3, label %cold_exit418 419cold_path.3:420  %side_cond.3 = call i1 @side_effect_cond()421  br i1 %side_cond.3, label %backedge, label %cold_exit422 423backedge:424  %iv.next = add i32 %iv, %x425  %loop.cond = icmp ult i32 %iv.next, 1000426  br i1 %loop.cond, label %loop, label %exit427 428exit:429  ret i32 %x430 431cold_exit:432  ret i32 -1433}434 435; TODO: PRE via splittinga backedge in the cold loop. Make sure we don't insert a load into an inner loop.436define i32 @test_inner_loop(ptr %p, i1 %arg) {437; CHECK-LABEL: @test_inner_loop(438; CHECK-NEXT:  entry:439; CHECK-NEXT:    br label [[LOOP:%.*]]440; CHECK:       loop:441; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]442; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4443; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0444; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]445; CHECK:       hot_path:446; CHECK-NEXT:    br label [[BACKEDGE]]447; CHECK:       cold_path:448; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]449; CHECK:       inner_loop:450; CHECK-NEXT:    call void @side_effect()451; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[INNER_LOOP]], label [[BACKEDGE]]452; CHECK:       backedge:453; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]454; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000455; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]456; CHECK:       exit:457; CHECK-NEXT:    ret i32 [[X]]458;459entry:460  br label %loop461 462loop:463  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]464  %x = load i32, ptr %p465  %cond = icmp ne i32 %x, 0466  br i1 %cond, label %hot_path, label %cold_path467 468hot_path:469  br label %backedge470 471cold_path:472  br label %inner_loop473 474inner_loop:475  call void @side_effect()476  br i1 %arg, label %inner_loop, label %backedge477 478backedge:479  %iv.next = add i32 %iv, %x480  %loop.cond = icmp ult i32 %iv.next, 1000481  br i1 %loop.cond, label %loop, label %exit482 483exit:484  ret i32 %x485}486 487; TODO: We can PRE here, but profitablility depends on frequency of cold blocks. Conservatively, we should not do it unless there is a reason.488define i32 @test_multiple_cold_paths(ptr %p) {489; CHECK-LABEL: @test_multiple_cold_paths(490; CHECK-NEXT:  entry:491; CHECK-NEXT:    br label [[LOOP:%.*]]492; CHECK:       loop:493; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]494; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4495; CHECK-NEXT:    [[COND_1:%.*]] = icmp ne i32 [[X]], 0496; CHECK-NEXT:    br i1 [[COND_1]], label [[HOT_PATH_1:%.*]], label [[COLD_PATH_1:%.*]]497; CHECK:       hot_path.1:498; CHECK-NEXT:    br label [[DOM_1:%.*]]499; CHECK:       cold_path.1:500; CHECK-NEXT:    call void @side_effect()501; CHECK-NEXT:    br label [[DOM_1]]502; CHECK:       dom.1:503; CHECK-NEXT:    [[COND_2:%.*]] = icmp ne i32 [[X]], 1504; CHECK-NEXT:    br i1 [[COND_2]], label [[HOT_PATH_2:%.*]], label [[COLD_PATH_2:%.*]]505; CHECK:       hot_path.2:506; CHECK-NEXT:    br label [[DOM_2:%.*]]507; CHECK:       cold_path.2:508; CHECK-NEXT:    call void @side_effect()509; CHECK-NEXT:    br label [[DOM_2]]510; CHECK:       dom.2:511; CHECK-NEXT:    [[COND_3:%.*]] = icmp ne i32 [[X]], 2512; CHECK-NEXT:    br i1 [[COND_3]], label [[HOT_PATH_3:%.*]], label [[COLD_PATH_3:%.*]]513; CHECK:       hot_path.3:514; CHECK-NEXT:    br label [[BACKEDGE]]515; CHECK:       cold_path.3:516; CHECK-NEXT:    call void @side_effect()517; CHECK-NEXT:    br label [[BACKEDGE]]518; CHECK:       backedge:519; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]520; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000521; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]522; CHECK:       exit:523; CHECK-NEXT:    ret i32 [[X]]524;525entry:526  br label %loop527 528loop:529  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]530  %x = load i32, ptr %p531  %cond.1 = icmp ne i32 %x, 0532  br i1 %cond.1, label %hot_path.1, label %cold_path.1533 534hot_path.1:535  br label %dom.1536 537cold_path.1:538  call void @side_effect()539  br label %dom.1540 541dom.1:542  %cond.2 = icmp ne i32 %x, 1543  br i1 %cond.2, label %hot_path.2, label %cold_path.2544 545hot_path.2:546  br label %dom.2547 548cold_path.2:549  call void @side_effect()550  br label %dom.2551 552dom.2:553  %cond.3 = icmp ne i32 %x, 2554  br i1 %cond.3, label %hot_path.3, label %cold_path.3555 556hot_path.3:557  br label %backedge558 559cold_path.3:560  call void @side_effect()561  br label %backedge562 563backedge:564  %iv.next = add i32 %iv, %x565  %loop.cond = icmp ult i32 %iv.next, 1000566  br i1 %loop.cond, label %loop, label %exit567 568exit:569  ret i32 %x570}571 572; TODO: We can PRE via split of critical edge.573define i32 @test_side_exit_after_merge(ptr %p) {574; CHECK-LABEL: @test_side_exit_after_merge(575; CHECK-NEXT:  entry:576; CHECK-NEXT:    br label [[LOOP:%.*]]577; CHECK:       loop:578; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]579; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4580; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[X]], 0581; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]582; CHECK:       hot_path:583; CHECK-NEXT:    br label [[BACKEDGE]]584; CHECK:       cold_path:585; CHECK-NEXT:    [[COND_1:%.*]] = icmp ne i32 [[IV]], 1586; CHECK-NEXT:    br i1 [[COND_1]], label [[DO_CALL:%.*]], label [[SIDE_EXITING:%.*]]587; CHECK:       do_call:588; CHECK-NEXT:    [[SIDE_COND:%.*]] = call i1 @side_effect_cond()589; CHECK-NEXT:    br label [[SIDE_EXITING]]590; CHECK:       side_exiting:591; CHECK-NEXT:    [[SIDE_COND_PHI:%.*]] = phi i1 [ [[SIDE_COND]], [[DO_CALL]] ], [ true, [[COLD_PATH]] ]592; CHECK-NEXT:    br i1 [[SIDE_COND_PHI]], label [[BACKEDGE]], label [[COLD_EXIT:%.*]]593; CHECK:       backedge:594; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]595; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000596; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]597; CHECK:       exit:598; CHECK-NEXT:    ret i32 [[X]]599; CHECK:       cold_exit:600; CHECK-NEXT:    ret i32 -1601;602entry:603  br label %loop604 605loop:606  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]607  %x = load i32, ptr %p608  %cond = icmp ne i32 %x, 0609  br i1 %cond, label %hot_path, label %cold_path610 611hot_path:612  br label %backedge613 614cold_path:615  %cond.1 = icmp ne i32 %iv, 1616  br i1 %cond.1, label %do_call, label %side_exiting617 618do_call:619  %side_cond = call i1 @side_effect_cond()620  br label %side_exiting621 622side_exiting:623  %side_cond_phi = phi i1 [%side_cond, %do_call], [true, %cold_path]624  br i1 %side_cond_phi, label %backedge, label %cold_exit625 626backedge:627  %iv.next = add i32 %iv, %x628  %loop.cond = icmp ult i32 %iv.next, 1000629  br i1 %loop.cond, label %loop, label %exit630 631exit:632  ret i32 %x633 634cold_exit:635  ret i32 -1636}637;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:638; MDEP: {{.*}}639; MSSA: {{.*}}640