1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -loop-unroll -S %s | FileCheck %s
6 define void @peel_unreachable_exit_and_latch_exit(i32* %ptr, i32 %N, i32 %x) {
7 ; CHECK-LABEL: @peel_unreachable_exit_and_latch_exit(
9 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
11 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2
13 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
15 ; CHECK-NEXT: br label [[LOOP_LATCH]]
17 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]]
18 ; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]
20 ; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ]
21 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]]
22 ; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4
23 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
24 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
25 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
27 ; CHECK-NEXT: ret void
28 ; CHECK: unreachable.exit:
29 ; CHECK-NEXT: call void @foo()
30 ; CHECK-NEXT: unreachable
36 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
37 %c = icmp ult i32 %iv, 2
38 br i1 %c, label %then, label %else
44 %c.2 = icmp eq i32 %iv, %x
45 br i1 %c.2, label %unreachable.exit, label %loop.latch
48 %m = phi i32 [ 0, %then ], [ %x, %else ]
49 %gep = getelementptr i32, i32* %ptr, i32 %iv
50 store i32 %m, i32* %gep
51 %iv.next = add nuw nsw i32 %iv, 1
52 %c.3 = icmp ult i32 %iv, 1000
53 br i1 %c.3, label %loop.header, label %exit
63 define void @peel_unreachable_exit_and_header_exit(i32* %ptr, i32 %N, i32 %x) {
64 ; CHECK-LABEL: @peel_unreachable_exit_and_header_exit(
66 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
68 ; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[ELSE:%.*]]
70 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 1, [[X:%.*]]
71 ; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH:%.*]]
73 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
74 ; CHECK-NEXT: store i32 [[X]], i32* [[GEP]], align 4
75 ; CHECK-NEXT: unreachable
77 ; CHECK-NEXT: ret void
78 ; CHECK: unreachable.exit:
79 ; CHECK-NEXT: call void @foo()
80 ; CHECK-NEXT: unreachable
86 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
87 %c = icmp ult i32 %iv, 1000
88 br i1 %c, label %exit, label %else
91 %c.2 = icmp eq i32 %iv, %x
92 br i1 %c.2, label %unreachable.exit, label %loop.latch
95 %gep = getelementptr i32, i32* %ptr, i32 %iv
96 store i32 %x, i32* %gep
97 %iv.next = add nuw nsw i32 %iv, 1
108 define void @peel_unreachable_and_multiple_reachable_exits(i32* %ptr, i32 %N, i32 %x) {
109 ; CHECK-LABEL: @peel_unreachable_and_multiple_reachable_exits(
111 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
112 ; CHECK: loop.header:
113 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
114 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2
115 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
117 ; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[IV]], [[X:%.*]]
118 ; CHECK-NEXT: br i1 [[C_2]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
120 ; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[IV]], [[X]]
121 ; CHECK-NEXT: br i1 [[C_3]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]
123 ; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ]
124 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]]
125 ; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4
126 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
127 ; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[IV]], 1000
128 ; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_HEADER]], label [[EXIT]]
130 ; CHECK-NEXT: ret void
131 ; CHECK: unreachable.exit:
132 ; CHECK-NEXT: call void @foo()
133 ; CHECK-NEXT: unreachable
136 br label %loop.header
139 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
140 %c = icmp ult i32 %iv, 2
141 br i1 %c, label %then, label %else
144 %c.2 = icmp sgt i32 %iv, %x
145 br i1 %c.2, label %exit, label %loop.latch
148 %c.3 = icmp eq i32 %iv, %x
149 br i1 %c.3, label %unreachable.exit, label %loop.latch
152 %m = phi i32 [ 0, %then ], [ %x, %else ]
153 %gep = getelementptr i32, i32* %ptr, i32 %iv
154 store i32 %m, i32* %gep
155 %iv.next = add nuw nsw i32 %iv, 1
156 %c.4 = icmp ult i32 %iv, 1000
157 br i1 %c.4, label %loop.header, label %exit
167 define void @peel_exits_to_blocks_branch_to_unreachable_block(i32* %ptr, i32 %N, i32 %x, i1 %c.1) {
168 ; CHECK-LABEL: @peel_exits_to_blocks_branch_to_unreachable_block(
170 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
171 ; CHECK: loop.header:
172 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
173 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2
174 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
176 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]]
178 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]]
179 ; CHECK-NEXT: br i1 [[C_2]], label [[EXIT_2:%.*]], label [[LOOP_LATCH]]
181 ; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ]
182 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]]
183 ; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4
184 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
185 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
186 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
188 ; CHECK-NEXT: ret void
190 ; CHECK-NEXT: call void @foo()
191 ; CHECK-NEXT: br label [[UNREACHABLE_TERM:%.*]]
193 ; CHECK-NEXT: call void @bar()
194 ; CHECK-NEXT: br label [[UNREACHABLE_TERM]]
195 ; CHECK: unreachable.term:
196 ; CHECK-NEXT: call void @baz()
197 ; CHECK-NEXT: unreachable
200 br label %loop.header
203 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
204 %c = icmp ult i32 %iv, 2
205 br i1 %c, label %then, label %else
208 br i1 %c.1, label %exit.1, label %loop.latch
211 %c.2 = icmp eq i32 %iv, %x
212 br i1 %c.2, label %exit.2, label %loop.latch
215 %m = phi i32 [ 0, %then ], [ %x, %else ]
216 %gep = getelementptr i32, i32* %ptr, i32 %iv
217 store i32 %m, i32* %gep
218 %iv.next = add nuw nsw i32 %iv, 1
219 %c.3 = icmp ult i32 %iv, 1000
220 br i1 %c.3, label %loop.header, label %exit
227 br label %unreachable.term
231 br label %unreachable.term