[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / IRCE / unsigned_comparisons_ugt.ll
blob117f5e5fa631bb18f2e054263754fe3082ba80ac
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_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
6 ; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
7 ; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
8 ; CHECK-NOT: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
9 ; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
11 ; UGT condition for increasing loop.
12 define void @test_01(i32* %arr, i32* %a_len_ptr) #0 {
14 ; CHECK: test_01(
15 ; CHECK:        entry:
16 ; CHECK-NEXT:     %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0
17 ; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at
18 ; CHECK-NEXT:     br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit
19 ; CHECK:        loop:
20 ; CHECK-NEXT:     %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ]
21 ; CHECK-NEXT:     %idx.next = add nuw nsw i32 %idx, 1
22 ; CHECK-NEXT:     %abc = icmp ult i32 %idx, %exit.mainloop.at
23 ; CHECK-NEXT:     br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
24 ; CHECK-NOT:    loop.preloop:
25 ; CHECK:        loop.postloop:
26 ; CHECK-NEXT:     %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ]
27 ; CHECK-NEXT:     %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1
28 ; CHECK-NEXT:     %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at
29 ; CHECK-NEXT:     br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit
31 entry:
32   %len = load i32, i32* %a_len_ptr, !range !0
33   br label %loop
35 loop:
36   %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
37   %idx.next = add nsw nuw i32 %idx, 1
38   %abc = icmp ult i32 %idx, %len
39   br i1 %abc, label %in.bounds, label %out.of.bounds
41 in.bounds:
42   %addr = getelementptr i32, i32* %arr, i32 %idx
43   store i32 0, i32* %addr
44   %next = icmp ugt i32 %idx.next, 100
45   br i1 %next, label %exit, label %loop
47 out.of.bounds:
48   ret void
50 exit:
51   ret void
54 ; UGT condition for decreasing loop.
55 define void @test_02(i32* %arr, i32* %a_len_ptr) #0 {
57 ; CHECK: test_02(
58 ; CHECK:        entry:
59 ; CHECK-NEXT:     %len = load i32, i32* %a_len_ptr, !range !0
60 ; CHECK-NEXT:     [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1
61 ; CHECK-NEXT:     [[UMIN:%[^ ]+]] = select i1 [[COND1]], i32 %len, i32 1
62 ; CHECK-NEXT:     %exit.preloop.at = add nsw i32 [[UMIN]], -1
63 ; CHECK-NEXT:     [[COND2:%[^ ]+]] = icmp ugt i32 100, %exit.preloop.at
64 ; CHECK-NEXT:     br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit
65 ; CHECK:        mainloop:
66 ; CHECK-NEXT:     br label %loop
67 ; CHECK:        loop:
68 ; CHECK-NEXT:     %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ]
69 ; CHECK-NEXT:     %idx.next = add i32 %idx, -1
70 ; CHECK-NEXT:     %abc = icmp ult i32 %idx, %len
71 ; CHECK-NEXT:     br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
72 ; CHECK-NOT:    loop.postloop:
73 ; CHECK:        loop.preloop:
74 ; CHECK-NEXT:     %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 100, %loop.preloop.preheader ]
75 ; CHECK-NEXT:     %idx.next.preloop = add i32 %idx.preloop, -1
76 ; CHECK-NEXT:     %abc.preloop = icmp ult i32 %idx.preloop, %len
77 ; CHECK-NEXT:     br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit
79 entry:
80   %len = load i32, i32* %a_len_ptr, !range !0
81   br label %loop
83 loop:
84   %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]
85   %idx.next = add i32 %idx, -1
86   %abc = icmp ult i32 %idx, %len
87   br i1 %abc, label %in.bounds, label %out.of.bounds
89 in.bounds:
90   %addr = getelementptr i32, i32* %arr, i32 %idx
91   store i32 0, i32* %addr
92   %next = icmp ugt i32 %idx.next, 0
93   br i1 %next, label %loop, label %exit
95 out.of.bounds:
96   ret void
98 exit:
99   ret void
102 ; Check SINT_MAX + 1, test is similar to test_01.
103 define void @test_03(i32* %arr, i32* %a_len_ptr) #0 {
105 ; CHECK: test_03(
106 ; CHECK:        entry:
107 ; CHECK-NEXT:     %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0
108 ; CHECK-NEXT:     [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at
109 ; CHECK-NEXT:     br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit
110 ; CHECK:        loop:
111 ; CHECK-NEXT:     %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ]
112 ; CHECK-NEXT:     %idx.next = add nuw nsw i32 %idx, 1
113 ; CHECK-NEXT:     %abc = icmp ult i32 %idx, %exit.mainloop.at
114 ; CHECK-NEXT:     br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
115 ; CHECK-NOT:    loop.preloop:
116 ; CHECK:        loop.postloop:
117 ; CHECK-NEXT:     %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ]
118 ; CHECK-NEXT:     %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1
119 ; CHECK-NEXT:     %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at
120 ; CHECK-NEXT:     br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit
122 entry:
123   %len = load i32, i32* %a_len_ptr, !range !0
124   br label %loop
126 loop:
127   %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
128   %idx.next = add nsw nuw i32 %idx, 1
129   %abc = icmp ult i32 %idx, %len
130   br i1 %abc, label %in.bounds, label %out.of.bounds
132 in.bounds:
133   %addr = getelementptr i32, i32* %arr, i32 %idx
134   store i32 0, i32* %addr
135   %next = icmp ugt i32 %idx.next, 2147483648
136   br i1 %next, label %exit, label %loop
138 out.of.bounds:
139   ret void
141 exit:
142   ret void
145 ; Check SINT_MAX + 1, test is similar to test_02.
146 define void @test_04(i32* %arr, i32* %a_len_ptr) #0 {
148 ; CHECK: test_04(
149 ; CHECK:        entry:
150 ; CHECK-NEXT:     %len = load i32, i32* %a_len_ptr, !range !0
151 ; CHECK-NEXT:     [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1
152 ; CHECK-NEXT:     [[UMIN:%[^ ]+]] = select i1 [[COND1]], i32 %len, i32 1
153 ; CHECK-NEXT:     %exit.preloop.at = add nsw i32 [[UMIN]], -1
154 ; CHECK-NEXT:     [[COND2:%[^ ]+]] = icmp ugt i32 -2147483648, %exit.preloop.at
155 ; CHECK-NEXT:     br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit
156 ; CHECK:        mainloop:
157 ; CHECK-NEXT:     br label %loop
158 ; CHECK:        loop:
159 ; CHECK-NEXT:     %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ]
160 ; CHECK-NEXT:     %idx.next = add i32 %idx, -1
161 ; CHECK-NEXT:     %abc = icmp ult i32 %idx, %len
162 ; CHECK-NEXT:     br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
163 ; CHECK-NOT:    loop.postloop:
164 ; CHECK:        loop.preloop:
165 ; CHECK-NEXT:     %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ -2147483648, %loop.preloop.preheader ]
166 ; CHECK-NEXT:     %idx.next.preloop = add i32 %idx.preloop, -1
167 ; CHECK-NEXT:     %abc.preloop = icmp ult i32 %idx.preloop, %len
168 ; CHECK-NEXT:     br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit
170 entry:
171   %len = load i32, i32* %a_len_ptr, !range !0
172   br label %loop
174 loop:
175   %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ]
176   %idx.next = add i32 %idx, -1
177   %abc = icmp ult i32 %idx, %len
178   br i1 %abc, label %in.bounds, label %out.of.bounds
180 in.bounds:
181   %addr = getelementptr i32, i32* %arr, i32 %idx
182   store i32 0, i32* %addr
183   %next = icmp ugt i32 %idx.next, 0
184   br i1 %next, label %loop, label %exit
186 out.of.bounds:
187   ret void
189 exit:
190   ret void
193 ; Increasing loop, UINT_MAX. Negative test: we cannot add 1 to UINT_MAX.
194 define void @test_05(i32* %arr, i32* %a_len_ptr) #0 {
196 ; CHECK: test_05(
197 ; CHECK-NOT:    loop.preloop:
198 ; CHECK-NOT:    loop.postloop:
200 entry:
201   %len = load i32, i32* %a_len_ptr, !range !0
202   br label %loop
204 loop:
205   %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
206   %idx.next = add nsw nuw i32 %idx, 1
207   %abc = icmp ult i32 %idx, %len
208   br i1 %abc, label %in.bounds, label %out.of.bounds
210 in.bounds:
211   %addr = getelementptr i32, i32* %arr, i32 %idx
212   store i32 0, i32* %addr
213   %next = icmp ugt i32 %idx.next, 4294967295
214   br i1 %next, label %exit, label %loop
216 out.of.bounds:
217   ret void
219 exit:
220   ret void
223 ; Decreasing loop, UINT_MAX. Positive test.
224 define void @test_06(i32* %arr, i32* %a_len_ptr) #0 {
226 ; CHECK: test_06(
227 ; CHECK:        mainloop:
228 ; CHECK-NEXT:     br label %loop
229 ; CHECK:        loop:
230 ; CHECK-NEXT:     %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ]
231 ; CHECK-NEXT:     %idx.next = add nuw i32 %idx, -1
232 ; CHECK-NEXT:     %abc = icmp ult i32 %idx, %len
233 ; CHECK-NEXT:     br i1 true, label %in.bounds, label %out.of.bounds.loopexit1
234 ; CHECK-NOT:    loop.postloop:
235 ; CHECK:        loop.preloop:
236 ; CHECK-NEXT:     %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ -1, %loop.preloop.preheader ]
237 ; CHECK-NEXT:     %idx.next.preloop = add nuw i32 %idx.preloop, -1
238 ; CHECK-NEXT:     %abc.preloop = icmp ult i32 %idx.preloop, %len
239 ; CHECK-NEXT:     br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit
241 entry:
242   %len = load i32, i32* %a_len_ptr, !range !0
243   br label %loop
245 loop:
246   %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ]
247   %idx.next = add nuw i32 %idx, -1
248   %abc = icmp ult i32 %idx, %len
249   br i1 %abc, label %in.bounds, label %out.of.bounds
251 in.bounds:
252   %addr = getelementptr i32, i32* %arr, i32 %idx
253   store i32 0, i32* %addr
254   %next = icmp ugt i32 %idx.next, 0
255   br i1 %next, label %loop, label %exit
257 out.of.bounds:
258   ret void
260 exit:
261   ret void
264 !0 = !{i32 0, i32 50}