• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
2; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s
3
4; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
5; CHECK: irce: in function test_01u: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
6; CHECK-NOT: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
7; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
8; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
9; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
10; CHECK-NOT: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
11; CHECK: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
12; CHECK-NOT: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
13
14; Show that IRCE can turn 'ne' condition to 'slt' in increasing IV when the IV
15; can be negative at some point.
16define void @test_01(i32* %arr, i32* %a_len_ptr) #0 {
17
18; CHECK:      test_01
19; CHECK:        main.exit.selector:
20; CHECK-NEXT:     [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]
21; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 100
22; CHECK-NEXT:     br i1 [[COND]]
23
24entry:
25  %len = load i32, i32* %a_len_ptr, !range !0
26  br label %loop
27
28loop:
29  %idx = phi i32 [ -3, %entry ], [ %idx.next, %in.bounds ]
30  %idx.next = add i32 %idx, 1
31  %abc = icmp slt i32 %idx, %len
32  br i1 %abc, label %in.bounds, label %out.of.bounds
33
34in.bounds:
35  %addr = getelementptr i32, i32* %arr, i32 %idx
36  store i32 0, i32* %addr
37  %next = icmp ne i32 %idx.next, 100
38  br i1 %next, label %loop, label %exit
39
40out.of.bounds:
41  ret void
42
43exit:
44  ret void
45}
46
47; Show that IRCE can turn 'ne' condition to 'ult' in increasing IV when IV is
48; non-negative.
49define void @test_01u(i32* %arr, i32* %a_len_ptr) #0 {
50
51; CHECK:      test_01u
52; CHECK:        main.exit.selector:
53; CHECK-NEXT:     [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]
54; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 100
55; CHECK-NEXT:     br i1 [[COND]]
56
57entry:
58  %len = load i32, i32* %a_len_ptr, !range !0
59  br label %loop
60
61loop:
62  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
63  %idx.next = add i32 %idx, 1
64  %abc = icmp slt i32 %idx, %len
65  br i1 %abc, label %in.bounds, label %out.of.bounds
66
67in.bounds:
68  %addr = getelementptr i32, i32* %arr, i32 %idx
69  store i32 0, i32* %addr
70  %next = icmp ne i32 %idx.next, 100
71  br i1 %next, label %loop, label %exit
72
73out.of.bounds:
74  ret void
75
76exit:
77  ret void
78}
79
80; Show that if n is not known to be greater than the starting value, IRCE
81; doesn't apply.
82define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
83
84; CHECK: test_02(
85
86entry:
87  %len = load i32, i32* %a_len_ptr, !range !0
88  br label %loop
89
90loop:
91  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
92  %idx.next = add i32 %idx, 1
93  %abc = icmp slt i32 %idx, %len
94  br i1 %abc, label %in.bounds, label %out.of.bounds
95
96in.bounds:
97  %addr = getelementptr i32, i32* %arr, i32 %idx
98  store i32 0, i32* %addr
99  %next = icmp ne i32 %idx.next, -100
100  br i1 %next, label %loop, label %exit
101
102out.of.bounds:
103  ret void
104
105exit:
106  ret void
107}
108
109; Show that IRCE can turn 'eq' condition to 'sge' in increasing IV.
110define void @test_03(i32* %arr, i32* %a_len_ptr) #0 {
111
112; CHECK: test_03(
113; CHECK:        main.exit.selector:
114; CHECK-NEXT:     [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]
115; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 100
116; CHECK-NEXT:     br i1 [[COND]]
117
118entry:
119  %len = load i32, i32* %a_len_ptr, !range !0
120  br label %loop
121
122loop:
123  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
124  %idx.next = add i32 %idx, 1
125  %abc = icmp slt i32 %idx, %len
126  br i1 %abc, label %in.bounds, label %out.of.bounds
127
128in.bounds:
129  %addr = getelementptr i32, i32* %arr, i32 %idx
130  store i32 0, i32* %addr
131  %next = icmp eq i32 %idx.next, 100
132  br i1 %next, label %exit, label %loop
133
134out.of.bounds:
135  ret void
136
137exit:
138  ret void
139}
140
141define void @test_04(i32* %arr, i32* %a_len_ptr) #0 {
142
143entry:
144  %len = load i32, i32* %a_len_ptr, !range !0
145  br label %loop
146
147loop:
148  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
149  %idx.next = add i32 %idx, 1
150  %abc = icmp slt i32 %idx, %len
151  br i1 %abc, label %in.bounds, label %out.of.bounds
152
153in.bounds:
154  %addr = getelementptr i32, i32* %arr, i32 %idx
155  store i32 0, i32* %addr
156  %next = icmp eq i32 %idx.next, -100
157  br i1 %next, label %exit, label %loop
158
159out.of.bounds:
160  ret void
161
162exit:
163  ret void
164}
165
166; Show that IRCE can turn 'ne' condition to 'sgt' in decreasing IV.
167define void @test_05(i32* %arr, i32* %a_len_ptr) #0 {
168
169; CHECK: test_05(
170; CHECK:        preloop.exit.selector:
171; CHECK-NEXT:     [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]
172; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0
173; CHECK-NEXT:     br i1 [[COND]]
174
175entry:
176  %len = load i32, i32* %a_len_ptr, !range !0
177  br label %loop
178
179loop:
180  %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
181  %idx.next = add i32 %idx, -1
182  %abc = icmp slt i32 %idx, %len
183  br i1 %abc, label %in.bounds, label %out.of.bounds
184
185in.bounds:
186  %addr = getelementptr i32, i32* %arr, i32 %idx
187  store i32 0, i32* %addr
188  %next = icmp ne i32 %idx.next, 0
189  br i1 %next, label %loop, label %exit
190
191out.of.bounds:
192  ret void
193
194exit:
195  ret void
196}
197
198; Show that IRCE cannot turn 'ne' condition to 'sgt' in decreasing IV if the end
199; value is not proved to be less than the start value.
200define void @test_06(i32* %arr, i32* %a_len_ptr) #0 {
201
202; CHECK: test_06(
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
212  br i1 %abc, label %in.bounds, label %out.of.bounds
213
214in.bounds:
215  %addr = getelementptr i32, i32* %arr, i32 %idx
216  store i32 0, i32* %addr
217  %next = icmp ne i32 %idx.next, 120
218  br i1 %next, label %loop, label %exit
219
220out.of.bounds:
221  ret void
222
223exit:
224  ret void
225}
226
227; Show that IRCE can turn 'eq' condition to 'slt' in decreasing IV.
228define void @test_07(i32* %arr, i32* %a_len_ptr) #0 {
229
230; CHECK: test_07(
231; CHECK:        preloop.exit.selector:
232; CHECK-NEXT:     [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]
233; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0
234; CHECK-NEXT:     br i1 [[COND]]
235
236entry:
237  %len = load i32, i32* %a_len_ptr, !range !0
238  br label %loop
239
240loop:
241  %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
242  %idx.next = add i32 %idx, -1
243  %abc = icmp slt i32 %idx, %len
244  br i1 %abc, label %in.bounds, label %out.of.bounds
245
246in.bounds:
247  %addr = getelementptr i32, i32* %arr, i32 %idx
248  store i32 0, i32* %addr
249  %next = icmp eq i32 %idx.next, 0
250  br i1 %next, label %exit, label %loop
251
252out.of.bounds:
253  ret void
254
255exit:
256  ret void
257}
258
259; Show that IRCE cannot turn 'eq' condition to 'slt' in decreasing IV if the end
260; value is not proved to be less than the start value.
261define void @test_08(i32* %arr, i32* %a_len_ptr) #0 {
262
263; CHECK: test_08(
264
265entry:
266  %len = load i32, i32* %a_len_ptr, !range !0
267  br label %loop
268
269loop:
270  %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
271  %idx.next = add i32 %idx, -1
272  %abc = icmp slt i32 %idx, %len
273  br i1 %abc, label %in.bounds, label %out.of.bounds
274
275in.bounds:
276  %addr = getelementptr i32, i32* %arr, i32 %idx
277  store i32 0, i32* %addr
278  %next = icmp eq i32 %idx.next, 120
279  br i1 %next, label %exit, label %loop
280
281out.of.bounds:
282  ret void
283
284exit:
285  ret void
286}
287
288!0 = !{i32 0, i32 50}
289