|
1 | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
2 |
| -; RUN: opt -p loop-unroll -S %s | FileCheck %s |
| 2 | +; RUN: opt -p loop-unroll -unroll-full-max-count=0 -S %s | FileCheck %s |
3 | 3 |
|
4 | 4 | define i64 @peel_single_block_loop_iv_step_1() {
|
5 | 5 | ; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1() {
|
@@ -68,16 +68,14 @@ exit:
|
68 | 68 | ret i64 %iv
|
69 | 69 | }
|
70 | 70 |
|
71 |
| - |
72 |
| - |
73 | 71 | define i64 @peel_single_block_loop_iv_step_1_eq_pred() {
|
74 | 72 | ; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_eq_pred() {
|
75 | 73 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
76 | 74 | ; CHECK-NEXT: br label %[[LOOP:.*]]
|
77 | 75 | ; CHECK: [[LOOP]]:
|
78 | 76 | ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
79 |
| -; CHECK-NEXT: [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 63 |
80 |
| -; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20 |
| 77 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 63 |
| 78 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
81 | 79 | ; CHECK-NEXT: call void @foo(i32 [[COND]])
|
82 | 80 | ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
|
83 | 81 | ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 64
|
@@ -136,22 +134,28 @@ exit:
|
136 | 134 |
|
137 | 135 | define i64 @peel_single_block_loop_iv_step_1_nested_loop() {
|
138 | 136 | ; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_nested_loop() {
|
139 |
| -; CHECK-NEXT: [[ENTRY:.*:]] |
| 137 | +; CHECK-NEXT: [[ENTRY:.*]]: |
140 | 138 | ; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
|
141 | 139 | ; CHECK: [[OUTER_HEADER]]:
|
| 140 | +; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[OUTER_LATCH:.*]] ] |
142 | 141 | ; CHECK-NEXT: br label %[[LOOP:.*]]
|
143 | 142 | ; CHECK: [[LOOP]]:
|
144 |
| -; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP]] ] |
145 |
| -; CHECK-NEXT: [[CMP18_NOT_PEEL:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 63 |
146 |
| -; CHECK-NEXT: [[COND_PEEL:%.*]] = select i1 [[CMP18_NOT_PEEL]], i32 10, i32 20 |
147 |
| -; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]]) |
148 |
| -; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i64 [[IV_NEXT_LCSSA]], 1 |
149 |
| -; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp ne i64 [[IV_NEXT_PEEL]], 64 |
150 |
| -; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[LOOP]], label %[[OUTER_LATCH:.*]] |
| 143 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] |
| 144 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 63 |
| 145 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
| 146 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
| 147 | +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 |
| 148 | +; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 64 |
| 149 | +; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH]] |
151 | 150 | ; CHECK: [[OUTER_LATCH]]:
|
152 |
| -; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_LCSSA]], %[[LOOP]] ] |
| 151 | +; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ] |
153 | 152 | ; CHECK-NEXT: call void @foo(i32 1)
|
154 |
| -; CHECK-NEXT: ret i64 [[IV_LCSSA]] |
| 153 | +; CHECK-NEXT: [[OUTER_IV_NEXT]] = add i64 [[OUTER_IV]], 1 |
| 154 | +; CHECK-NEXT: [[OUTER_EC:%.*]] = icmp ne i64 [[OUTER_IV_NEXT]], 100 |
| 155 | +; CHECK-NEXT: br i1 [[OUTER_EC]], label %[[EXIT:.*]], label %[[OUTER_HEADER]] |
| 156 | +; CHECK: [[EXIT]]: |
| 157 | +; CHECK-NEXT: [[IV_LCSSA_LCSSA:%.*]] = phi i64 [ [[IV_LCSSA]], %[[OUTER_LATCH]] ] |
| 158 | +; CHECK-NEXT: ret i64 [[IV_LCSSA_LCSSA]] |
155 | 159 | ;
|
156 | 160 | entry:
|
157 | 161 | br label %outer.header
|
@@ -184,21 +188,21 @@ define i64 @peel_multi_block_loop_iv_step_1() {
|
184 | 188 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
185 | 189 | ; CHECK-NEXT: br label %[[LOOP:.*]]
|
186 | 190 | ; CHECK: [[LOOP]]:
|
187 |
| -; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LATCH:.*]] ] |
188 |
| -; CHECK-NEXT: [[CMP18_NOT_PEEL:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 63 |
189 |
| -; CHECK-NEXT: [[COND_PEEL:%.*]] = select i1 [[CMP18_NOT_PEEL]], i32 10, i32 20 |
190 |
| -; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]]) |
191 |
| -; CHECK-NEXT: [[C_PEEL:%.*]] = call i1 @cond() |
192 |
| -; CHECK-NEXT: br i1 [[C_PEEL]], label %[[THEN:.*]], label %[[LATCH]] |
| 191 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] |
| 192 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 63 |
| 193 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
| 194 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
| 195 | +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() |
| 196 | +; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[LATCH]] |
193 | 197 | ; CHECK: [[THEN]]:
|
194 |
| -; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]]) |
| 198 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
195 | 199 | ; CHECK-NEXT: br label %[[LATCH]]
|
196 | 200 | ; CHECK: [[LATCH]]:
|
197 |
| -; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i64 [[IV_NEXT_LCSSA]], 1 |
198 |
| -; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp ne i64 [[IV_NEXT_PEEL]], 64 |
199 |
| -; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[LOOP]], label %[[EXIT:.*]] |
| 201 | +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 |
| 202 | +; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 64 |
| 203 | +; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]] |
200 | 204 | ; CHECK: [[EXIT]]:
|
201 |
| -; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_LCSSA]], %[[LATCH]] ] |
| 205 | +; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LATCH]] ] |
202 | 206 | ; CHECK-NEXT: ret i64 [[IV_LCSSA]]
|
203 | 207 | ;
|
204 | 208 | entry:
|
@@ -264,6 +268,69 @@ exit:
|
264 | 268 | ret i64 %iv
|
265 | 269 | }
|
266 | 270 |
|
| 271 | +define i64 @peel_single_block_loop_iv_step_1_btc_0() { |
| 272 | +; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_btc_0() { |
| 273 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 274 | +; CHECK-NEXT: br label %[[LOOP:.*]] |
| 275 | +; CHECK: [[LOOP]]: |
| 276 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] |
| 277 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 0 |
| 278 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
| 279 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
| 280 | +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 |
| 281 | +; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 1 |
| 282 | +; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]] |
| 283 | +; CHECK: [[EXIT]]: |
| 284 | +; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ] |
| 285 | +; CHECK-NEXT: ret i64 [[IV_LCSSA]] |
| 286 | +; |
| 287 | +entry: |
| 288 | + br label %loop |
| 289 | + |
| 290 | +loop: |
| 291 | + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| 292 | + %cmp = icmp eq i64 %iv, 0 |
| 293 | + %cond = select i1 %cmp, i32 10, i32 20 |
| 294 | + call void @foo(i32 %cond) |
| 295 | + %iv.next = add i64 %iv, 1 |
| 296 | + %ec = icmp ne i64 %iv.next, 1 |
| 297 | + br i1 %ec, label %loop, label %exit |
| 298 | + |
| 299 | +exit: |
| 300 | + ret i64 %iv |
| 301 | +} |
| 302 | + |
| 303 | +define i64 @peel_single_block_loop_iv_step_1_btc_1() { |
| 304 | +; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_btc_1() { |
| 305 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 306 | +; CHECK-NEXT: br label %[[LOOP:.*]] |
| 307 | +; CHECK: [[LOOP]]: |
| 308 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] |
| 309 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 1 |
| 310 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
| 311 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
| 312 | +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 |
| 313 | +; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 2 |
| 314 | +; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]] |
| 315 | +; CHECK: [[EXIT]]: |
| 316 | +; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ] |
| 317 | +; CHECK-NEXT: ret i64 [[IV_LCSSA]] |
| 318 | +; |
| 319 | +entry: |
| 320 | + br label %loop |
| 321 | + |
| 322 | +loop: |
| 323 | + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| 324 | + %cmp = icmp eq i64 %iv, 1 |
| 325 | + %cond = select i1 %cmp, i32 10, i32 20 |
| 326 | + call void @foo(i32 %cond) |
| 327 | + %iv.next = add i64 %iv, 1 |
| 328 | + %ec = icmp ne i64 %iv.next, 2 |
| 329 | + br i1 %ec, label %loop, label %exit |
| 330 | + |
| 331 | +exit: |
| 332 | + ret i64 %iv |
| 333 | +} |
267 | 334 |
|
268 | 335 | define i64 @peel_single_block_loop_iv_step_1_may_execute_only_once(i64 %n) {
|
269 | 336 | ; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_may_execute_only_once(
|
@@ -427,5 +494,62 @@ exit:
|
427 | 494 | ret i32 %sum.0.lcssa
|
428 | 495 | }
|
429 | 496 |
|
| 497 | +define i64 @peel_multi_exit_multi_latch_loop_iv_step_1(i64 %N) { |
| 498 | +; CHECK-LABEL: define i64 @peel_multi_exit_multi_latch_loop_iv_step_1( |
| 499 | +; CHECK-SAME: i64 [[N:%.*]]) { |
| 500 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 501 | +; CHECK-NEXT: br label %[[LOOP:.*]] |
| 502 | +; CHECK: [[LOOP]]: |
| 503 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_BE:%.*]], %[[LOOP_BACKEDGE:.*]] ] |
| 504 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 63 |
| 505 | +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20 |
| 506 | +; CHECK-NEXT: call void @foo(i32 [[COND]]) |
| 507 | +; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[IV]], [[N]] |
| 508 | +; CHECK-NEXT: br i1 [[C_1]], label %[[THEN:.*]], label %[[ELSE:.*]] |
| 509 | +; CHECK: [[THEN]]: |
| 510 | +; CHECK-NEXT: call void @foo(i32 20) |
| 511 | +; CHECK-NEXT: [[IV_NEXT_1:%.*]] = add i64 [[IV]], 1 |
| 512 | +; CHECK-NEXT: [[EC_1:%.*]] = icmp ne i64 [[IV_NEXT_1]], 64 |
| 513 | +; CHECK-NEXT: br i1 [[EC_1]], label %[[EXIT:.*]], label %[[LOOP_BACKEDGE]] |
| 514 | +; CHECK: [[LOOP_BACKEDGE]]: |
| 515 | +; CHECK-NEXT: [[IV_BE]] = phi i64 [ [[IV_NEXT_1]], %[[THEN]] ], [ [[IV_NEXT_2:%.*]], %[[ELSE]] ] |
| 516 | +; CHECK-NEXT: br label %[[LOOP]] |
| 517 | +; CHECK: [[ELSE]]: |
| 518 | +; CHECK-NEXT: call void @foo(i32 10) |
| 519 | +; CHECK-NEXT: [[IV_NEXT_2]] = add i64 [[IV]], 1 |
| 520 | +; CHECK-NEXT: [[EC_2:%.*]] = icmp ne i64 [[IV_NEXT_2]], 64 |
| 521 | +; CHECK-NEXT: br i1 [[EC_2]], label %[[LOOP_BACKEDGE]], label %[[EXIT]] |
| 522 | +; CHECK: [[EXIT]]: |
| 523 | +; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[ELSE]] ], [ [[IV]], %[[THEN]] ] |
| 524 | +; CHECK-NEXT: ret i64 [[IV_LCSSA]] |
| 525 | +; |
| 526 | +entry: |
| 527 | + br label %loop |
| 528 | + |
| 529 | +loop: |
| 530 | + %iv = phi i64 [ 0, %entry ], [ %iv.next.1, %then ], [ %iv.next.2, %else ] |
| 531 | + %cmp = icmp eq i64 %iv, 63 |
| 532 | + %cond = select i1 %cmp, i32 10, i32 20 |
| 533 | + call void @foo(i32 %cond) |
| 534 | + %c.1 = icmp eq i64 %iv, %N |
| 535 | + br i1 %c.1, label %then, label %else |
| 536 | + |
| 537 | +then: |
| 538 | + call void @foo(i32 20) |
| 539 | + %iv.next.1 = add i64 %iv, 1 |
| 540 | + %ec.1 = icmp ne i64 %iv.next.1, 64 |
| 541 | + br i1 %ec.1, label %exit, label %loop |
| 542 | + |
| 543 | +else: |
| 544 | + call void @foo(i32 10) |
| 545 | + %iv.next.2 = add i64 %iv, 1 |
| 546 | + %ec.2 = icmp ne i64 %iv.next.2, 64 |
| 547 | + br i1 %ec.2, label %loop, label %exit |
| 548 | + |
| 549 | +exit: |
| 550 | + ret i64 %iv |
| 551 | +} |
| 552 | + |
430 | 553 | declare void @foo(i32)
|
431 | 554 | declare i1 @cond()
|
| 555 | + |
0 commit comments