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>,loop(irce)' -S < %s 2>&1 | FileCheck %s
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>
14 ; Show that IRCE can turn 'ne' condition to 'slt' in increasing IV when the IV
15 ; can be negative at some point.
16 define void @test_01(i32* %arr, i32* %a_len_ptr) #0 {
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]]
25 %len = load i32, i32* %a_len_ptr, !range !0
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
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
47 ; Show that IRCE can turn 'ne' condition to 'ult' in increasing IV when IV is
49 define void @test_01u(i32* %arr, i32* %a_len_ptr) #0 {
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]]
58 %len = load i32, i32* %a_len_ptr, !range !0
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
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
80 ; Show that if n is not known to be greater than the starting value, IRCE
82 define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
87 %len = load i32, i32* %a_len_ptr, !range !0
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
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
109 ; Show that IRCE can turn 'eq' condition to 'sge' in increasing IV.
110 define void @test_03(i32* %arr, i32* %a_len_ptr) #0 {
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]]
119 %len = load i32, i32* %a_len_ptr, !range !0
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
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
141 define void @test_04(i32* %arr, i32* %a_len_ptr) #0 {
144 %len = load i32, i32* %a_len_ptr, !range !0
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
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
166 ; Show that IRCE can turn 'ne' condition to 'sgt' in decreasing IV.
167 define void @test_05(i32* %arr, i32* %a_len_ptr) #0 {
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]]
176 %len = load i32, i32* %a_len_ptr, !range !0
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
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
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.
200 define void @test_06(i32* %arr, i32* %a_len_ptr) #0 {
205 %len = load i32, i32* %a_len_ptr, !range !0
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
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
227 ; Show that IRCE can turn 'eq' condition to 'slt' in decreasing IV.
228 define void @test_07(i32* %arr, i32* %a_len_ptr) #0 {
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]]
237 %len = load i32, i32* %a_len_ptr, !range !0
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
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
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.
261 define void @test_08(i32* %arr, i32* %a_len_ptr) #0 {
266 %len = load i32, i32* %a_len_ptr, !range !0
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
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
288 !0 = !{i32 0, i32 50}