228 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -S -passes=loop-simplify | FileCheck %s3 4; This function should get a preheader inserted before bb3, that is jumped5; to by bb1 & bb26define void @test() {7; CHECK-LABEL: @test(8; CHECK-NEXT: entry:9; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]10; CHECK: bb1:11; CHECK-NEXT: br label [[BB3_PREHEADER:%.*]]12; CHECK: bb2:13; CHECK-NEXT: br label [[BB3_PREHEADER]]14; CHECK: bb3.preheader:15; CHECK-NEXT: br label [[BB3:%.*]]16; CHECK: bb3:17; CHECK-NEXT: br label [[BB3]]18;19entry:20 br i1 true, label %bb1, label %bb221 22bb1:23 br label %bb324 25bb2:26 br label %bb327 28bb3:29 br label %bb330}31 32; Test a case where we have multiple exit blocks as successors of a single loop33; block that need to be made dedicated exit blocks. We also have multiple34; exiting edges to one of the exit blocks that all should be rewritten.35define void @test_multiple_exits_from_single_block(i8 %a, ptr %b.ptr) {36; CHECK-LABEL: @test_multiple_exits_from_single_block(37; CHECK-NEXT: entry:38; CHECK-NEXT: switch i8 [[A:%.*]], label [[LOOP_PREHEADER:%.*]] [39; CHECK-NEXT: i8 0, label [[EXIT_A:%.*]]40; CHECK-NEXT: i8 1, label [[EXIT_B:%.*]]41; CHECK-NEXT: ]42; CHECK: loop.preheader:43; CHECK-NEXT: br label [[LOOP:%.*]]44; CHECK: loop:45; CHECK-NEXT: [[B:%.*]] = load volatile i8, ptr [[B_PTR:%.*]]46; CHECK-NEXT: switch i8 [[B]], label [[LOOP_BACKEDGE:%.*]] [47; CHECK-NEXT: i8 0, label [[EXIT_A_LOOPEXIT:%.*]]48; CHECK-NEXT: i8 1, label [[EXIT_B_LOOPEXIT:%.*]]49; CHECK-NEXT: i8 2, label [[LOOP_BACKEDGE]]50; CHECK-NEXT: i8 3, label [[EXIT_A_LOOPEXIT]]51; CHECK-NEXT: i8 4, label [[LOOP_BACKEDGE]]52; CHECK-NEXT: i8 5, label [[EXIT_A_LOOPEXIT]]53; CHECK-NEXT: i8 6, label [[LOOP_BACKEDGE]]54; CHECK-NEXT: ]55; CHECK: loop.backedge:56; CHECK-NEXT: br label [[LOOP]]57; CHECK: exit.a.loopexit:58; CHECK-NEXT: br label [[EXIT_A]]59; CHECK: exit.a:60; CHECK-NEXT: ret void61; CHECK: exit.b.loopexit:62; CHECK-NEXT: br label [[EXIT_B]]63; CHECK: exit.b:64; CHECK-NEXT: ret void65;66entry:67 switch i8 %a, label %loop [68 i8 0, label %exit.a69 i8 1, label %exit.b70 ]71 72loop:73 %b = load volatile i8, ptr %b.ptr74 switch i8 %b, label %loop [75 i8 0, label %exit.a76 i8 1, label %exit.b77 i8 2, label %loop78 i8 3, label %exit.a79 i8 4, label %loop80 i8 5, label %exit.a81 i8 6, label %loop82 ]83 84exit.a:85 ret void86 87exit.b:88 ret void89}90 91; Check that we leave already dedicated exits alone when forming dedicated exit92; blocks.93define void @test_pre_existing_dedicated_exits(i1 %a, ptr %ptr) {94; CHECK-LABEL: @test_pre_existing_dedicated_exits(95; CHECK-NEXT: entry:96; CHECK-NEXT: br i1 [[A:%.*]], label [[LOOP_PH:%.*]], label [[NON_DEDICATED_EXIT:%.*]]97; CHECK: loop.ph:98; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]99; CHECK: loop.header:100; CHECK-NEXT: [[C1:%.*]] = load volatile i1, ptr [[PTR:%.*]]101; CHECK-NEXT: br i1 [[C1]], label [[LOOP_BODY1:%.*]], label [[DEDICATED_EXIT1:%.*]]102; CHECK: loop.body1:103; CHECK-NEXT: [[C2:%.*]] = load volatile i1, ptr [[PTR]]104; CHECK-NEXT: br i1 [[C2]], label [[LOOP_BODY2:%.*]], label [[NON_DEDICATED_EXIT_LOOPEXIT:%.*]]105; CHECK: loop.body2:106; CHECK-NEXT: [[C3:%.*]] = load volatile i1, ptr [[PTR]]107; CHECK-NEXT: br i1 [[C3]], label [[LOOP_BACKEDGE:%.*]], label [[DEDICATED_EXIT2:%.*]]108; CHECK: loop.backedge:109; CHECK-NEXT: br label [[LOOP_HEADER]]110; CHECK: dedicated_exit1:111; CHECK-NEXT: ret void112; CHECK: dedicated_exit2:113; CHECK-NEXT: ret void114; CHECK: non_dedicated_exit.loopexit:115; CHECK-NEXT: br label [[NON_DEDICATED_EXIT]]116; CHECK: non_dedicated_exit:117; CHECK-NEXT: ret void118;119entry:120 br i1 %a, label %loop.ph, label %non_dedicated_exit121 122loop.ph:123 br label %loop.header124 125loop.header:126 %c1 = load volatile i1, ptr %ptr127 br i1 %c1, label %loop.body1, label %dedicated_exit1128 129loop.body1:130 %c2 = load volatile i1, ptr %ptr131 br i1 %c2, label %loop.body2, label %non_dedicated_exit132 133loop.body2:134 %c3 = load volatile i1, ptr %ptr135 br i1 %c3, label %loop.backedge, label %dedicated_exit2136 137loop.backedge:138 br label %loop.header139 140dedicated_exit1:141 ret void142; Check that there isn't a split loop exit.143 144dedicated_exit2:145 ret void146; Check that there isn't a split loop exit.147 148non_dedicated_exit:149 ret void150}151 152; Check that we form what dedicated exits we can even when some exits are153; reached via indirectbr which precludes forming dedicated exits.154define void @test_form_some_dedicated_exits_despite_indirectbr(i8 %a, ptr %ptr, ptr %addr.ptr) {155; CHECK-LABEL: @test_form_some_dedicated_exits_despite_indirectbr(156; CHECK-NEXT: entry:157; CHECK-NEXT: switch i8 [[A:%.*]], label [[LOOP_PH:%.*]] [158; CHECK-NEXT: i8 0, label [[EXIT_A:%.*]]159; CHECK-NEXT: i8 1, label [[EXIT_B:%.*]]160; CHECK-NEXT: i8 2, label [[EXIT_C:%.*]]161; CHECK-NEXT: ]162; CHECK: loop.ph:163; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]164; CHECK: loop.header:165; CHECK-NEXT: [[ADDR1:%.*]] = load volatile ptr, ptr [[ADDR_PTR:%.*]]166; CHECK-NEXT: indirectbr ptr [[ADDR1]], [label [[LOOP_BODY1:%.*]], label %exit.a]167; CHECK: loop.body1:168; CHECK-NEXT: [[B:%.*]] = load volatile i8, ptr [[PTR:%.*]]169; CHECK-NEXT: switch i8 [[B]], label [[LOOP_BODY2:%.*]] [170; CHECK-NEXT: i8 0, label [[EXIT_A]]171; CHECK-NEXT: i8 1, label [[EXIT_B_LOOPEXIT:%.*]]172; CHECK-NEXT: i8 2, label [[EXIT_C]]173; CHECK-NEXT: ]174; CHECK: loop.body2:175; CHECK-NEXT: [[ADDR2:%.*]] = load volatile ptr, ptr [[ADDR_PTR]]176; CHECK-NEXT: indirectbr ptr [[ADDR2]], [label [[LOOP_BACKEDGE:%.*]], label %exit.c]177; CHECK: loop.backedge:178; CHECK-NEXT: br label [[LOOP_HEADER]]179; CHECK: exit.a:180; CHECK-NEXT: ret void181; CHECK: exit.b.loopexit:182; CHECK-NEXT: br label [[EXIT_B]]183; CHECK: exit.b:184; CHECK-NEXT: ret void185; CHECK: exit.c:186; CHECK-NEXT: ret void187;188entry:189 switch i8 %a, label %loop.ph [190 i8 0, label %exit.a191 i8 1, label %exit.b192 i8 2, label %exit.c193 ]194 195loop.ph:196 br label %loop.header197 198loop.header:199 %addr1 = load volatile ptr, ptr %addr.ptr200 indirectbr ptr %addr1, [label %loop.body1, label %exit.a]201 202loop.body1:203 %b = load volatile i8, ptr %ptr204 switch i8 %b, label %loop.body2 [205 i8 0, label %exit.a206 i8 1, label %exit.b207 i8 2, label %exit.c208 ]209 210loop.body2:211 %addr2 = load volatile ptr, ptr %addr.ptr212 indirectbr ptr %addr2, [label %loop.backedge, label %exit.c]213 214loop.backedge:215 br label %loop.header216 217exit.a:218 ret void219; Check that there isn't a split loop exit.220 221exit.b:222 ret void223 224exit.c:225 ret void226; Check that there isn't a split loop exit.227}228