1; RUN: opt < %s -S -loop-unroll -unroll-threshold=30 | FileCheck %s
2; RUN: opt < %s -S -loop-unroll -unroll-threshold=30 -unroll-allow-peeling=false | FileCheck %s --check-prefix=DISABLE
3
4define i32 @invariant_backedge_1(i32 %a, i32 %b) {
5; CHECK-LABEL: @invariant_backedge_1
6; CHECK-NOT:     %plus = phi
7; CHECK:       loop.peel:
8; CHECK:       loop:
9; CHECK:         %i = phi
10; CHECK:         %sum = phi
11; DISABLE-LABEL: @invariant_backedge_1
12; DISABLE-NOT: loop.peel:
13entry:
14  br label %loop
15
16loop:
17  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
18  %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ]
19  %plus = phi i32 [ %a, %entry ], [ %b, %loop ]
20
21  %incsum = add i32 %sum, %plus
22  %inc = add i32 %i, 1
23  %cmp = icmp slt i32 %i, 1000
24
25  br i1 %cmp, label %loop, label %exit
26
27exit:
28  ret i32 %sum
29}
30
31define i32 @invariant_backedge_2(i32 %a, i32 %b) {
32; This loop should be peeled twice because it has a Phi which becomes invariant
33; starting from 3rd iteration.
34; CHECK-LABEL: @invariant_backedge_2
35; CHECK:       loop.peel{{.*}}:
36; CHECK:       loop.peel{{.*}}:
37; CHECK:         %i = phi
38; CHECK:         %sum = phi
39; CHECK-NOT:     %half.inv = phi
40; CHECK-NOT:     %plus = phi
41entry:
42  br label %loop
43
44loop:
45  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
46  %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ]
47  %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ]
48  %plus = phi i32 [ %a, %entry ], [ %half.inv, %loop ]
49
50  %incsum = add i32 %sum, %plus
51  %inc = add i32 %i, 1
52  %cmp = icmp slt i32 %i, 1000
53
54  br i1 %cmp, label %loop, label %exit
55
56exit:
57  ret i32 %sum
58}
59
60define i32 @invariant_backedge_3(i32 %a, i32 %b) {
61; This loop should be peeled thrice because it has a Phi which becomes invariant
62; starting from 4th iteration.
63; CHECK-LABEL: @invariant_backedge_3
64; CHECK:       loop.peel{{.*}}:
65; CHECK:       loop.peel{{.*}}:
66; CHECK:       loop.peel{{.*}}:
67; CHECK:         %i = phi
68; CHECK:         %sum = phi
69; CHECK-NOT:     %half.inv = phi
70; CHECK-NOT:     %half.inv.2 = phi
71; CHECK-NOT:     %plus = phi
72entry:
73  br label %loop
74
75loop:
76  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
77  %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ]
78  %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ]
79  %half.inv.2 = phi i32 [ %a, %entry ], [ %half.inv, %loop ]
80  %plus = phi i32 [ %a, %entry ], [ %half.inv.2, %loop ]
81
82  %incsum = add i32 %sum, %plus
83  %inc = add i32 %i, 1
84  %cmp = icmp slt i32 %i, 1000
85
86  br i1 %cmp, label %loop, label %exit
87
88exit:
89  ret i32 %sum
90}
91
92define i32 @invariant_backedge_limited_by_size(i32 %a, i32 %b) {
93; This loop should normally be peeled thrice because it has a Phi which becomes
94; invariant starting from 4th iteration, but the size of the loop only allows
95; us to peel twice because we are restricted to 30 instructions in resulting
96; code. Thus, %plus Phi node should stay in loop even despite its backedge
97; input is an invariant.
98; CHECK-LABEL: @invariant_backedge_limited_by_size
99; CHECK:       loop.peel{{.*}}:
100; CHECK:       loop.peel{{.*}}:
101; CHECK:         %i = phi
102; CHECK:         %sum = phi
103; CHECK:         %plus = phi i32 [ %a, {{.*}} ], [ %b, %loop ]
104; CHECK-NOT:     %half.inv = phi
105; CHECK-NOT:     %half.inv.2 = phi
106entry:
107  br label %loop
108
109loop:
110  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
111  %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ]
112  %half.inv = phi i32 [ %a, %entry ], [ %b, %loop ]
113  %half.inv.2 = phi i32 [ %a, %entry ], [ %half.inv, %loop ]
114  %plus = phi i32 [ %a, %entry ], [ %half.inv.2, %loop ]
115
116  %incsum = add i32 %sum, %plus
117  %inc = add i32 %i, 1
118  %cmp = icmp slt i32 %i, 1000
119
120  %incsum2 = add i32 %incsum, %plus
121  %incsum3 = add i32 %incsum, %plus
122  %incsum4 = add i32 %incsum, %plus
123  %incsum5 = add i32 %incsum, %plus
124  %incsum6 = add i32 %incsum, %plus
125  %incsum7 = add i32 %incsum, %plus
126
127  br i1 %cmp, label %loop, label %exit
128
129exit:
130  ret i32 %sum
131}
132
133; Peeling should fail due to method size.
134define i32 @invariant_backedge_negative(i32 %a, i32 %b) {
135; CHECK-LABEL: @invariant_backedge_negative
136; CHECK-NOT:   loop.peel{{.*}}:
137; CHECK:       loop:
138; CHECK:         %i = phi
139; CHECK:         %sum = phi
140; CHECK:         %plus = phi
141entry:
142  br label %loop
143
144loop:
145  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
146  %sum = phi i32 [ 0, %entry ], [ %incsum2, %loop ]
147  %plus = phi i32 [ %a, %entry ], [ %b, %loop ]
148
149  %incsum = add i32 %sum, %plus
150  %incsum2 = add i32 %incsum, %plus
151  %incsum3 = add i32 %incsum, %plus
152  %incsum4 = add i32 %incsum, %plus
153  %incsum5 = add i32 %incsum, %plus
154  %incsum6 = add i32 %incsum, %plus
155  %incsum7 = add i32 %incsum, %plus
156  %incsum8 = add i32 %incsum, %plus
157  %incsum9 = add i32 %incsum, %plus
158  %incsum10 = add i32 %incsum, %plus
159  %incsum11 = add i32 %incsum, %plus
160  %incsum12 = add i32 %incsum, %plus
161  %incsum13 = add i32 %incsum, %plus
162  %incsum14 = add i32 %incsum, %plus
163  %incsum15 = add i32 %incsum, %plus
164  %inc = add i32 %i, 1
165  %cmp = icmp slt i32 %i, 1000
166
167  br i1 %cmp, label %loop, label %exit
168
169exit:
170  ret i32 %sum
171}
172
173define i32 @cycled_phis(i32 %a, i32 %b) {
174; Make sure that we do not crash working with cycled Phis and don't peel it.
175; TODO: Actually this loop should be partially unrolled with factor 2.
176; CHECK-LABEL: @cycled_phis
177; CHECK-NOT:   loop.peel{{.*}}:
178; CHECK:       loop:
179; CHECK:         %i = phi
180; CHECK:         %phi.a = phi
181; CHECK:         %phi.b = phi
182; CHECK:         %sum = phi
183entry:
184  br label %loop
185
186loop:
187  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
188  %phi.a = phi i32 [ %a, %entry ], [ %phi.b, %loop ]
189  %phi.b = phi i32 [ %b, %entry ], [ %phi.a, %loop ]
190  %sum = phi i32 [ 0, %entry], [ %incsum, %loop ]
191  %incsum = add i32 %sum, %phi.a
192  %inc = add i32 %i, 1
193  %cmp = icmp slt i32 %i, 1000
194
195  br i1 %cmp, label %loop, label %exit
196
197exit:
198  ret i32 %sum
199}
200