1; Checks whether dead loops with multiple exits can be eliminated. 2; Note that we loop simplify and LCSSA over the test cases to make sure the 3; critical components remain after those passes and are visible to the loop 4; deletion pass. 5; 6; RUN: opt < %s -loop-simplify -lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE 7; RUN: opt < %s -loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER 8; 9; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE 10; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER 11 12 13define void @foo(i64 %n, i64 %m) nounwind { 14; CHECK-LABEL: @foo( 15 16entry: 17 br label %bb 18; CHECK: entry: 19; BEFORE-NEXT: br label %bb 20; AFTER-NEXT: br label %return 21 22bb: 23 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ] 24 %t0 = add i64 %x.0, 1 25 %t1 = icmp slt i64 %x.0, %n 26 br i1 %t1, label %bb2, label %return 27; BEFORE: bb: 28; BEFORE: br i1 {{.*}}, label %bb2, label %return 29; AFTER-NOT: bb: 30; AFTER-NOT: br 31 32bb2: 33 %t2 = icmp slt i64 %x.0, %m 34 br i1 %t1, label %bb, label %return 35; BEFORE: bb2: 36; BEFORE: br i1 {{.*}}, label %bb, label %return 37; AFTER-NOT: bb2: 38; AFTER-NOT: br 39 40return: 41 ret void 42; CHECK: return: 43; CHECK-NEXT: ret void 44} 45 46define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind { 47; CHECK-LABEL: @bar( 48 49entry: 50 br label %bb 51; CHECK: entry: 52; BEFORE-NEXT: br label %bb 53; AFTER-NEXT: br label %return 54 55bb: 56 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ] 57 %t0 = add i64 %x.0, 1 58 %t1 = icmp slt i64 %x.0, %n 59 br i1 %t1, label %bb2, label %return 60; BEFORE: bb: 61; BEFORE: br i1 {{.*}}, label %bb2, label %return 62; AFTER-NOT: bb: 63; AFTER-NOT: br 64 65bb2: 66 %t2 = icmp slt i64 %x.0, %m 67 ; This unused division prevents unifying this loop exit path with others 68 ; because it can be deleted but cannot be hoisted. 69 %unused1 = udiv i64 42, %maybe_zero 70 br i1 %t2, label %bb3, label %return 71; BEFORE: bb2: 72; BEFORE: br i1 {{.*}}, label %bb3, label %return 73; AFTER-NOT: bb2: 74; AFTER-NOT: br 75 76bb3: 77 %t3 = icmp slt i64 %x.0, %m 78 ; This unused division prevents unifying this loop exit path with others 79 ; because it can be deleted but cannot be hoisted. 80 %unused2 = sdiv i64 42, %maybe_zero 81 br i1 %t3, label %bb, label %return 82; BEFORE: bb3: 83; BEFORE: br i1 {{.*}}, label %bb, label %return 84; AFTER-NOT: bb3: 85; AFTER-NOT: br 86 87return: 88 %x.lcssa = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ] 89 ret i64 %x.lcssa 90; CHECK: return: 91; BEFORE-NEXT: %[[X:.*]] = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ] 92; AFTER-NEXT: %[[X:.*]] = phi i64 [ 10, %entry ] 93; CHECK-NEXT: ret i64 %[[X]] 94} 95 96; This function has a loop which looks like @bar's but that cannot be deleted 97; because which path we exit through determines which value is selected. 98define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind { 99; CHECK-LABEL: @baz( 100 101entry: 102 br label %bb 103; CHECK: entry: 104; CHECK-NEXT: br label %bb 105 106bb: 107 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ] 108 %t0 = add i64 %x.0, 1 109 %t1 = icmp slt i64 %x.0, %n 110 br i1 %t1, label %bb2, label %return 111; CHECK: bb: 112; CHECK: br i1 {{.*}}, label %bb2, label %return 113 114bb2: 115 %t2 = icmp slt i64 %x.0, %m 116 ; This unused division prevents unifying this loop exit path with others 117 ; because it can be deleted but cannot be hoisted. 118 %unused1 = udiv i64 42, %maybe_zero 119 br i1 %t2, label %bb3, label %return 120; CHECK: bb2: 121; CHECK: br i1 {{.*}}, label %bb3, label %return 122 123bb3: 124 %t3 = icmp slt i64 %x.0, %m 125 ; This unused division prevents unifying this loop exit path with others 126 ; because it can be deleted but cannot be hoisted. 127 %unused2 = sdiv i64 42, %maybe_zero 128 br i1 %t3, label %bb, label %return 129; CHECK: bb3: 130; CHECK: br i1 {{.*}}, label %bb, label %return 131 132return: 133 %x.lcssa = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ] 134 ret i64 %x.lcssa 135; CHECK: return: 136; CHECK-NEXT: %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ] 137; CHECK-NEXT: ret i64 %[[X]] 138} 139