187 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=irce < %s -S | FileCheck %s3; RUN: opt -passes='require<branch-prob>,irce' < %s -S | FileCheck %s4 5; REQUIRES: asserts6 7; IRCE creates the pre and post loop, and invokes the8; canonicalizing these loops to LCSSA and loop-simplfy structure. Make sure that the update to the loopinfo does not9; incorrectly change the header while canonicalizing these pre/post loops. We10; were incorrectly updating LI when the split loop is a subloop as in the case below.11source_filename = "correct-loop-info.ll"12 13define void @baz() personality ptr @ham {14; CHECK-LABEL: @baz(15; CHECK-NEXT: bb:16; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 undef, i32 -1)17; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 undef, i32 0)18; CHECK-NEXT: br label [[OUTERHEADER:%.*]]19; CHECK: outerheader:20; CHECK-NEXT: [[TMP:%.*]] = icmp slt i32 undef, 8421; CHECK-NEXT: br i1 [[TMP]], label [[BB2:%.*]], label [[BB16:%.*]]22; CHECK: bb2:23; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 undef, [[EXIT_PRELOOP_AT]]24; CHECK-NEXT: br i1 [[TMP0]], label [[INNERHEADER_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]25; CHECK: innerheader.preloop.preheader:26; CHECK-NEXT: br label [[INNERHEADER_PRELOOP:%.*]]27; CHECK: mainloop:28; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]29; CHECK-NEXT: br i1 [[TMP1]], label [[INNERHEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]30; CHECK: innerheader.preheader:31; CHECK-NEXT: br label [[INNERHEADER:%.*]]32; CHECK: innerheader:33; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP6:%.*]], [[BB8:%.*]] ], [ [[TMP4_PRELOOP_COPY:%.*]], [[INNERHEADER_PREHEADER]] ]34; CHECK-NEXT: invoke void @pluto()35; CHECK-NEXT: to label [[BB5:%.*]] unwind label [[OUTER_EXITING_LOOPEXIT_SPLIT_LP_LOOPEXIT_SPLIT_LP:%.*]]36; CHECK: bb5:37; CHECK-NEXT: [[TMP6]] = add nsw i32 [[TMP4]], 138; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 139; CHECK-NEXT: br i1 true, label [[BB8]], label [[EXIT3_LOOPEXIT5:%.*]]40; CHECK: bb8:41; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i32 [[TMP6]], 8442; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP6]], [[EXIT_MAINLOOP_AT]]43; CHECK-NEXT: br i1 [[TMP2]], label [[INNERHEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]44; CHECK: main.exit.selector:45; CHECK-NEXT: [[TMP6_LCSSA:%.*]] = phi i32 [ [[TMP6]], [[BB8]] ]46; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP6_LCSSA]], 8447; CHECK-NEXT: br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[BB13:%.*]]48; CHECK: main.pseudo.exit:49; CHECK-NEXT: [[TMP4_COPY:%.*]] = phi i32 [ [[TMP4_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]50; CHECK-NEXT: [[INDVAR_END1:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]51; CHECK-NEXT: br label [[POSTLOOP:%.*]]52; CHECK: outer_exiting.loopexit:53; CHECK-NEXT: [[LPAD_LOOPEXIT:%.*]] = landingpad { ptr, i32 }54; CHECK-NEXT: cleanup55; CHECK-NEXT: br label [[OUTER_EXITING:%.*]]56; CHECK: outer_exiting.loopexit.split-lp.loopexit:57; CHECK-NEXT: [[LPAD_LOOPEXIT2:%.*]] = landingpad { ptr, i32 }58; CHECK-NEXT: cleanup59; CHECK-NEXT: br label [[OUTER_EXITING_LOOPEXIT_SPLIT_LP:%.*]]60; CHECK: outer_exiting.loopexit.split-lp.loopexit.split-lp:61; CHECK-NEXT: [[LPAD_LOOPEXIT_SPLIT_LP3:%.*]] = landingpad { ptr, i32 }62; CHECK-NEXT: cleanup63; CHECK-NEXT: br label [[OUTER_EXITING_LOOPEXIT_SPLIT_LP]]64; CHECK: outer_exiting.loopexit.split-lp:65; CHECK-NEXT: br label [[OUTER_EXITING]]66; CHECK: outer_exiting:67; CHECK-NEXT: switch i32 undef, label [[EXIT2:%.*]] [68; CHECK-NEXT: i32 142, label [[BB14:%.*]]69; CHECK-NEXT: i32 448, label [[EXIT:%.*]]70; CHECK-NEXT: ]71; CHECK: exit3.loopexit:72; CHECK-NEXT: br label [[EXIT3:%.*]]73; CHECK: exit3.loopexit4:74; CHECK-NEXT: br label [[EXIT3]]75; CHECK: exit3.loopexit5:76; CHECK-NEXT: br label [[EXIT3]]77; CHECK: exit3:78; CHECK-NEXT: ret void79; CHECK: bb13.loopexit:80; CHECK-NEXT: br label [[BB13]]81; CHECK: bb13:82; CHECK-NEXT: unreachable83; CHECK: bb14:84; CHECK-NEXT: br label [[OUTERHEADER]]85; CHECK: exit:86; CHECK-NEXT: ret void87; CHECK: bb16:88; CHECK-NEXT: ret void89; CHECK: exit2:90; CHECK-NEXT: ret void91; CHECK: innerheader.preloop:92; CHECK-NEXT: [[TMP4_PRELOOP:%.*]] = phi i32 [ [[TMP6_PRELOOP:%.*]], [[BB8_PRELOOP:%.*]] ], [ undef, [[INNERHEADER_PRELOOP_PREHEADER]] ]93; CHECK-NEXT: invoke void @pluto()94; CHECK-NEXT: to label [[BB5_PRELOOP:%.*]] unwind label [[OUTER_EXITING_LOOPEXIT:%.*]]95; CHECK: bb5.preloop:96; CHECK-NEXT: [[TMP6_PRELOOP]] = add i32 [[TMP4_PRELOOP]], 197; CHECK-NEXT: [[TMP7_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 198; CHECK-NEXT: br i1 [[TMP7_PRELOOP]], label [[BB8_PRELOOP]], label [[EXIT3_LOOPEXIT:%.*]]99; CHECK: bb8.preloop:100; CHECK-NEXT: [[TMP9_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 84101; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], [[EXIT_PRELOOP_AT]]102; CHECK-NEXT: br i1 [[TMP4]], label [[INNERHEADER_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]]103; CHECK: preloop.exit.selector:104; CHECK-NEXT: [[TMP6_PRELOOP_LCSSA:%.*]] = phi i32 [ [[TMP6_PRELOOP]], [[BB8_PRELOOP]] ]105; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP6_PRELOOP_LCSSA]], 84106; CHECK-NEXT: br i1 [[TMP5]], label [[PRELOOP_PSEUDO_EXIT]], label [[BB13]]107; CHECK: preloop.pseudo.exit:108; CHECK-NEXT: [[TMP4_PRELOOP_COPY]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]109; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]110; CHECK-NEXT: br label [[MAINLOOP]]111; CHECK: postloop:112; CHECK-NEXT: br label [[INNERHEADER_POSTLOOP:%.*]]113; CHECK: innerheader.postloop:114; CHECK-NEXT: [[TMP4_POSTLOOP:%.*]] = phi i32 [ [[TMP6_POSTLOOP:%.*]], [[BB8_POSTLOOP:%.*]] ], [ [[TMP4_COPY]], [[POSTLOOP]] ]115; CHECK-NEXT: invoke void @pluto()116; CHECK-NEXT: to label [[BB5_POSTLOOP:%.*]] unwind label [[OUTER_EXITING_LOOPEXIT_SPLIT_LP_LOOPEXIT:%.*]]117; CHECK: bb5.postloop:118; CHECK-NEXT: [[TMP6_POSTLOOP]] = add i32 [[TMP4_POSTLOOP]], 1119; CHECK-NEXT: [[TMP7_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 1120; CHECK-NEXT: br i1 [[TMP7_POSTLOOP]], label [[BB8_POSTLOOP]], label [[EXIT3_LOOPEXIT4:%.*]]121; CHECK: bb8.postloop:122; CHECK-NEXT: [[TMP9_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 84123; CHECK-NEXT: br i1 [[TMP9_POSTLOOP]], label [[INNERHEADER_POSTLOOP]], label [[BB13_LOOPEXIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]], !loop_constrainer.loop.clone [[META5]]124;125bb:126 br label %outerheader127 128outerheader: ; preds = %bb14, %bb129 %tmp = icmp slt i32 undef, 84130 br i1 %tmp, label %bb2, label %bb16131 132bb2: ; preds = %outerheader133 br label %innerheader134 135innerheader: ; preds = %bb8, %bb2136 %tmp4 = phi i32 [ %tmp6, %bb8 ], [ undef, %bb2 ]137 invoke void @pluto()138 to label %bb5 unwind label %outer_exiting139 140bb5: ; preds = %innerheader141 %tmp6 = add i32 %tmp4, 1142 %tmp7 = icmp slt i32 %tmp6, 1143 br i1 %tmp7, label %bb8, label %exit3144 145bb8: ; preds = %bb5146 %tmp9 = icmp slt i32 %tmp6, 84147 br i1 %tmp9, label %innerheader, label %bb13148 149outer_exiting: ; preds = %innerheader150 %tmp11 = landingpad { ptr, i32 }151 cleanup152 switch i32 undef, label %exit2 [153 i32 142, label %bb14154 i32 448, label %exit155 ]156 157exit3: ; preds = %bb5158 ret void159 160bb13: ; preds = %bb8161 unreachable162 163bb14: ; preds = %outer_exiting164 br label %outerheader165 166exit: ; preds = %outer_exiting167 ret void168 169bb16: ; preds = %outerheader170 ret void171 172exit2: ; preds = %outer_exiting173 ret void174}175 176declare ptr @ham()177 178declare void @pluto()179 180!0 = distinct !{!0, !1, !2, !3, !4}181!1 = !{!"llvm.loop.unroll.disable"}182!2 = !{!"llvm.loop.vectorize.enable", i1 false}183!3 = !{!"llvm.loop.licm_versioning.disable"}184!4 = !{!"llvm.loop.distribute.enable", i1 false}185!5 = !{}186!6 = distinct !{!6, !1, !2, !3, !4}187