137 lines · plain
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 the3; critical components remain after those passes and are visible to the loop4; deletion pass.5;6; RUN: opt < %s -passes=loop-simplify,lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE7; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE8; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER9 10 11define void @foo(i64 %n, i64 %m) nounwind {12; CHECK-LABEL: @foo(13 14entry:15 br label %bb16; CHECK: entry:17; BEFORE-NEXT: br label %bb18; AFTER-NEXT: br label %return19 20bb:21 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ]22 %t0 = add i64 %x.0, 123 %t1 = icmp slt i64 %x.0, %n24 br i1 %t1, label %bb2, label %return25; BEFORE: bb:26; BEFORE: br i1 {{.*}}, label %bb2, label %return27; AFTER-NOT: bb:28; AFTER-NOT: br29 30bb2:31 %t2 = icmp slt i64 %x.0, %m32 br i1 %t1, label %bb, label %return33; BEFORE: bb2:34; BEFORE: br i1 {{.*}}, label %bb, label %return35; AFTER-NOT: bb2:36; AFTER-NOT: br37 38return:39 ret void40; CHECK: return:41; CHECK-NEXT: ret void42}43 44define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind {45; CHECK-LABEL: @bar(46 47entry:48 br label %bb49; CHECK: entry:50; BEFORE-NEXT: br label %bb51; AFTER-NEXT: br label %return52 53bb:54 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]55 %t0 = add i64 %x.0, 156 %t1 = icmp slt i64 %x.0, %n57 br i1 %t1, label %bb2, label %return58; BEFORE: bb:59; BEFORE: br i1 {{.*}}, label %bb2, label %return60; AFTER-NOT: bb:61; AFTER-NOT: br62 63bb2:64 %t2 = icmp slt i64 %x.0, %m65 ; This unused division prevents unifying this loop exit path with others66 ; because it can be deleted but cannot be hoisted.67 %unused1 = udiv i64 42, %maybe_zero68 br i1 %t2, label %bb3, label %return69; BEFORE: bb2:70; BEFORE: br i1 {{.*}}, label %bb3, label %return71; AFTER-NOT: bb2:72; AFTER-NOT: br73 74bb3:75 %t3 = icmp slt i64 %x.0, %m76 ; This unused division prevents unifying this loop exit path with others77 ; because it can be deleted but cannot be hoisted.78 %unused2 = sdiv i64 42, %maybe_zero79 br i1 %t3, label %bb, label %return80; BEFORE: bb3:81; BEFORE: br i1 {{.*}}, label %bb, label %return82; AFTER-NOT: bb3:83; AFTER-NOT: br84 85return:86 %x.lcssa = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]87 ret i64 %x.lcssa88; CHECK: return:89; BEFORE-NEXT: %[[X:.*]] = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]90; AFTER-NEXT: %[[X:.*]] = phi i64 [ 10, %entry ]91; CHECK-NEXT: ret i64 %[[X]]92}93 94; This function has a loop which looks like @bar's but that cannot be deleted95; because which path we exit through determines which value is selected.96define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind {97; CHECK-LABEL: @baz(98 99entry:100 br label %bb101; CHECK: entry:102; CHECK-NEXT: br label %bb103 104bb:105 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]106 %t0 = add i64 %x.0, 1107 %t1 = icmp slt i64 %x.0, %n108 br i1 %t1, label %bb2, label %return109; CHECK: bb:110; CHECK: br i1 {{.*}}, label %bb2, label %return111 112bb2:113 %t2 = icmp slt i64 %x.0, %m114 ; This unused division prevents unifying this loop exit path with others115 ; because it can be deleted but cannot be hoisted.116 %unused1 = udiv i64 42, %maybe_zero117 br i1 %t2, label %bb3, label %return118; CHECK: bb2:119; CHECK: br i1 {{.*}}, label %bb3, label %return120 121bb3:122 %t3 = icmp slt i64 %x.0, %m123 ; This unused division prevents unifying this loop exit path with others124 ; because it can be deleted but cannot be hoisted.125 %unused2 = sdiv i64 42, %maybe_zero126 br i1 %t3, label %bb, label %return127; CHECK: bb3:128; CHECK: br i1 {{.*}}, label %bb, label %return129 130return:131 %x.lcssa = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]132 ret i64 %x.lcssa133; CHECK: return:134; CHECK-NEXT: %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]135; CHECK-NEXT: ret i64 %[[X]]136}137