[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / LoopDeletion / multiple-exits.ll
blob1132ec3a207a824c6324012cec2343475c046dae
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.
6 ; RUN: opt < %s -passes=loop-simplify,lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE
7 ; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE
8 ; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
11 define void @foo(i64 %n, i64 %m) nounwind {
12 ; CHECK-LABEL: @foo(
14 entry:
15   br label %bb
16 ; CHECK:       entry:
17 ; BEFORE-NEXT:   br label %bb
18 ; AFTER-NEXT:    br label %return
20 bb:
21   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ]
22   %t0 = add i64 %x.0, 1
23   %t1 = icmp slt i64 %x.0, %n
24   br i1 %t1, label %bb2, label %return
25 ; BEFORE:      bb:
26 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
27 ; AFTER-NOT:   bb:
28 ; AFTER-NOT:     br
30 bb2:
31   %t2 = icmp slt i64 %x.0, %m
32   br i1 %t1, label %bb, label %return
33 ; BEFORE:      bb2:
34 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
35 ; AFTER-NOT:   bb2:
36 ; AFTER-NOT:     br
38 return:
39   ret void
40 ; CHECK:       return:
41 ; CHECK-NEXT:    ret void
44 define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
45 ; CHECK-LABEL: @bar(
47 entry:
48   br label %bb
49 ; CHECK:       entry:
50 ; BEFORE-NEXT:   br label %bb
51 ; AFTER-NEXT:    br label %return
53 bb:
54   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
55   %t0 = add i64 %x.0, 1
56   %t1 = icmp slt i64 %x.0, %n
57   br i1 %t1, label %bb2, label %return
58 ; BEFORE:      bb:
59 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
60 ; AFTER-NOT:   bb:
61 ; AFTER-NOT:     br
63 bb2:
64   %t2 = icmp slt i64 %x.0, %m
65   ; This unused division prevents unifying this loop exit path with others
66   ; because it can be deleted but cannot be hoisted.
67   %unused1 = udiv i64 42, %maybe_zero
68   br i1 %t2, label %bb3, label %return
69 ; BEFORE:      bb2:
70 ; BEFORE:        br i1 {{.*}}, label %bb3, label %return
71 ; AFTER-NOT:   bb2:
72 ; AFTER-NOT:     br
74 bb3:
75   %t3 = icmp slt i64 %x.0, %m
76   ; This unused division prevents unifying this loop exit path with others
77   ; because it can be deleted but cannot be hoisted.
78   %unused2 = sdiv i64 42, %maybe_zero
79   br i1 %t3, label %bb, label %return
80 ; BEFORE:      bb3:
81 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
82 ; AFTER-NOT:   bb3:
83 ; AFTER-NOT:     br
85 return:
86   %x.lcssa = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
87   ret i64 %x.lcssa
88 ; 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]]
94 ; This function has a loop which looks like @bar's but that cannot be deleted
95 ; because which path we exit through determines which value is selected.
96 define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
97 ; CHECK-LABEL:  @baz(
99 entry:
100   br label %bb
101 ; CHECK:       entry:
102 ; CHECK-NEXT:    br label %bb
105   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
106   %t0 = add i64 %x.0, 1
107   %t1 = icmp slt i64 %x.0, %n
108   br i1 %t1, label %bb2, label %return
109 ; CHECK:       bb:
110 ; CHECK:         br i1 {{.*}}, label %bb2, label %return
112 bb2:
113   %t2 = icmp slt i64 %x.0, %m
114   ; This unused division prevents unifying this loop exit path with others
115   ; because it can be deleted but cannot be hoisted.
116   %unused1 = udiv i64 42, %maybe_zero
117   br i1 %t2, label %bb3, label %return
118 ; CHECK:       bb2:
119 ; CHECK:         br i1 {{.*}}, label %bb3, label %return
121 bb3:
122   %t3 = icmp slt i64 %x.0, %m
123   ; This unused division prevents unifying this loop exit path with others
124   ; because it can be deleted but cannot be hoisted.
125   %unused2 = sdiv i64 42, %maybe_zero
126   br i1 %t3, label %bb, label %return
127 ; CHECK:       bb3:
128 ; CHECK:         br i1 {{.*}}, label %bb, label %return
130 return:
131   %x.lcssa = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
132   ret i64 %x.lcssa
133 ; CHECK: return:
134 ; CHECK-NEXT:  %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
135 ; CHECK-NEXT:  ret i64 %[[X]]