[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / LoopUnroll / runtime-loop-multiexit-dom-verify.ll
blobb3c0039dc155ff6936f8f277d7e077b47e1c5ca4
1 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -unroll-count=4  -verify-dom-info -S | FileCheck %s
3 ; REQUIRES: asserts
4 ; The tests below are for verifying dom tree after runtime unrolling
5 ; with multiple exit/exiting blocks.
7 ; We explicitly set the unroll count so that expensiveTripCount computation is allowed.
9 ; mergedexit block has edges from loop exit blocks.
10 define i64 @test1() {
11 ; CHECK-LABEL: test1(
12 ; CHECK-LABEL: headerexit:
13 ; CHECK-NEXT:    %addphi = phi i64 [ %add.iv, %header ], [ %add.iv.1, %header.1 ], [ %add.iv.2, %header.2 ], [ %add.iv.3, %header.3 ]
14 ; CHECK-NEXT:    br label %mergedexit
15 ; CHECK-LABEL: latchexit:
16 ; CHECK-NEXT:    %shftphi = phi i64 [ %shft, %latch ], [ %shft.1, %latch.1 ], [ %shft.2, %latch.2 ], [ %shft.3, %latch.3 ]
17 ; CHECK-NEXT:    br label %mergedexit
18 ; CHECK-LABEL: mergedexit:
19 ; CHECK-NEXT:    %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ]
20 ; CHECK-NEXT:    ret i64 %retval
21 entry:
22   br label %preheader
24 preheader:                                              ; preds = %bb
25   %trip = zext i32 undef to i64
26   br label %header
28 header:                                              ; preds = %latch, %preheader
29   %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
30   %add.iv = add nuw nsw i64 %iv, 2
31   %cmp1 = icmp ult i64 %add.iv, %trip
32   br i1 %cmp1, label %latch, label %headerexit
34 latch:                                             ; preds = %header
35   %shft = ashr i64 %add.iv, 1
36   %cmp2 = icmp ult i64 %shft, %trip
37   br i1 %cmp2, label %header, label %latchexit
39 headerexit:                                              ; preds = %header
40   %addphi = phi i64 [ %add.iv, %header ]
41   br label %mergedexit
43 latchexit:                                              ; preds = %latch
44  %shftphi = phi i64 [ %shft, %latch ]
45   br label %mergedexit
47 mergedexit:                                              ; preds = %latchexit, %headerexit
48   %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ]
49   ret i64 %retval
52 ; mergedexit has edges from loop exit blocks and a block outside the loop.
53 define  void @test2(i1 %cond, i32 %n) {
54 ; CHECK-LABEL: header.1:
55 ; CHECK-NEXT:    %add.iv.1 = add nuw nsw i64 %add.iv, 2
56 ; CHECK:         br i1 %cmp1.1, label %latch.1, label %headerexit
57 ; CHECK-LABEL: latch.3:
58 ; CHECK:         %cmp2.3 = icmp ult i64 %shft.3, %trip
59 ; CHECK-NEXT:    br i1 %cmp2.3, label %header, label %latchexit, !llvm.loop
60 entry:
61   br i1 %cond, label %preheader, label %mergedexit
63 preheader:                                              ; preds = %entry
64   %trip = zext i32 %n to i64
65   br label %header
67 header:                                              ; preds = %latch, %preheader
68   %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
69   %add.iv = add nuw nsw i64 %iv, 2
70   %cmp1 = icmp ult i64 %add.iv, %trip
71   br i1 %cmp1, label %latch, label %headerexit
73 latch:                                             ; preds = %header
74   %shft = ashr i64 %add.iv, 1
75   %cmp2 = icmp ult i64 %shft, %trip
76   br i1 %cmp2, label %header, label %latchexit
78 headerexit:                                              ; preds = %header
79   br label %mergedexit
81 latchexit:                                              ; preds = %latch
82   br label %mergedexit
84 mergedexit:                                              ; preds = %latchexit, %headerexit, %entry
85   ret void
89 ; exitsucc is from loop exit block only.
90 define i64 @test3(i32 %n) {
91 ; CHECK-LABEL: test3(
92 ; CHECK-LABEL:  headerexit:
93 ; CHECK-NEXT:     br label %exitsucc
94 ; CHECK-LABEL:  latchexit:
95 ; CHECK-NEXT:     %shftphi = phi i64 [ %shft, %latch ], [ %shft.1, %latch.1 ], [ %shft.2, %latch.2 ], [ %shft.3, %latch.3 ]
96 ; CHECK-NEXT:     ret i64 %shftphi
97 ; CHECK-LABEL:  exitsucc:
98 ; CHECK-NEXT:     ret i64 96
99 entry:
100   br label %preheader
102 preheader:                                              ; preds = %bb
103   %trip = zext i32 %n to i64
104   br label %header
106 header:                                              ; preds = %latch, %preheader
107   %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
108   %add.iv = add nuw nsw i64 %iv, 2
109   %cmp1 = icmp ult i64 %add.iv, %trip
110   br i1 %cmp1, label %latch, label %headerexit
112 latch:                                             ; preds = %header
113   %shft = ashr i64 %add.iv, 1
114   %cmp2 = icmp ult i64 %shft, %trip
115   br i1 %cmp2, label %header, label %latchexit
117 headerexit:                                              ; preds = %header
118   br label %exitsucc
120 latchexit:                                              ; preds = %latch
121   %shftphi = phi i64 [ %shft, %latch ]
122   ret i64 %shftphi
124 exitsucc:                                              ; preds = %headerexit
125   ret i64 96
128 ; exit block (%default) has an exiting block and another exit block as predecessors.
129 define void @test4(i16 %c3) {
130 ; CHECK-LABEL: test4
132 ; CHECK-LABEL: exiting.prol:
133 ; CHECK-NEXT:   switch i16 %c3, label %default.loopexit.loopexit1 [
135 ; CHECK-LABEL: exiting:
136 ; CHECK-NEXT:   switch i16 %c3, label %default.loopexit.loopexit [
138 ; CHECK-LABEL: default.loopexit.loopexit:
139 ; CHECK-NEXT:   br label %default.loopexit
141 ; CHECK-LABEL: default.loopexit.loopexit1:
142 ; CHECK-NEXT:   br label %default.loopexit
144 ; CHECK-LABEL: default.loopexit:
145 ; CHECK-NEXT:   br label %default
146 preheader:
147   %c1 = zext i32 undef to i64
148   br label %header
150 header:                                       ; preds = %latch, %preheader
151   %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %latch ]
152   br label %exiting
154 exiting:                                           ; preds = %header
155   switch i16 %c3, label %default [
156     i16 45, label %otherexit
157     i16 95, label %latch
158   ]
160 latch:                                          ; preds = %exiting
161   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
162   %c2 = icmp ult i64 %indvars.iv.next, %c1
163   br i1 %c2, label %header, label %latchexit
165 latchexit:                                          ; preds = %latch
166   ret void
168 default:                                          ; preds = %otherexit, %exiting
169   ret void
171 otherexit:                                           ; preds = %exiting
172   br label %default
175 ; exit block (%exitB) has an exiting block and another exit block as predecessors.
176 ; exiting block comes from inner loop.
177 define void @test5() {
178 ; CHECK-LABEL: test5
179 ; CHECK-LABEL: bb1:
180 ; CHECK-NEXT:   br i1 false, label %outerH.prol.preheader, label %outerH.prol.loopexit
182 ; CHECK-LABEL: outerH.prol.preheader:
183 ; CHECK-NEXT:   br label %outerH.prol
185 ; CHECK-LABEL: outerH.prol:
186 ; CHECK-NEXT:   %tmp4.prol = phi i32 [ %tmp6.prol, %outerLatch.prol ], [ undef, %outerH.prol.preheader ]
187 ; CHECK-NEXT:   %prol.iter = phi i32 [ 0, %outerH.prol.preheader ], [ %prol.iter.sub, %outerLatch.prol ]
188 ; CHECK-NEXT:   br label %innerH.prol
190   %tmp = icmp sgt i32 undef, 79
191   br i1 %tmp, label %outerLatchExit, label %bb1
193 bb1:                                              ; preds = %bb
194   br label %outerH
196 outerH:                                              ; preds = %outerLatch, %bb1
197   %tmp4 = phi i32 [ %tmp6, %outerLatch ], [ undef, %bb1 ]
198   br label %innerH
200 innerH:                                              ; preds = %innerLatch, %outerH
201   br i1 undef, label %innerexiting, label %otherexitB
203 innerexiting:                                             ; preds = %innerH
204   br i1 undef, label %innerLatch, label %exitB
206 innerLatch:                                             ; preds = %innerexiting
207   %tmp13 = fcmp olt double undef, 2.000000e+00
208   br i1 %tmp13, label %innerH, label %outerLatch
210 outerLatch:                                              ; preds = %innerLatch
211   %tmp6 = add i32 %tmp4, 1
212   %tmp7 = icmp sgt i32 %tmp6, 79
213   br i1 %tmp7, label %outerLatchExit, label %outerH
215 outerLatchExit:                                              ; preds = %outerLatch, %bb
216   ret void
218 exitB:                                             ; preds = %innerexiting, %otherexitB
219   ret void
221 otherexitB:                                              ; preds = %innerH
222   br label %exitB
226 ; Blocks reachable from exits (not_zero44) have the IDom as the block within the loop (Header).
227 ; Update the IDom to the preheader.
228 define void @test6() {
229 ; CHECK-LABEL: test6
230 ; CHECK-LABEL: header.prol.preheader:
231 ; CHECK-NEXT:    br label %header.prol
233 ; CHECK-LABEL: header.prol:
234 ; CHECK-NEXT:    %indvars.iv.prol = phi i64 [ undef, %header.prol.preheader ], [ %indvars.iv.next.prol, %latch.prol ]
235 ; CHECK-NEXT:    %prol.iter = phi i64 [ 1, %header.prol.preheader ], [ %prol.iter.sub, %latch.prol ]
236 ; CHECK-NEXT:    br i1 false, label %latch.prol, label %otherexit.loopexit1
238 ; CHECK-LABEL: header.prol.loopexit.unr-lcssa:
239 ; CHECK-NEXT:    %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ]
240 ; CHECK-NEXT:    br label %header.prol.loopexit
242 ; CHECK-LABEL: header.prol.loopexit:
243 ; CHECK-NEXT:    %indvars.iv.unr = phi i64 [ undef, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ]
244 ; CHECK-NEXT:    br i1 true, label %latchexit, label %entry.new
246 ; CHECK-LABEL: entry.new:
247 ; CHECK-NEXT:    br label %header
248 entry:
249   br label %header
251 header:                                          ; preds = %latch, %entry
252   %indvars.iv = phi i64 [ undef, %entry ], [ %indvars.iv.next, %latch ]
253   br i1 undef, label %latch, label %otherexit
255 latch:                                         ; preds = %header
256   %indvars.iv.next = add nsw i64 %indvars.iv, 2
257   %0 = icmp slt i64 %indvars.iv.next, 616
258   br i1 %0, label %header, label %latchexit
260 latchexit:                                          ; preds = %latch
261   br label %latchexitsucc
263 otherexit:                                 ; preds = %header
264   br label %otherexitsucc
266 otherexitsucc:                                          ; preds = %otherexit
267   br label %not_zero44
269 not_zero44:                                       ; preds = %latchexitsucc, %otherexitsucc
270   unreachable
272 latchexitsucc:                                      ; preds = %latchexit
273   br label %not_zero44