[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / full-unroll-keep-first-exit.ll
blobcaa59da17490c2fd2792eab1b812de5ee3bb1619
1 ; RUN: opt -S -loop-unroll < %s | FileCheck %s
2 ; RUN: opt -S -passes='require<opt-remark-emit>,loop(loop-unroll-full)' < %s | FileCheck %s
4 ; Unroll twice, with first loop exit kept
5 ; CHECK-LABEL: @s32_max1
6 ; CHECK: do.body:
7 ; CHECK:  store
8 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
9 ; CHECK: do.end:
10 ; CHECK:  ret void
11 ; CHECK: do.body.1:
12 ; CHECK:  store
13 ; CHECK:  br label %do.end
14 define void @s32_max1(i32 %n, i32* %p) {
15 entry:
16   %add = add i32 %n, 1
17   br label %do.body
19 do.body:
20   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
21   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
22   store i32 %i.0, i32* %arrayidx, align 4
23   %inc = add i32 %i.0, 1
24   %cmp = icmp slt i32 %i.0, %add
25   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
27 do.end:
28   ret void
31 ; Unroll thrice, with first loop exit kept
32 ; CHECK-LABEL: @s32_max2
33 ; CHECK: do.body:
34 ; CHECK:  store
35 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
36 ; CHECK: do.end:
37 ; CHECK:  ret void
38 ; CHECK: do.body.1:
39 ; CHECK:  store
40 ; CHECK:  store
41 ; CHECK:  br label %do.end
42 define void @s32_max2(i32 %n, i32* %p) {
43 entry:
44   %add = add i32 %n, 2
45   br label %do.body
47 do.body:
48   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
49   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
50   store i32 %i.0, i32* %arrayidx, align 4
51   %inc = add i32 %i.0, 1
52   %cmp = icmp slt i32 %i.0, %add
53   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
55 do.end:
56   ret void
59 ; Should not be unrolled
60 ; CHECK-LABEL: @s32_maxx
61 ; CHECK: do.body:
62 ; CHECK: do.end:
63 ; CHECK-NOT: do.body.1:
64 define void @s32_maxx(i32 %n, i32 %x, i32* %p) {
65 entry:
66   %add = add i32 %x, %n
67   br label %do.body
69 do.body:
70   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
71   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
72   store i32 %i.0, i32* %arrayidx, align 4
73   %inc = add i32 %i.0, 1
74   %cmp = icmp slt i32 %i.0, %add
75   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
77 do.end:
78   ret void
81 ; Should not be unrolled
82 ; CHECK-LABEL: @s32_max2_unpredictable_exit
83 ; CHECK: do.body:
84 ; CHECK: do.end:
85 ; CHECK-NOT: do.body.1:
86 define void @s32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
87 entry:
88   %add = add i32 %n, 2
89   br label %do.body
91 do.body:
92   %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
93   %cmp = icmp eq i32 %i.0, %x
94   br i1 %cmp, label %do.end, label %if.end ; unpredictable
96 if.end:
97   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
98   store i32 %i.0, i32* %arrayidx, align 4
99   %inc = add i32 %i.0, 1
100   %cmp1 = icmp slt i32 %i.0, %add
101   br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
103 do.end:
104   ret void
107 ; Unroll twice, with first loop exit kept
108 ; CHECK-LABEL: @u32_max1
109 ; CHECK: do.body:
110 ; CHECK:  store
111 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
112 ; CHECK: do.end:
113 ; CHECK:  ret void
114 ; CHECK: do.body.1:
115 ; CHECK:  store
116 ; CHECK:  br label %do.end
117 define void @u32_max1(i32 %n, i32* %p) {
118 entry:
119   %add = add i32 %n, 1
120   br label %do.body
122 do.body:
123   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
124   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
125   store i32 %i.0, i32* %arrayidx, align 4
126   %inc = add i32 %i.0, 1
127   %cmp = icmp ult i32 %i.0, %add
128   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
130 do.end:
131   ret void
134 ; Unroll thrice, with first loop exit kept
135 ; CHECK-LABEL: @u32_max2
136 ; CHECK: do.body:
137 ; CHECK:  store
138 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
139 ; CHECK: do.end:
140 ; CHECK:  ret void
141 ; CHECK: do.body.1:
142 ; CHECK:  store
143 ; CHECK:  store
144 ; CHECK:  br label %do.end
145 define void @u32_max2(i32 %n, i32* %p) {
146 entry:
147   %add = add i32 %n, 2
148   br label %do.body
150 do.body:
151   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
152   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
153   store i32 %i.0, i32* %arrayidx, align 4
154   %inc = add i32 %i.0, 1
155   %cmp = icmp ult i32 %i.0, %add
156   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
158 do.end:
159   ret void
162 ; Should not be unrolled
163 ; CHECK-LABEL: @u32_maxx
164 ; CHECK: do.body:
165 ; CHECK: do.end:
166 ; CHECK-NOT: do.body.1:
167 define void @u32_maxx(i32 %n, i32 %x, i32* %p) {
168 entry:
169   %add = add i32 %x, %n
170   br label %do.body
172 do.body:
173   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
174   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
175   store i32 %i.0, i32* %arrayidx, align 4
176   %inc = add i32 %i.0, 1
177   %cmp = icmp ult i32 %i.0, %add
178   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
180 do.end:
181   ret void
184 ; Should not be unrolled
185 ; CHECK-LABEL: @u32_max2_unpredictable_exit
186 ; CHECK: do.body:
187 ; CHECK: do.end:
188 ; CHECK-NOT: do.body.1:
189 define void @u32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
190 entry:
191   %add = add i32 %n, 2
192   br label %do.body
194 do.body:
195   %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
196   %cmp = icmp eq i32 %i.0, %x
197   br i1 %cmp, label %do.end, label %if.end ; unpredictable
199 if.end:
200   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
201   store i32 %i.0, i32* %arrayidx, align 4
202   %inc = add i32 %i.0, 1
203   %cmp1 = icmp ult i32 %i.0, %add
204   br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
206 do.end:
207   ret void