[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / ARM / multi-blocks.ll
blob7e8c55e7541cfd7fbaf794514fcc8cb4ec3f369e
1 ; RUN: opt -mtriple=thumbv8m.main -mcpu=cortex-m33 -loop-unroll -S < %s -o - | FileCheck %s
2 ; RUN: opt -mtriple=thumbv7em -mcpu=cortex-m7 -loop-unroll -S < %s -o - | FileCheck %s
4 ;CHECK-LABEL: test_three_blocks
5 ;CHECK: for.body.epil:
6 ;CHECK: if.then.epil:
7 ;CHECK: for.inc.epil:
8 ;CHECK: for.body:
9 ;CHECK: if.then:
10 ;CHECK: for.inc:
11 ;CHECK: for.body.epil.1:
12 ;CHECK: if.then.epil.1:
13 ;CHECK: for.inc.epil.1:
14 ;CHECK: for.body.epil.2:
15 ;CHECK: if.then.epil.2:
16 ;CHECK: for.inc.epil.2:
17 ;CHECK: if.then.1:
18 ;CHECK: for.inc.1:
19 ;CHECK: if.then.2:
20 ;CHECK: for.inc.2:
21 ;CHECK: if.then.3:
22 ;CHECK: for.inc.3:
23 define void @test_three_blocks(i32* nocapture %Output,
24                                i32* nocapture readonly %Condition,
25                                i32* nocapture readonly %Input,
26                                i32 %MaxJ) {
27 entry:
28   %cmp8 = icmp eq i32 %MaxJ, 0
29   br i1 %cmp8, label %for.cond.cleanup, label %for.body.preheader
31 for.body.preheader:                               ; preds = %entry
32   br label %for.body
34 for.cond.cleanup:                                 ; preds = %for.inc, %entry
35   %temp.0.lcssa = phi i32 [ 0, %entry ], [ %temp.1, %for.inc ]
36   store i32 %temp.0.lcssa, i32* %Output, align 4
37   ret void
39 for.body:                                         ; preds = %for.body.preheader, %for.inc
40   %j.010 = phi i32 [ %inc, %for.inc ], [ 0, %for.body.preheader ]
41   %temp.09 = phi i32 [ %temp.1, %for.inc ], [ 0, %for.body.preheader ]
42   %arrayidx = getelementptr inbounds i32, i32* %Condition, i32 %j.010
43   %0 = load i32, i32* %arrayidx, align 4
44   %tobool = icmp eq i32 %0, 0
45   br i1 %tobool, label %for.inc, label %if.then
47 if.then:                                          ; preds = %for.body
48   %arrayidx1 = getelementptr inbounds i32, i32* %Input, i32 %j.010
49   %1 = load i32, i32* %arrayidx1, align 4
50   %add = add i32 %1, %temp.09
51   br label %for.inc
53 for.inc:                                          ; preds = %for.body, %if.then
54   %temp.1 = phi i32 [ %add, %if.then ], [ %temp.09, %for.body ]
55   %inc = add nuw i32 %j.010, 1
56   %exitcond = icmp eq i32 %inc, %MaxJ
57   br i1 %exitcond, label %for.cond.cleanup, label %for.body
60 ;CHECK-LABEL: test_two_exits
61 ;CHECK: for.body:
62 ;CHECK: if.end:
63 ;CHECK: cleanup.loopexit:
64 ;CHECK: cleanup:
65 ;CHECK: for.body.1:
66 ;CHECK: if.end.1:
67 ;CHECK: for.body.2:
68 ;CHECK: if.end.2:
69 ;CHECK: for.body.3:
70 ;CHECK: if.end.3:
71 define void @test_two_exits(i32* nocapture %Output,
72                             i32* nocapture readonly %Condition,
73                             i32* nocapture readonly %Input,
74                             i32 %MaxJ) {
75 entry:
76   %cmp14 = icmp eq i32 %MaxJ, 0
77   br i1 %cmp14, label %cleanup, label %for.body.preheader
79 for.body.preheader:                               ; preds = %entry
80   br label %for.body
82 for.body:                                         ; preds = %for.body.preheader, %if.end
83   %j.016 = phi i32 [ %inc, %if.end ], [ 0, %for.body.preheader ]
84   %temp.015 = phi i32 [ %temp.0.add, %if.end ], [ 0, %for.body.preheader ]
85   %arrayidx = getelementptr inbounds i32, i32* %Input, i32 %j.016
86   %0 = load i32, i32* %arrayidx, align 4
87   %cmp1 = icmp ugt i32 %0, 65535
88   br i1 %cmp1, label %cleanup, label %if.end
90 if.end:                                           ; preds = %for.body
91   %arrayidx2 = getelementptr inbounds i32, i32* %Condition, i32 %j.016
92   %1 = load i32, i32* %arrayidx2, align 4
93   %tobool = icmp eq i32 %1, 0
94   %add = select i1 %tobool, i32 0, i32 %0
95   %temp.0.add = add i32 %add, %temp.015
96   %inc = add nuw i32 %j.016, 1
97   %cmp = icmp ult i32 %inc, %MaxJ
98   br i1 %cmp, label %for.body, label %cleanup
100 cleanup:                                          ; preds = %if.end, %for.body, %entry
101   %temp.0.lcssa = phi i32 [ 0, %entry ], [ %temp.015, %for.body ], [ %temp.0.add, %if.end ]
102   store i32 %temp.0.lcssa, i32* %Output, align 4
103   ret void
106 ;CHECK-LABEL: test_three_exits
107 ;CHECK-NOT: for.body.epil
108 ;CHECK-NOT: if.end.epil
109 ;CHECK-LABEL: for.body
110 ;CHECK-LABEL: if.end
111 ;CHECK-LABEL: if.end5
112 define void @test_three_exits(i32* nocapture %Output,
113                               i32* nocapture readonly %Condition,
114                               i32* nocapture readonly %Input,
115                               i32 %MaxJ) {
116 entry:
117   %cmp20 = icmp eq i32 %MaxJ, 0
118   br i1 %cmp20, label %cleanup, label %for.body.preheader
120 for.body.preheader:                               ; preds = %entry
121   br label %for.body
123 for.body:                                         ; preds = %for.body.preheader, %if.end5
124   %j.022 = phi i32 [ %inc, %if.end5 ], [ 0, %for.body.preheader ]
125   %temp.021 = phi i32 [ %temp.0.add, %if.end5 ], [ 0, %for.body.preheader ]
126   %arrayidx = getelementptr inbounds i32, i32* %Condition, i32 %j.022
127   %0 = load i32, i32* %arrayidx, align 4
128   %cmp1 = icmp ugt i32 %0, 65535
129   br i1 %cmp1, label %cleanup, label %if.end
131 if.end:                                           ; preds = %for.body
132   %arrayidx2 = getelementptr inbounds i32, i32* %Input, i32 %j.022
133   %1 = load i32, i32* %arrayidx2, align 4
134   %cmp3 = icmp ugt i32 %1, 65535
135   br i1 %cmp3, label %cleanup, label %if.end5
137 if.end5:                                          ; preds = %if.end
138   %tobool = icmp eq i32 %0, 0
139   %add = select i1 %tobool, i32 0, i32 %1
140   %temp.0.add = add i32 %add, %temp.021
141   %inc = add nuw i32 %j.022, 1
142   %cmp = icmp ult i32 %inc, %MaxJ
143   br i1 %cmp, label %for.body, label %cleanup
145 cleanup:                                          ; preds = %if.end5, %for.body, %if.end, %entry
146   %temp.0.lcssa = phi i32 [ 0, %entry ], [ %temp.021, %if.end ], [ %temp.021, %for.body ], [ %temp.0.add, %if.end5 ]
147   store i32 %temp.0.lcssa, i32* %Output, align 4
148   ret void
151 ;CHECK-LABEL: test_four_blocks
152 ;CHECK: for.body.epil:
153 ;CHECK: if.else.epil:
154 ;CHECK: if.then.epil:
155 ;CHECK: for.cond.cleanup:
156 ;CHECK: for.body:
157 ;CHECK: if.then:
158 ;CHECK: for.inc:
159 ;CHECK: for.body.epil.1:
160 ;CHECK: if.else.epil.1:
161 ;CHECK: if.then.epil.1:
162 ;CHECK: for.inc.epil.1:
163 ;CHECK: for.body.epil.2:
164 ;CHECK: if.else.epil.2:
165 ;CHECK: if.then.epil.2:
166 ;CHECK: for.inc.epil.2:
167 ;CHECK: if.else.1:
168 ;CHECK: if.then.1:
169 ;CHECK: for.inc.1:
170 ;CHECK: if.else.2:
171 ;CHECK: if.then.2:
172 ;CHECK: for.inc.2:
173 ;CHECK: if.else.3:
174 ;CHECK: if.then.3:
175 ;CHECK: for.inc.3:
176 define void @test_four_blocks(i32* nocapture %Output,
177                               i32* nocapture readonly %Condition,
178                               i32* nocapture readonly %Input,
179                               i32 %MaxJ) {
180 entry:
181   %cmp25 = icmp ugt i32 %MaxJ, 1
182   br i1 %cmp25, label %for.body.lr.ph, label %for.cond.cleanup
184 for.body.lr.ph:                                   ; preds = %entry
185   %.pre = load i32, i32* %Input, align 4
186   br label %for.body
188 for.cond.cleanup:                                 ; preds = %for.inc, %entry
189   %temp.0.lcssa = phi i32 [ 0, %entry ], [ %temp.1, %for.inc ]
190   store i32 %temp.0.lcssa, i32* %Output, align 4
191   ret void
193 for.body:                                         ; preds = %for.inc, %for.body.lr.ph
194   %0 = phi i32 [ %.pre, %for.body.lr.ph ], [ %2, %for.inc ]
195   %j.027 = phi i32 [ 1, %for.body.lr.ph ], [ %inc, %for.inc ]
196   %temp.026 = phi i32 [ 0, %for.body.lr.ph ], [ %temp.1, %for.inc ]
197   %arrayidx = getelementptr inbounds i32, i32* %Condition, i32 %j.027
198   %1 = load i32, i32* %arrayidx, align 4
199   %cmp1 = icmp ugt i32 %1, 65535
200   %arrayidx2 = getelementptr inbounds i32, i32* %Input, i32 %j.027
201   %2 = load i32, i32* %arrayidx2, align 4
202   %cmp4 = icmp ugt i32 %2, %0
203   br i1 %cmp1, label %if.then, label %if.else
205 if.then:                                          ; preds = %for.body
206   %cond = zext i1 %cmp4 to i32
207   %add = add i32 %temp.026, %cond
208   br label %for.inc
210 if.else:                                          ; preds = %for.body
211   %not.cmp4 = xor i1 %cmp4, true
212   %sub = sext i1 %not.cmp4 to i32
213   %sub10.sink = add i32 %j.027, %sub
214   %arrayidx11 = getelementptr inbounds i32, i32* %Input, i32 %sub10.sink
215   %3 = load i32, i32* %arrayidx11, align 4
216   %sub13 = sub i32 %temp.026, %3
217   br label %for.inc
219 for.inc:                                          ; preds = %if.then, %if.else
220   %temp.1 = phi i32 [ %add, %if.then ], [ %sub13, %if.else ]
221   %inc = add nuw i32 %j.027, 1
222   %exitcond = icmp eq i32 %inc, %MaxJ
223   br i1 %exitcond, label %for.cond.cleanup, label %for.body
226 ;CHECK-LABEL: test_five_blocks
227 ;CHECK-NOT: for.body.epil:
228 ;CHECK: for.body:
229 ;CHECK: if.end:
230 ;CHECK: if.else:
231 ;CHECK: for.inc:
232 ;CHECK-NOT: for.inc.1:
233 define void @test_five_blocks(i32* nocapture %Output,
234                               i32* nocapture readonly %Condition,
235                               i32* nocapture readonly %Input,
236                               i32 %MaxJ) {
237 entry:
238   %cmp24 = icmp ugt i32 %MaxJ, 1
239   br i1 %cmp24, label %for.body.preheader, label %cleanup
241 for.body.preheader:                               ; preds = %entry
242   br label %for.body
244 for.body:                                         ; preds = %for.body.preheader, %for.inc
245   %j.026 = phi i32 [ %inc, %for.inc ], [ 1, %for.body.preheader ]
246   %temp.025 = phi i32 [ %temp.1, %for.inc ], [ 0, %for.body.preheader ]
247   %arrayidx = getelementptr inbounds i32, i32* %Input, i32 %j.026
248   %0 = load i32, i32* %arrayidx, align 4
249   %add = add i32 %0, %temp.025
250   %cmp1 = icmp ugt i32 %add, 16777215
251   br i1 %cmp1, label %cleanup, label %if.end
253 if.end:                                           ; preds = %for.body
254   %arrayidx2 = getelementptr inbounds i32, i32* %Condition, i32 %j.026
255   %1 = load i32, i32* %arrayidx2, align 4
256   %cmp3 = icmp ugt i32 %1, 65535
257   br i1 %cmp3, label %if.then4, label %if.else
259 if.then4:                                         ; preds = %if.end
260   %sub = add i32 %j.026, -1
261   %arrayidx6 = getelementptr inbounds i32, i32* %Input, i32 %sub
262   %2 = load i32, i32* %arrayidx6, align 4
263   %cmp7 = icmp ugt i32 %0, %2
264   %cond = zext i1 %cmp7 to i32
265   %add8 = add i32 %add, %cond
266   br label %for.inc
268 if.else:                                          ; preds = %if.end
269   %and = and i32 %add, %0
270   br label %for.inc
272 for.inc:                                          ; preds = %if.then4, %if.else
273   %temp.1 = phi i32 [ %add8, %if.then4 ], [ %and, %if.else ]
274   %inc = add nuw i32 %j.026, 1
275   %cmp = icmp ult i32 %inc, %MaxJ
276   br i1 %cmp, label %for.body, label %cleanup
278 cleanup:                                          ; preds = %for.inc, %for.body, %entry
279   %temp.2 = phi i32 [ 0, %entry ], [ %add, %for.body ], [ %temp.1, %for.inc ]
280   store i32 %temp.2, i32* %Output, align 4
281   ret void
284 ;CHECK-LABEL: iterate_inc
285 ;CHECK: while.body:
286 ;CHECK: while.end:
287 ;CHECK: while.body.1:
288 ;CHECK: while.body.2:
289 ;CHECK: while.body.3:
290 %struct.Node = type { %struct.Node*, i32 }
291 define void @iterate_inc(%struct.Node* %n, i32 %limit) {
292 entry:
293   %tobool5 = icmp eq %struct.Node* %n, null
294   br i1 %tobool5, label %while.end, label %land.rhs.preheader
296 land.rhs.preheader:                               ; preds = %entry
297   br label %land.rhs
299 land.rhs:                                         ; preds = %land.rhs.preheader, %while.body
300   %list.addr.06 = phi %struct.Node* [ %2, %while.body ], [ %n, %land.rhs.preheader ]
301   %val = getelementptr inbounds %struct.Node, %struct.Node* %list.addr.06, i32 0, i32 1
302   %0 = load i32, i32* %val, align 4
303   %cmp = icmp slt i32 %0, %limit
304   br i1 %cmp, label %while.body, label %while.end
306 while.body:                                       ; preds = %land.rhs
307   %inc = add nsw i32 %0, 1
308   store i32 %inc, i32* %val, align 4
309   %1 = bitcast %struct.Node* %list.addr.06 to %struct.Node**
310   %2 = load %struct.Node*, %struct.Node** %1, align 4
311   %tobool = icmp eq %struct.Node* %2, null
312   br i1 %tobool, label %while.end, label %land.rhs
314 while.end:                                        ; preds = %land.rhs, %while.body, %entry
315   ret void