[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / LoopUnroll / unroll-unconditional-latch.ll
blobda0d9ec4e8e4b2a3d8b5aed0ea7f7c69a9784fd5
1 ; RUN: opt -loop-unroll -S %s -verify-loop-info -verify-dom-info -verify-loop-lcssa | FileCheck %s
3 %struct.spam = type { double, double, double, double, double, double, double }
5 define void @test2(i32* %arg)  {
6 ; CHECK-LABEL: void @test2
7 ; CHECK-NEXT: entry:
8 ; CHECK-NEXT:   br label %for.header
10 ; CHECK-LABEL: for.header:                                       ; preds = %entry
11 ; CHECK-NEXT:    store i32 0, i32* %arg, align 4
12 ; CHECK-NEXT:    br label %for.latch
14 ; CHECK-LABEL: for.latch:                                        ; preds = %for.header
15 ; CHECK-NEXT:    %ptr.1 = getelementptr inbounds i32, i32* %arg, i64 1
16 ; CHECK-NEXT:    store i32 0, i32* %ptr.1, align 4
17 ; CHECK-NEXT:    br label %for.latch.1
19 ; CHECK-LABEL: if.end.loopexit:                                  ; preds = %for.latch.2
20 ; CHECK-NEXT:    ret void
22 ; CHECK-LABEL: for.latch.1:                                      ; preds = %for.latch
23 ; CHECK-NEXT:    %ptr.2 = getelementptr inbounds i32, i32* %arg, i64 2
24 ; CHECK-NEXT:    store i32 0, i32* %ptr.2, align 4
25 ; CHECK-NEXT:    br label %for.latch.2
27 ; CHECK-LABEL: for.latch.2:                                      ; preds = %for.latch.1
28 ; CHECK-NEXT:    %ptr.3 = getelementptr inbounds i32, i32* %arg, i64 3
29 ; CHECK-NEXT:    store i32 0, i32* %ptr.3, align 4
30 ; CHECK-NEXT:    br i1 true, label %if.end.loopexit, label %for.latch.3
32 ; CHECK-LABEL: for.latch.3:                                      ; preds = %for.latch.2
33 ; CHECK-NEXT:    unreachable
35 entry:
36   br label %for.header
38 for.header:                              ; preds = %for.latch, %entry
39   %indvars.iv800 = phi i64 [ 0, %entry ], [ %indvars.iv.next801, %for.latch ]
40   %ptr = getelementptr inbounds i32, i32* %arg, i64 %indvars.iv800
41   store i32 0, i32* %ptr, align 4
42   %indvars.iv.next801 = add nuw nsw i64 %indvars.iv800, 1
43   %exitcond802 = icmp eq i64 %indvars.iv.next801, 4
44   br i1 %exitcond802, label %if.end.loopexit, label %for.latch
46 for.latch: ; preds = %for.header
47   br label %for.header
49 if.end.loopexit:                                  ; preds = %for.header
50   ret void
53 define double @test_with_lcssa(double %arg1, double* %arg2) {
54 ; CHECK-LABEL: define double @test_with_lcssa(
55 ; CHECK-LABEL: entry:
56 ; CHECK-NEXT:    br label %loop.header
58 ; CHECK-LABEL: loop.header:                                      ; preds = %entry
59 ; CHECK-NEXT:    %res = fsub double %arg1, 3.000000e+00
60 ; CHECK-NEXT:    br label %loop.latch
62 ; CHECK-LABEL: loop.latch:                                       ; preds = %loop.header
63 ; CHECK-NEXT:    %ptr = getelementptr inbounds double, double* %arg2, i64 1
64 ; CHECK-NEXT:    %lv = load double, double* %ptr, align 8
65 ; CHECK-NEXT:    %res.1 = fsub double %lv, %res
66 ; CHECK-NEXT:    br i1 true, label %loop.exit, label %loop.latch.1
68 ; CHECK-LABEL: loop.exit:                                        ; preds = %loop.latch
69 ; CHECK-NEXT:    %res.lcssa = phi double [ %res.1, %loop.latch ]
70 ; CHECK-NEXT:    ret double %res.lcssa
72 ; CHECK-LABEL: loop.latch.1:                                     ; preds = %loop.latch
73 ; CHECK-NEXT:    %ptr.1 = getelementptr inbounds double, double* %arg2, i64 2
74 ; CHECK-NEXT:    unreachable
76 entry:
77   br label %loop.header
79 loop.header:                                            ; preds = %entry, %loop.latch
80   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
81   %d1 = phi double [ %arg1, %entry ], [ %lv, %loop.latch ]
82   %d2 = phi double [ 3.0, %entry ], [ %res, %loop.latch ]
83   %res = fsub double %d1, %d2
84   %iv.next = add nuw nsw i64 %iv, 1
85   %cond = icmp eq i64 %iv.next, 2
86   br i1 %cond, label %loop.exit, label %loop.latch
88 loop.latch:                                            ; preds = %bb366
89   %ptr = getelementptr inbounds double, double* %arg2, i64 %iv.next
90   %lv = load double, double* %ptr, align 8
91   br label %loop.header
93 loop.exit:                                            ; preds = %bb366
94   %res.lcssa = phi double [ %res, %loop.header ]
95   ret double %res.lcssa
98 ; We unroll the outer loop and need to preserve LI for the inner loop.
99 define void @test_with_nested_loop(i32* %arg)  {
100 ; CHECK-LABEL: void @test_with_nested_loop
101 ; CHECK-LABEL: entry:
102 ; CHECK-NEXT:    br label %outer.header
104 ; CHECK-DAG: outer.header:                                     ; preds = %entry
105 ; CHECK-NEXT:    br label %inner.body.preheader
107 ; CHECK-DAG: inner.body.preheader:                             ; preds = %outer.header
108 ; CHECK-NEXT:    br label %inner.body
110 ; CHECK-LABEL: inner.body:                                       ; preds = %inner.body.preheader, %inner.body
111 ; CHECK-NEXT:    %j.iv = phi i64 [ %j.iv.next, %inner.body ], [ 0, %inner.body.preheader ]
112 ; CHECK-NEXT:    %ptr = getelementptr inbounds i32, i32* %arg, i64 %j.iv
113 ; CHECK-NEXT:    store i32 0, i32* %ptr, align 4
114 ; CHECK-NEXT:    %j.iv.next = add nuw nsw i64 %j.iv, 1
115 ; CHECK-NEXT:    %inner.cond = icmp eq i64 %j.iv.next, 40000
116 ; CHECK-NEXT:    br i1 %inner.cond, label %outer.latch, label %inner.body
118 ; CHECK-LABEL: outer.latch:                                      ; preds = %inner.body
119 ; CHECK-NEXT:    br label %inner.body.preheader.1
121 ; CHECK-LABEL: exit:                                             ; preds = %outer.latch.1
122 ; CHECK-NEXT:    ret void
124 ; CHECK-LABEL: inner.body.preheader.1:                           ; preds = %outer.latch
125 ; CHECK-NEXT:    br label %inner.body.1
127 ; CHECK-LABEL: inner.body.1:                                     ; preds = %inner.body.1, %inner.body.preheader.1
128 ; CHECK-NEXT:    %j.iv.1 = phi i64 [ %j.iv.next.1, %inner.body.1 ], [ 0, %inner.body.preheader.1 ]
129 ; CHECK-NEXT:    %idx.1 = add i64 1, %j.iv.1
130 ; CHECK-NEXT:    %ptr.1 = getelementptr inbounds i32, i32* %arg, i64 %idx.1
131 ; CHECK-NEXT:    store i32 0, i32* %ptr.1, align 4
132 ; CHECK-NEXT:    %j.iv.next.1 = add nuw nsw i64 %j.iv.1, 1
133 ; CHECK-NEXT:    %inner.cond.1 = icmp eq i64 %j.iv.next.1, 40000
134 ; CHECK-NEXT:    br i1 %inner.cond.1, label %outer.latch.1, label %inner.body.1
136 ; CHECK-LABEL: outer.latch.1:                                    ; preds = %inner.body.1
137 ; CHECK-NEXT:    br i1 true, label %exit, label %inner.body.preheader.2
139 ; CHECK-LABEL: inner.body.preheader.2:                           ; preds = %outer.latch.1
140 ; CHECK-NEXT:    br label %inner.body.2
142 ; CHECK-LABEL: inner.body.2:                                     ; preds = %inner.body.2, %inner.body.preheader.2
143 ; CHECK-NEXT:    %j.iv.2 = phi i64 [ %j.iv.next.2, %inner.body.2 ], [ 0, %inner.body.preheader.2 ]
144 ; CHECK-NEXT:    %idx.2 = add i64 2, %j.iv.2
145 ; CHECK-NEXT:    %ptr.2 = getelementptr inbounds i32, i32* %arg, i64 %idx.2
146 ; CHECK-NEXT:    store i32 0, i32* %ptr.2, align 4
147 ; CHECK-NEXT:    %j.iv.next.2 = add nuw nsw i64 %j.iv.2, 1
148 ; CHECK-NEXT:    %inner.cond.2 = icmp eq i64 %j.iv.next.2, 40000
149 ; CHECK-NEXT:    br i1 %inner.cond.2, label %outer.latch.2, label %inner.body.2
151 ; CHECK-LABEL: outer.latch.2:                                    ; preds = %inner.body.2
152 ; CHECK-NEXT:    unreachable
154 entry:
155   br label %outer.header
157 outer.header:                              ; preds = %outer.latch, %entry
158   %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
159   %outer.iv.next = add nuw nsw i64 %outer.iv, 1
160   %outer.cond = icmp eq i64 %outer.iv, 2
161   br i1 %outer.cond, label %exit, label %inner.body
163 inner.body:
164   %j.iv = phi i64 [ 0, %outer.header ], [ %j.iv.next, %inner.body ]
165   %idx = add i64 %outer.iv, %j.iv
166   %ptr = getelementptr inbounds i32, i32* %arg, i64 %idx
167   store i32 0, i32* %ptr, align 4
168   %j.iv.next = add nuw nsw i64 %j.iv, 1
169   %inner.cond = icmp eq i64 %j.iv.next, 40000
170   br i1 %inner.cond, label %outer.latch, label %inner.body
172 outer.latch: ; preds = %inner.body
173   br label %outer.header
175 exit:                                  ; preds = %outer.header
176   ret void
179 ; We unroll the inner loop and need to preserve LI for the outer loop.
180 define void @test_with_nested_loop_unroll_inner(i32* %arg)  {
181 ; CHECK-LABEL: define void @test_with_nested_loop_unroll_inner(
182 ; CHECK-LABEL: entry:
183 ; CHECK-NEXT:   br label %outer.header
185 ; CHECK-LABEL: outer.header:                                     ; preds = %inner.body, %entry
186 ; CHECK-NEXT:   %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %inner.body ]
187 ; CHECK-NEXT:   %outer.iv.next = add nuw nsw i64 %outer.iv, 1
188 ; CHECK-NEXT:   %outer.cond = icmp eq i64 %outer.iv, 40000
189 ; CHECK-NEXT:   br i1 %outer.cond, label %exit, label %inner.body.preheader
191 ; CHECK-LABEL: inner.body.preheader:                             ; preds = %outer.header
192 ; CHECK-NEXT:   br label %inner.body
194 ; CHECK-LABEL: inner.body:                                       ; preds = %inner.body.preheader
195 ; CHECK-NEXT:   %ptr = getelementptr inbounds i32, i32* %arg, i64 %outer.iv
196 ; CHECK-NEXT:   store i32 0, i32* %ptr, align 4
197 ; CHECK-NEXT:   %idx.1 = add i64 %outer.iv, 1
198 ; CHECK-NEXT:   %ptr.1 = getelementptr inbounds i32, i32* %arg, i64 %idx.1
199 ; CHECK-NEXT:   store i32 0, i32* %ptr.1, align 4
200 ; CHECK-NEXT:   br label %outer.header
202 ; CHECK-LABEL: exit:                                             ; preds = %outer.header
203 ; CHECK-NEXT:  ret void
205 entry:
206   br label %outer.header
208 outer.header:                              ; preds = %outer.latch, %entry
209   %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
210   %outer.iv.next = add nuw nsw i64 %outer.iv, 1
211   %outer.cond = icmp eq i64 %outer.iv, 40000
212   br i1 %outer.cond, label %exit, label %inner.body
214 inner.body:
215   %j.iv = phi i64 [ 0, %outer.header ], [ %j.iv.next, %inner.body ]
216   %idx = add i64 %outer.iv, %j.iv
217   %ptr = getelementptr inbounds i32, i32* %arg, i64 %idx
218   store i32 0, i32* %ptr, align 4
219   %j.iv.next = add nuw nsw i64 %j.iv, 1
220   %inner.cond = icmp eq i64 %j.iv.next, 2
221   br i1 %inner.cond, label %outer.latch, label %inner.body
223 outer.latch: ; preds = %inner.body
224   br label %outer.header
226 exit:                                  ; preds = %outer.header
227   ret void
232 ; Check that we do not crash for headers with non-branch instructions, e.g.
233 ; switch. We do not unroll in those cases.
234 define void @test_switchinst_in_header() {
235 ; CHECK-LABEL: define void @test_switchinst_in_header() {
236 ; CHECK-LABEL: entry:
237 ; CHECK-NEXT:    br label %while.header
239 ; CHECK-LABEL: while.header:                                     ; preds = %while.latch, %entry
240 ; CHECK-NEXT:    switch i32 undef, label %exit [
241 ; CHECK-NEXT:      i32 11, label %while.body1
242 ; CHECK-NEXT:      i32 5, label %while.body2
243 ; CHECK-NEXT:    ]
245 ; CHECK-LABEL: while.body1:                                      ; preds = %while.header
246 ; CHECK-NEXT:    unreachable
248 ; CHECK-LABEL: while.body2:                                      ; preds = %while.header
249 ; CHECK-NEXT:    br label %while.latch
251 ; CHECK-LABEL: while.latch:                                      ; preds = %while.body2
252 ; CHECK-NEXT:    br label %while.header
254 ; CHECK-LABEL: exit:                                             ; preds = %while.header
255 ; CHECK-NEXT:    ret void
257 entry:
258   br label %while.header
260 while.header:                               ; preds = %while.latch, %entry
261   switch i32 undef, label %exit [
262     i32 11, label %while.body1
263     i32 5, label %while.body2
264   ]
266 while.body1:                                ; preds = %while.header
267   unreachable
269 while.body2:                                ; preds = %while.header
270   br label %while.latch
272 while.latch:                                                            ; preds = %while.body2
273   br label %while.header
275 exit:                                               ; preds = %while.header
276   ret void