[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / IndVarSimplify / post-inc-range.ll
blobd859eb28e78d59d33473b14fdd82a77b6dc1b62d
1 ; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s
3 target datalayout = "p:64:64:64-n32:64"
5 ; When the IV in this loop is widened we want to widen this use as well:
6 ; icmp slt i32 %i.inc, %limit
7 ; In order to do this indvars need to prove that the narrow IV def (%i.inc)
8 ; is not-negative from the range check inside of the loop.
9 define void @test(i32* %base, i32 %limit, i32 %start) {
10 ; CHECK-LABEL: @test(
11 ; CHECK-NOT: trunc
13 for.body.lr.ph:
14   br label %for.body
16 for.body:
17   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
18   %within_limits = icmp ult i32 %i, 64
19   br i1 %within_limits, label %continue, label %for.end
21 continue:
22   %i.i64 = zext i32 %i to i64
23   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
24   %val = load i32, i32* %arrayidx, align 4
25   br label %for.inc
27 for.inc:
28   %i.inc = add nsw nuw i32 %i, 1
29   %cmp = icmp slt i32 %i.inc, %limit
30   br i1 %cmp, label %for.body, label %for.end
32 for.end:
33   br label %exit
35 exit:
36   ret void
39 define void @test_false_edge(i32* %base, i32 %limit, i32 %start) {
40 ; CHECK-LABEL: @test_false_edge(
41 ; CHECK-NOT: trunc
43 for.body.lr.ph:
44   br label %for.body
46 for.body:
47   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
48   %out_of_bounds = icmp ugt i32 %i, 64
49   br i1 %out_of_bounds, label %for.end, label %continue
51 continue:
52   %i.i64 = zext i32 %i to i64
53   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
54   %val = load i32, i32* %arrayidx, align 4
55   br label %for.inc
57 for.inc:
58   %i.inc = add nsw nuw i32 %i, 1
59   %cmp = icmp slt i32 %i.inc, %limit
60   br i1 %cmp, label %for.body, label %for.end
62 for.end:
63   br label %exit
65 exit:
66   ret void
69 define void @test_range_metadata(i32* %array_length_ptr, i32* %base,
70                                  i32 %limit, i32 %start) {
71 ; CHECK-LABEL: @test_range_metadata(
72 ; CHECK-NOT: trunc
74 for.body.lr.ph:
75   br label %for.body
77 for.body:
78   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
79   %array_length = load i32, i32* %array_length_ptr, !range !{i32 0, i32 64 }
80   %within_limits = icmp ult i32 %i, %array_length
81   br i1 %within_limits, label %continue, label %for.end
83 continue:
84   %i.i64 = zext i32 %i to i64
85   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
86   %val = load i32, i32* %arrayidx, align 4
87   br label %for.inc
89 for.inc:
90   %i.inc = add nsw nuw i32 %i, 1
91   %cmp = icmp slt i32 %i.inc, %limit
92   br i1 %cmp, label %for.body, label %for.end
94 for.end:
95   br label %exit
97 exit:
98   ret void
101 ; Negative version of the test above, we don't know anything about
102 ; array_length_ptr range.
103 define void @test_neg(i32* %array_length_ptr, i32* %base,
104                       i32 %limit, i32 %start) {
105 ; CHECK-LABEL: @test_neg(
106 ; CHECK: trunc i64
108 for.body.lr.ph:
109   br label %for.body
111 for.body:
112   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
113   %array_length = load i32, i32* %array_length_ptr
114   %within_limits = icmp ult i32 %i, %array_length
115   br i1 %within_limits, label %continue, label %for.end
117 continue:
118   %i.i64 = zext i32 %i to i64
119   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
120   %val = load i32, i32* %arrayidx, align 4
121   br label %for.inc
123 for.inc:
124   %i.inc = add nsw nuw i32 %i, 1
125   %cmp = icmp slt i32 %i.inc, %limit
126   br i1 %cmp, label %for.body, label %for.end
128 for.end:
129   br label %exit
131 exit:
132   ret void
135 define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) {
136 ; CHECK-LABEL: @test_transitive_use(
137 ; CHECK-NOT: trunc
138 ; CHECK: %result = icmp slt i64
140 for.body.lr.ph:
141   br label %for.body
143 for.body:
144   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
145   %within_limits = icmp ult i32 %i, 64
146   br i1 %within_limits, label %continue, label %for.end
148 continue:
149   %i.mul.3 = mul nsw nuw i32 %i, 3
150   %mul_within = icmp ult i32 %i.mul.3, 64
151   br i1 %mul_within, label %guarded, label %continue.2
152   
153 guarded:
154   %i.mul.3.inc = add nsw nuw i32 %i.mul.3, 1
155   %result = icmp slt i32 %i.mul.3.inc, %limit
156   br i1 %result, label %continue.2, label %for.end
158 continue.2:
159   %i.i64 = zext i32 %i to i64
160   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
161   %val = load i32, i32* %arrayidx, align 4
162   br label %for.inc
164 for.inc:
165   %i.inc = add nsw nuw i32 %i, 1
166   %cmp = icmp slt i32 %i.inc, %limit
167   br i1 %cmp, label %for.body, label %for.end
170 for.end:
171   br label %exit
173 exit:
174   ret void
177 declare void @llvm.experimental.guard(i1, ...)
179 define void @test_guard_one_bb(i32* %base, i32 %limit, i32 %start) {
180 ; CHECK-LABEL: @test_guard_one_bb(
181 ; CHECK-NOT: trunc
182 ; CHECK-NOT: icmp slt i32
184 for.body.lr.ph:
185   br label %for.body
187 for.body:
188   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ]
189   %within_limits = icmp ult i32 %i, 64
190   %i.i64 = zext i32 %i to i64
191   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
192   %val = load i32, i32* %arrayidx, align 4
193   call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
194   %i.inc = add nsw nuw i32 %i, 1
195   %cmp = icmp slt i32 %i.inc, %limit
196   br i1 %cmp, label %for.body, label %for.end
198 for.end:
199   br label %exit
201 exit:
202   ret void
205 define void @test_guard_in_the_same_bb(i32* %base, i32 %limit, i32 %start) {
206 ; CHECK-LABEL: @test_guard_in_the_same_bb(
207 ; CHECK-NOT: trunc
208 ; CHECK-NOT: icmp slt i32
210 for.body.lr.ph:
211   br label %for.body
213 for.body:
214   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
215   %within_limits = icmp ult i32 %i, 64
216   %i.i64 = zext i32 %i to i64
217   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
218   %val = load i32, i32* %arrayidx, align 4
219   br label %for.inc
221 for.inc:
222   call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
223   %i.inc = add nsw nuw i32 %i, 1
224   %cmp = icmp slt i32 %i.inc, %limit
225   br i1 %cmp, label %for.body, label %for.end
227 for.end:
228   br label %exit
230 exit:
231   ret void
234 define void @test_guard_in_idom(i32* %base, i32 %limit, i32 %start) {
235 ; CHECK-LABEL: @test_guard_in_idom(
236 ; CHECK-NOT: trunc
237 ; CHECK-NOT: icmp slt i32
239 for.body.lr.ph:
240   br label %for.body
242 for.body:
243   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
244   %within_limits = icmp ult i32 %i, 64
245   call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
246   %i.i64 = zext i32 %i to i64
247   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
248   %val = load i32, i32* %arrayidx, align 4
249   br label %for.inc
251 for.inc:
252   %i.inc = add nsw nuw i32 %i, 1
253   %cmp = icmp slt i32 %i.inc, %limit
254   br i1 %cmp, label %for.body, label %for.end
256 for.end:
257   br label %exit
259 exit:
260   ret void
263 define void @test_guard_merge_ranges(i32* %base, i32 %limit, i32 %start) {
264 ; CHECK-LABEL: @test_guard_merge_ranges(
265 ; CHECK-NOT: trunc
266 ; CHECK-NOT: icmp slt i32
268 for.body.lr.ph:
269   br label %for.body
271 for.body:
272   %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ]
273   %within_limits.1 = icmp ult i32 %i, 64
274   call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.1) [ "deopt"() ]
275   %within_limits.2 = icmp ult i32 %i, 2147483647
276   call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.2) [ "deopt"() ]
277   %i.i64 = zext i32 %i to i64
278   %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
279   %val = load i32, i32* %arrayidx, align 4
280   %i.inc = add nsw nuw i32 %i, 1
281   %cmp = icmp slt i32 %i.inc, %limit
282   br i1 %cmp, label %for.body, label %for.end
284 for.end:
285   br label %exit
287 exit:
288   ret void