blob: e70ff4156d35b4dc51851cc9728e70f6d541605f [file] [log] [blame]
John Brawn84b21832016-10-21 11:08:48 +00001; RUN: opt -S -loop-unroll < %s | FileCheck %s
2
3; Unroll twice, with first loop exit kept
4; CHECK-LABEL: @s32_max1
5; CHECK: do.body:
6; CHECK: store
7; CHECK: br i1 %cmp, label %do.body.1, label %do.end
8; CHECK: do.end:
9; CHECK: ret void
10; CHECK: do.body.1:
11; CHECK: store
12; CHECK: br label %do.end
13define void @s32_max1(i32 %n, i32* %p) {
14entry:
15 %add = add i32 %n, 1
16 br label %do.body
17
18do.body:
19 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
20 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
21 store i32 %i.0, i32* %arrayidx, align 4
22 %inc = add i32 %i.0, 1
23 %cmp = icmp slt i32 %i.0, %add
24 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
25
26do.end:
27 ret void
28}
29
30; Unroll thrice, with first loop exit kept
31; CHECK-LABEL: @s32_max2
32; CHECK: do.body:
33; CHECK: store
34; CHECK: br i1 %cmp, label %do.body.1, label %do.end
35; CHECK: do.end:
36; CHECK: ret void
37; CHECK: do.body.1:
38; CHECK: store
39; CHECK: store
40; CHECK: br label %do.end
41define void @s32_max2(i32 %n, i32* %p) {
42entry:
43 %add = add i32 %n, 2
44 br label %do.body
45
46do.body:
47 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
48 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
49 store i32 %i.0, i32* %arrayidx, align 4
50 %inc = add i32 %i.0, 1
51 %cmp = icmp slt i32 %i.0, %add
52 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
53
54do.end:
55 ret void
56}
57
58; Should not be unrolled
59; CHECK-LABEL: @s32_maxx
60; CHECK: do.body:
61; CHECK: do.end:
62; CHECK-NOT: do.body.1:
63define void @s32_maxx(i32 %n, i32 %x, i32* %p) {
64entry:
65 %add = add i32 %x, %n
66 br label %do.body
67
68do.body:
69 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
70 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
71 store i32 %i.0, i32* %arrayidx, align 4
72 %inc = add i32 %i.0, 1
73 %cmp = icmp slt i32 %i.0, %add
74 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
75
76do.end:
77 ret void
78}
79
80; Should not be unrolled
81; CHECK-LABEL: @s32_max2_unpredictable_exit
82; CHECK: do.body:
83; CHECK: do.end:
84; CHECK-NOT: do.body.1:
85define void @s32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
86entry:
87 %add = add i32 %n, 2
88 br label %do.body
89
90do.body:
91 %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
92 %cmp = icmp eq i32 %i.0, %x
93 br i1 %cmp, label %do.end, label %if.end ; unpredictable
94
95if.end:
96 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
97 store i32 %i.0, i32* %arrayidx, align 4
98 %inc = add i32 %i.0, 1
99 %cmp1 = icmp slt i32 %i.0, %add
100 br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
101
102do.end:
103 ret void
104}
105
106; Unroll twice, with first loop exit kept
107; CHECK-LABEL: @u32_max1
108; CHECK: do.body:
109; CHECK: store
110; CHECK: br i1 %cmp, label %do.body.1, label %do.end
111; CHECK: do.end:
112; CHECK: ret void
113; CHECK: do.body.1:
114; CHECK: store
115; CHECK: br label %do.end
116define void @u32_max1(i32 %n, i32* %p) {
117entry:
118 %add = add i32 %n, 1
119 br label %do.body
120
121do.body:
122 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
123 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
124 store i32 %i.0, i32* %arrayidx, align 4
125 %inc = add i32 %i.0, 1
126 %cmp = icmp ult i32 %i.0, %add
127 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
128
129do.end:
130 ret void
131}
132
133; Unroll thrice, with first loop exit kept
134; CHECK-LABEL: @u32_max2
135; CHECK: do.body:
136; CHECK: store
137; CHECK: br i1 %cmp, label %do.body.1, label %do.end
138; CHECK: do.end:
139; CHECK: ret void
140; CHECK: do.body.1:
141; CHECK: store
142; CHECK: store
143; CHECK: br label %do.end
144define void @u32_max2(i32 %n, i32* %p) {
145entry:
146 %add = add i32 %n, 2
147 br label %do.body
148
149do.body:
150 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
151 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
152 store i32 %i.0, i32* %arrayidx, align 4
153 %inc = add i32 %i.0, 1
154 %cmp = icmp ult i32 %i.0, %add
155 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
156
157do.end:
158 ret void
159}
160
161; Should not be unrolled
162; CHECK-LABEL: @u32_maxx
163; CHECK: do.body:
164; CHECK: do.end:
165; CHECK-NOT: do.body.1:
166define void @u32_maxx(i32 %n, i32 %x, i32* %p) {
167entry:
168 %add = add i32 %x, %n
169 br label %do.body
170
171do.body:
172 %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
173 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
174 store i32 %i.0, i32* %arrayidx, align 4
175 %inc = add i32 %i.0, 1
176 %cmp = icmp ult i32 %i.0, %add
177 br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
178
179do.end:
180 ret void
181}
182
183; Should not be unrolled
184; CHECK-LABEL: @u32_max2_unpredictable_exit
185; CHECK: do.body:
186; CHECK: do.end:
187; CHECK-NOT: do.body.1:
188define void @u32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
189entry:
190 %add = add i32 %n, 2
191 br label %do.body
192
193do.body:
194 %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
195 %cmp = icmp eq i32 %i.0, %x
196 br i1 %cmp, label %do.end, label %if.end ; unpredictable
197
198if.end:
199 %arrayidx = getelementptr i32, i32* %p, i32 %i.0
200 store i32 %i.0, i32* %arrayidx, align 4
201 %inc = add i32 %i.0, 1
202 %cmp1 = icmp ult i32 %i.0, %add
203 br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
204
205do.end:
206 ret void
207}