blob: 682d1b35c1fae3b24b3d6c27e0094c2e50160653 [file] [log] [blame]
John Brawn84b21832016-10-21 11:08:48 +00001; RUN: opt -S -loop-unroll < %s | FileCheck %s
Chandler Carrutheab3b902017-01-26 02:13:50 +00002; RUN: opt -S -passes='require<opt-remark-emit>,loop(unroll-full)' < %s | FileCheck %s
John Brawn84b21832016-10-21 11:08:48 +00003
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
14define void @s32_max1(i32 %n, i32* %p) {
15entry:
16 %add = add i32 %n, 1
17 br label %do.body
18
19do.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
26
27do.end:
28 ret void
29}
30
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
42define void @s32_max2(i32 %n, i32* %p) {
43entry:
44 %add = add i32 %n, 2
45 br label %do.body
46
47do.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
54
55do.end:
56 ret void
57}
58
59; Should not be unrolled
60; CHECK-LABEL: @s32_maxx
61; CHECK: do.body:
62; CHECK: do.end:
63; CHECK-NOT: do.body.1:
64define void @s32_maxx(i32 %n, i32 %x, i32* %p) {
65entry:
66 %add = add i32 %x, %n
67 br label %do.body
68
69do.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
76
77do.end:
78 ret void
79}
80
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:
86define void @s32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
87entry:
88 %add = add i32 %n, 2
89 br label %do.body
90
91do.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
95
96if.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
102
103do.end:
104 ret void
105}
106
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
117define void @u32_max1(i32 %n, i32* %p) {
118entry:
119 %add = add i32 %n, 1
120 br label %do.body
121
122do.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
129
130do.end:
131 ret void
132}
133
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
145define void @u32_max2(i32 %n, i32* %p) {
146entry:
147 %add = add i32 %n, 2
148 br label %do.body
149
150do.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
157
158do.end:
159 ret void
160}
161
162; Should not be unrolled
163; CHECK-LABEL: @u32_maxx
164; CHECK: do.body:
165; CHECK: do.end:
166; CHECK-NOT: do.body.1:
167define void @u32_maxx(i32 %n, i32 %x, i32* %p) {
168entry:
169 %add = add i32 %x, %n
170 br label %do.body
171
172do.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
179
180do.end:
181 ret void
182}
183
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:
189define void @u32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
190entry:
191 %add = add i32 %n, 2
192 br label %do.body
193
194do.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
198
199if.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
205
206do.end:
207 ret void
208}