[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / IRCE / eq_ne.ll
blob290c1cb823e6b2ebb21e73ef67e26ad32452c6b9
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 {
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]]
24 entry:
25   %len = load i32, i32* %a_len_ptr, !range !0
26   br label %loop
28 loop:
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
34 in.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
40 out.of.bounds:
41   ret void
43 exit:
44   ret void
47 ; Show that IRCE can turn 'ne' condition to 'ult' in increasing IV when IV is
48 ; non-negative.
49 define void @test_01u(i32* %arr, i32* %a_len_ptr) #0 {
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]]
57 entry:
58   %len = load i32, i32* %a_len_ptr, !range !0
59   br label %loop
61 loop:
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
67 in.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
73 out.of.bounds:
74   ret void
76 exit:
77   ret void
80 ; Show that if n is not known to be greater than the starting value, IRCE
81 ; doesn't apply.
82 define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
84 ; CHECK: test_02(
86 entry:
87   %len = load i32, i32* %a_len_ptr, !range !0
88   br label %loop
90 loop:
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
96 in.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
102 out.of.bounds:
103   ret void
105 exit:
106   ret void
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 {
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]]
118 entry:
119   %len = load i32, i32* %a_len_ptr, !range !0
120   br label %loop
122 loop:
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
128 in.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
134 out.of.bounds:
135   ret void
137 exit:
138   ret void
141 define void @test_04(i32* %arr, i32* %a_len_ptr) #0 {
143 entry:
144   %len = load i32, i32* %a_len_ptr, !range !0
145   br label %loop
147 loop:
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
153 in.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
159 out.of.bounds:
160   ret void
162 exit:
163   ret void
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 {
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]]
175 entry:
176   %len = load i32, i32* %a_len_ptr, !range !0
177   br label %loop
179 loop:
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
185 in.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
191 out.of.bounds:
192   ret void
194 exit:
195   ret void
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 {
202 ; CHECK: test_06(
204 entry:
205   %len = load i32, i32* %a_len_ptr, !range !0
206   br label %loop
208 loop:
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
214 in.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
220 out.of.bounds:
221   ret void
223 exit:
224   ret void
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 {
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]]
236 entry:
237   %len = load i32, i32* %a_len_ptr, !range !0
238   br label %loop
240 loop:
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
246 in.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
252 out.of.bounds:
253   ret void
255 exit:
256   ret void
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 {
263 ; CHECK: test_08(
265 entry:
266   %len = load i32, i32* %a_len_ptr, !range !0
267   br label %loop
269 loop:
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
275 in.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
281 out.of.bounds:
282   ret void
284 exit:
285   ret void
288 !0 = !{i32 0, i32 50}