| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt -S -passes=loop-simplify < %s | FileCheck %s --implicit-check-not="!llvm.loop" | |
| ; When the backedges of a loop are merged into a unique backedge block, the | |
| ; llvm.loop metadata is only kept if all backedges carry the same loop ID. | |
| ; Backedges with different metadata may come from different source loops. | |
| ; The convergent call keeps LoopSimplify from separating the loops. | |
| ; The case where all backedges share the same loop ID is covered by | |
| ; preserve-llvm-loop-metadata.ll. | |
| declare void @convergent() convergent | |
| define void @different_md(i1 %c1, i1 %c2) { | |
| ; CHECK-LABEL: define void @different_md( | |
| ; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*:]] | |
| ; CHECK-NEXT: br label %[[HEADER:.*]] | |
| ; CHECK: [[HEADER]]: | |
| ; CHECK-NEXT: call void @convergent() | |
| ; CHECK-NEXT: br i1 [[C1]], label %[[INNER_LATCH:.*]], label %[[OUTER_LATCH:.*]] | |
| ; CHECK: [[INNER_LATCH]]: | |
| ; CHECK-NEXT: br i1 [[C2]], label %[[HEADER_BACKEDGE:.*]], label %[[EXIT:.*]] | |
| ; CHECK: [[HEADER_BACKEDGE]]: | |
| ; CHECK-NEXT: br label %[[HEADER]] | |
| ; CHECK: [[OUTER_LATCH]]: | |
| ; CHECK-NEXT: br i1 [[C2]], label %[[HEADER_BACKEDGE]], label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %header | |
| header: | |
| call void @convergent() | |
| br i1 %c1, label %inner.latch, label %outer.latch | |
| inner.latch: | |
| br i1 %c2, label %header, label %exit, !llvm.loop !0 | |
| outer.latch: | |
| br i1 %c2, label %header, label %exit, !llvm.loop !2 | |
| exit: | |
| ret void | |
| } | |
| define void @partial_md(i1 %c1, i1 %c2) { | |
| ; CHECK-LABEL: define void @partial_md( | |
| ; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*:]] | |
| ; CHECK-NEXT: br label %[[HEADER:.*]] | |
| ; CHECK: [[HEADER]]: | |
| ; CHECK-NEXT: call void @convergent() | |
| ; CHECK-NEXT: br i1 [[C1]], label %[[INNER_LATCH:.*]], label %[[OUTER_LATCH:.*]] | |
| ; CHECK: [[INNER_LATCH]]: | |
| ; CHECK-NEXT: br i1 [[C2]], label %[[HEADER_BACKEDGE:.*]], label %[[EXIT:.*]] | |
| ; CHECK: [[HEADER_BACKEDGE]]: | |
| ; CHECK-NEXT: br label %[[HEADER]] | |
| ; CHECK: [[OUTER_LATCH]]: | |
| ; CHECK-NEXT: br i1 [[C2]], label %[[HEADER_BACKEDGE]], label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %header | |
| header: | |
| call void @convergent() | |
| br i1 %c1, label %inner.latch, label %outer.latch | |
| inner.latch: | |
| br i1 %c2, label %header, label %exit, !llvm.loop !4 | |
| outer.latch: | |
| br i1 %c2, label %header, label %exit | |
| exit: | |
| ret void | |
| } | |
| !0 = distinct !{!0, !1} | |
| !1 = !{!"llvm.loop.mustprogress"} | |
| !2 = distinct !{!2, !3} | |
| !3 = !{!"llvm.loop.unroll.disable"} | |
| !4 = distinct !{!4, !1} |