| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes | |
| ; RUN: opt < %s -passes=loop-deletion -verify-dom-info -S | FileCheck %s | |
| ;; Original C Code: | |
| ;; void unknown_tripcount_mustprogress_attr_mustprogress_loopmd(int a, int b) { | |
| ;; for (; a < b;) ; | |
| ;; for (;;) ; | |
| ;; } | |
| define void @unknown_tripcount_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) #0 { | |
| ; CHECK: Function Attrs: mustprogress | |
| ; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_mustprogress_loopmd | |
| ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#.*]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: unreachable | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %cmp = icmp slt i32 %a, %b | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.cond, !llvm.loop !2 | |
| for.end: | |
| br label %for.cond1 | |
| for.cond1: | |
| br label %for.cond1 | |
| } | |
| ;; Original C Code: | |
| ;; void unknown_tripcount_mustprogress_attr_no_mustprogress_loopmd(int a, int b) { | |
| ;; for (; a < b;) ; | |
| ;; for (;;) ; | |
| ;; } | |
| ;; => Removed mustprogress loop attribute | |
| define void @unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd(i32 %a, i32 %b) #0 { | |
| ; CHECK: Function Attrs: mustprogress | |
| ; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_mustprogress_attr_no_mustprogess_loopmd | |
| ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: unreachable | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %cmp = icmp slt i32 %a, %b | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.cond | |
| for.end: | |
| br label %for.cond1 | |
| for.cond1: | |
| br label %for.cond1 | |
| } | |
| ;; Original C Code: | |
| ;; void known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() { | |
| ;; for (int i = 0; i < 5; i++) ; | |
| ;; } | |
| define void @known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() { | |
| ; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_no_mustprogress_loopmd() { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
| %cmp = icmp slt i32 %i.0, 5 | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.inc | |
| for.inc: | |
| %inc = add nsw i32 %i.0, 1 | |
| br label %for.cond | |
| for.end: | |
| ret void | |
| } | |
| ;; Original C Code: | |
| ;; void known_tripcount_no_mustprogress_attr_mustprogress_loopmd() { | |
| ;; for (int i = 0; i < 5; i++) ; | |
| ;; } | |
| ;; => Added mustprogress loop attribute | |
| define void @known_tripcount_no_mustprogress_attr_mustprogress_loopmd() { | |
| ; CHECK-LABEL: define {{[^@]+}}@known_tripcount_no_mustprogress_attr_mustprogress_loopmd() { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
| %cmp = icmp slt i32 %i.0, 5 | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.inc | |
| for.inc: | |
| %inc = add nsw i32 %i.0, 1 | |
| br label %for.cond, !llvm.loop !4 | |
| for.end: | |
| ret void | |
| } | |
| ;; Original C Code: | |
| ;; void known_tripcount_mustprogress_attr_no_mustprogress_loopmd() { | |
| ;; for (int i = 0; i < 5; i++) ; | |
| ;; } | |
| ;; => Added mustprogress function attribute | |
| define void @known_tripcount_mustprogress_attr_no_mustprogress_loopmd() #0 { | |
| ; CHECK: Function Attrs: mustprogress | |
| ; CHECK-LABEL: define {{[^@]+}}@known_tripcount_mustprogress_attr_no_mustprogress_loopmd | |
| ; CHECK-SAME: () [[ATTR0]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
| %cmp = icmp slt i32 %i.0, 5 | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.inc | |
| for.inc: | |
| %inc = add nsw i32 %i.0, 1 | |
| br label %for.cond | |
| for.end: | |
| ret void | |
| } | |
| ;; Original C Code: | |
| ;; void known_tripcount_mustprogress_attr_mustprogress_loopmd() { | |
| ;; for (int i = 0; i < 5; i++) ; | |
| ;; } | |
| ;; => Added mustprogress function and mustprogress loop attribute | |
| define void @known_tripcount_mustprogress_attr_mustprogress_loopmd() #0 { | |
| ; CHECK: Function Attrs: mustprogress | |
| ; CHECK-LABEL: define {{[^@]+}}@known_tripcount_mustprogress_attr_mustprogress_loopmd | |
| ; CHECK-SAME: () [[ATTR0]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
| %cmp = icmp slt i32 %i.0, 5 | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.inc | |
| for.inc: | |
| %inc = add nsw i32 %i.0, 1 | |
| br label %for.cond, !llvm.loop !5 | |
| for.end: | |
| ret void | |
| } | |
| ;; Original C Code: | |
| ;; void unknown_tripcount_no_mustprogress_attr_mustprogress_loopmd(int a, int b) { | |
| ;; for (; a < b;) ; | |
| ;; } | |
| ;; => Added mustprogress loop attribute | |
| define void @unknown_tripcount_no_mustprogress_attr_mustprogress_loopmd(i32 %a, i32 %b) { | |
| ; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_no_mustprogress_attr_mustprogress_loopmd | |
| ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_END:%.*]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %cmp = icmp slt i32 %a, %b | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.cond, !llvm.loop !6 | |
| for.end: | |
| ret void | |
| } | |
| ;; Original C Code: | |
| ;; void unknown_tripcount_no_mustprogress_attr_no_mustprogress_loopmd(int a, int b) { | |
| ;; for (; a < b;) ; | |
| ;; } | |
| define void @unknown_tripcount_no_mustprogress_attr_no_mustprogress_loopmd(i32 %a, i32 %b) { | |
| ; CHECK-LABEL: define {{[^@]+}}@unknown_tripcount_no_mustprogress_attr_no_mustprogress_loopmd | |
| ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_COND:%.*]] | |
| ; CHECK: for.cond: | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]] | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] | |
| ; CHECK: for.body: | |
| ; CHECK-NEXT: br label [[FOR_COND]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %cmp = icmp slt i32 %a, %b | |
| br i1 %cmp, label %for.body, label %for.end | |
| for.body: | |
| br label %for.cond | |
| for.end: | |
| ret void | |
| } | |
| ; CHECK: attributes [[ATTR0]] = { mustprogress } | |
| attributes #0 = { mustprogress } | |
| !2 = distinct !{!2, !3} | |
| !3 = !{!"llvm.loop.mustprogress"} | |
| !4 = distinct !{!4, !3} | |
| !5 = distinct !{!5, !3} | |
| !6 = distinct !{!6, !3} |