blob: 0090429114871e0dcc918d52e7c8b85d369dab47 [file] [log] [blame]
Max Kazantsev2c627a92017-07-18 04:53:48 +00001; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
2
3; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
4; CHECK-NOT: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
5; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
6; CHECK-NOT: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
7; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
8; CHECK-NOT: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
9; CHECK: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
10; CHECK-NOT: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
11
12; Show that IRCE can turn 'ne' condition to 'slt' in increasing IV.
13define void @test_01(i32* %arr, i32* %a_len_ptr) #0 {
14
15; CHECK: test_01
16; CHECK: main.exit.selector:
17; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]
18; CHECK-NEXT: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 100
19; CHECK-NEXT: br i1 [[COND]]
20
21entry:
22 %len = load i32, i32* %a_len_ptr, !range !0
23 br label %loop
24
25loop:
26 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
27 %idx.next = add i32 %idx, 1
28 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +000029 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +000030
31in.bounds:
32 %addr = getelementptr i32, i32* %arr, i32 %idx
33 store i32 0, i32* %addr
34 %next = icmp ne i32 %idx.next, 100
35 br i1 %next, label %loop, label %exit
36
37out.of.bounds:
38 ret void
39
40exit:
41 ret void
42}
43
44; Show that if n is not known to be greater than the starting value, IRCE
45; doesn't apply.
46define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
47
48; CHECK: test_02(
49
50entry:
51 %len = load i32, i32* %a_len_ptr, !range !0
52 br label %loop
53
54loop:
55 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
56 %idx.next = add i32 %idx, 1
57 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +000058 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +000059
60in.bounds:
61 %addr = getelementptr i32, i32* %arr, i32 %idx
62 store i32 0, i32* %addr
63 %next = icmp ne i32 %idx.next, -100
64 br i1 %next, label %loop, label %exit
65
66out.of.bounds:
67 ret void
68
69exit:
70 ret void
71}
72
73; Show that IRCE can turn 'eq' condition to 'sge' in increasing IV.
74define void @test_03(i32* %arr, i32* %a_len_ptr) #0 {
75
76; CHECK: test_03(
77; CHECK: main.exit.selector:
78; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]
79; CHECK-NEXT: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 100
80; CHECK-NEXT: br i1 [[COND]]
81
82entry:
83 %len = load i32, i32* %a_len_ptr, !range !0
84 br label %loop
85
86loop:
87 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
88 %idx.next = add i32 %idx, 1
89 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +000090 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +000091
92in.bounds:
93 %addr = getelementptr i32, i32* %arr, i32 %idx
94 store i32 0, i32* %addr
95 %next = icmp eq i32 %idx.next, 100
96 br i1 %next, label %exit, label %loop
97
98out.of.bounds:
99 ret void
100
101exit:
102 ret void
103}
104
105; Show that if n is not known to be greater than the starting value, IRCE
106; doesn't apply.
107define void @test_04(i32* %arr, i32* %a_len_ptr) #0 {
108
109; CHECK: test_04(
110
111entry:
112 %len = load i32, i32* %a_len_ptr, !range !0
113 br label %loop
114
115loop:
116 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
117 %idx.next = add i32 %idx, 1
118 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +0000119 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +0000120
121in.bounds:
122 %addr = getelementptr i32, i32* %arr, i32 %idx
123 store i32 0, i32* %addr
124 %next = icmp eq i32 %idx.next, -100
125 br i1 %next, label %exit, label %loop
126
127out.of.bounds:
128 ret void
129
130exit:
131 ret void
132}
133
134; Show that IRCE can turn 'ne' condition to 'sgt' in decreasing IV.
135define void @test_05(i32* %arr, i32* %a_len_ptr) #0 {
136
137; CHECK: test_05(
138; CHECK: preloop.exit.selector:
139; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]
140; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0
141; CHECK-NEXT: br i1 [[COND]]
142
143entry:
144 %len = load i32, i32* %a_len_ptr, !range !0
145 br label %loop
146
147loop:
148 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
149 %idx.next = add i32 %idx, -1
150 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +0000151 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +0000152
153in.bounds:
154 %addr = getelementptr i32, i32* %arr, i32 %idx
155 store i32 0, i32* %addr
156 %next = icmp ne i32 %idx.next, 0
157 br i1 %next, label %loop, label %exit
158
159out.of.bounds:
160 ret void
161
162exit:
163 ret void
164}
165
166; Show that IRCE cannot turn 'ne' condition to 'sgt' in decreasing IV if the end
167; value is not proved to be less than the start value.
168define void @test_06(i32* %arr, i32* %a_len_ptr) #0 {
169
170; CHECK: test_06(
171
172entry:
173 %len = load i32, i32* %a_len_ptr, !range !0
174 br label %loop
175
176loop:
177 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
178 %idx.next = add i32 %idx, -1
179 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +0000180 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +0000181
182in.bounds:
183 %addr = getelementptr i32, i32* %arr, i32 %idx
184 store i32 0, i32* %addr
185 %next = icmp ne i32 %idx.next, 120
186 br i1 %next, label %loop, label %exit
187
188out.of.bounds:
189 ret void
190
191exit:
192 ret void
193}
194
195; Show that IRCE can turn 'eq' condition to 'slt' in decreasing IV.
196define void @test_07(i32* %arr, i32* %a_len_ptr) #0 {
197
198; CHECK: test_07(
199; CHECK: preloop.exit.selector:
200; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]
201; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0
202; CHECK-NEXT: br i1 [[COND]]
203
204entry:
205 %len = load i32, i32* %a_len_ptr, !range !0
206 br label %loop
207
208loop:
209 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
210 %idx.next = add i32 %idx, -1
211 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +0000212 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +0000213
214in.bounds:
215 %addr = getelementptr i32, i32* %arr, i32 %idx
216 store i32 0, i32* %addr
217 %next = icmp eq i32 %idx.next, 0
218 br i1 %next, label %exit, label %loop
219
220out.of.bounds:
221 ret void
222
223exit:
224 ret void
225}
226
227; Show that IRCE cannot turn 'eq' condition to 'slt' in decreasing IV if the end
228; value is not proved to be less than the start value.
229define void @test_08(i32* %arr, i32* %a_len_ptr) #0 {
230
231; CHECK: test_08(
232
233entry:
234 %len = load i32, i32* %a_len_ptr, !range !0
235 br label %loop
236
237loop:
238 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
239 %idx.next = add i32 %idx, -1
240 %abc = icmp slt i32 %idx, %len
Max Kazantsevd18b0192017-08-01 10:13:29 +0000241 br i1 %abc, label %in.bounds, label %out.of.bounds
Max Kazantsev2c627a92017-07-18 04:53:48 +0000242
243in.bounds:
244 %addr = getelementptr i32, i32* %arr, i32 %idx
245 store i32 0, i32* %addr
246 %next = icmp eq i32 %idx.next, 120
247 br i1 %next, label %exit, label %loop
248
249out.of.bounds:
250 ret void
251
252exit:
253 ret void
254}
255
256!0 = !{i32 0, i32 50}