1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -passes=loop-simplify | FileCheck %s
4 ; This function should get a preheader inserted before bb3, that is jumped
9 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
11 ; CHECK-NEXT: br label [[BB3_PREHEADER:%.*]]
13 ; CHECK-NEXT: br label [[BB3_PREHEADER]]
14 ; CHECK: bb3.preheader:
15 ; CHECK-NEXT: br label [[BB3:%.*]]
17 ; CHECK-NEXT: br label [[BB3]]
20 br i1 true, label %bb1, label %bb2
32 ; Test a case where we have multiple exit blocks as successors of a single loop
33 ; block that need to be made dedicated exit blocks. We also have multiple
34 ; exiting edges to one of the exit blocks that all should be rewritten.
35 define void @test_multiple_exits_from_single_block(i8 %a, ptr %b.ptr) {
36 ; CHECK-LABEL: @test_multiple_exits_from_single_block(
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:%.*]]
42 ; CHECK: loop.preheader:
43 ; CHECK-NEXT: br label [[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]]
55 ; CHECK: loop.backedge:
56 ; CHECK-NEXT: br label [[LOOP]]
57 ; CHECK: exit.a.loopexit:
58 ; CHECK-NEXT: br label [[EXIT_A]]
60 ; CHECK-NEXT: ret void
61 ; CHECK: exit.b.loopexit:
62 ; CHECK-NEXT: br label [[EXIT_B]]
64 ; CHECK-NEXT: ret void
67 switch i8 %a, label %loop [
73 %b = load volatile i8, ptr %b.ptr
74 switch i8 %b, label %loop [
91 ; Check that we leave already dedicated exits alone when forming dedicated exit
93 define void @test_pre_existing_dedicated_exits(i1 %a, ptr %ptr) {
94 ; CHECK-LABEL: @test_pre_existing_dedicated_exits(
96 ; CHECK-NEXT: br i1 [[A:%.*]], label [[LOOP_PH:%.*]], label [[NON_DEDICATED_EXIT:%.*]]
98 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
100 ; CHECK-NEXT: [[C1:%.*]] = load volatile i1, ptr [[PTR:%.*]]
101 ; CHECK-NEXT: br i1 [[C1]], label [[LOOP_BODY1:%.*]], label [[DEDICATED_EXIT1:%.*]]
103 ; CHECK-NEXT: [[C2:%.*]] = load volatile i1, ptr [[PTR]]
104 ; CHECK-NEXT: br i1 [[C2]], label [[LOOP_BODY2:%.*]], label [[NON_DEDICATED_EXIT_LOOPEXIT:%.*]]
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 void
112 ; CHECK: dedicated_exit2:
113 ; CHECK-NEXT: ret void
114 ; CHECK: non_dedicated_exit.loopexit:
115 ; CHECK-NEXT: br label [[NON_DEDICATED_EXIT]]
116 ; CHECK: non_dedicated_exit:
117 ; CHECK-NEXT: ret void
120 br i1 %a, label %loop.ph, label %non_dedicated_exit
123 br label %loop.header
126 %c1 = load volatile i1, ptr %ptr
127 br i1 %c1, label %loop.body1, label %dedicated_exit1
130 %c2 = load volatile i1, ptr %ptr
131 br i1 %c2, label %loop.body2, label %non_dedicated_exit
134 %c3 = load volatile i1, ptr %ptr
135 br i1 %c3, label %loop.backedge, label %dedicated_exit2
138 br label %loop.header
142 ; Check that there isn't a split loop exit.
146 ; Check that there isn't a split loop exit.
152 ; Check that we form what dedicated exits we can even when some exits are
153 ; reached via indirectbr which precludes forming dedicated exits.
154 define 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(
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:%.*]]
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]
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]]
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]]
180 ; CHECK-NEXT: ret void
181 ; CHECK: exit.b.loopexit:
182 ; CHECK-NEXT: br label [[EXIT_B]]
184 ; CHECK-NEXT: ret void
186 ; CHECK-NEXT: ret void
189 switch i8 %a, label %loop.ph [
196 br label %loop.header
199 %addr1 = load volatile ptr, ptr %addr.ptr
200 indirectbr ptr %addr1, [label %loop.body1, label %exit.a]
203 %b = load volatile i8, ptr %ptr
204 switch i8 %b, label %loop.body2 [
211 %addr2 = load volatile ptr, ptr %addr.ptr
212 indirectbr ptr %addr2, [label %loop.backedge, label %exit.c]
215 br label %loop.header
219 ; Check that there isn't a split loop exit.
226 ; Check that there isn't a split loop exit.