xref: /llvm-project/llvm/test/Transforms/LoopStrengthReduce/RISCV/icmp-zero.ll (revision 6ab686eb86fb60ab63750dddd575ac92d8a1f9f9)
1ddd4ed99SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2ddd4ed99SPhilip Reames; RUN: opt < %s -loop-reduce -S | FileCheck %s
3ddd4ed99SPhilip Reames
4ddd4ed99SPhilip Reamestarget datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
5ddd4ed99SPhilip Reamestarget triple = "riscv64"
6ddd4ed99SPhilip Reames
7ddd4ed99SPhilip Reames
8ddd4ed99SPhilip Reamesdefine void @icmp_zero(i64 %N, ptr %p) {
9ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero(
10ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
11ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
12ddd4ed99SPhilip Reames; CHECK:       vector.body:
13ddd4ed99SPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[N:%.*]], [[ENTRY:%.*]] ]
14ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
15ddd4ed99SPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
16ddd4ed99SPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
17ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
18ddd4ed99SPhilip Reames; CHECK:       exit:
19ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
20ddd4ed99SPhilip Reames;
21ddd4ed99SPhilip Reamesentry:
22ddd4ed99SPhilip Reames  br label %vector.body
23ddd4ed99SPhilip Reames
24ddd4ed99SPhilip Reamesvector.body:
25ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
26ddd4ed99SPhilip Reames  store i64 0, ptr %p
27ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
28ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %N
29ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
30ddd4ed99SPhilip Reames
31ddd4ed99SPhilip Reamesexit:
32ddd4ed99SPhilip Reames  ret void
33ddd4ed99SPhilip Reames}
34ddd4ed99SPhilip Reames
35ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nonzero_con(i64 %N, ptr %p) {
36ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nonzero_con(
37ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
38ddd4ed99SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], 16
39ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
40ddd4ed99SPhilip Reames; CHECK:       vector.body:
41ddd4ed99SPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
42ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
43ddd4ed99SPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
44ddd4ed99SPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
45ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
46ddd4ed99SPhilip Reames; CHECK:       exit:
47ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
48ddd4ed99SPhilip Reames;
49ddd4ed99SPhilip Reamesentry:
50ddd4ed99SPhilip Reames  %urem = urem i64 %N, 16
51ddd4ed99SPhilip Reames  br label %vector.body
52ddd4ed99SPhilip Reames
53ddd4ed99SPhilip Reamesvector.body:
54ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
55ddd4ed99SPhilip Reames  store i64 0, ptr %p
56ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
57ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
58ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
59ddd4ed99SPhilip Reames
60ddd4ed99SPhilip Reamesexit:
61ddd4ed99SPhilip Reames  ret void
62ddd4ed99SPhilip Reames}
63ddd4ed99SPhilip Reames
64ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_invariant(i64 %N, i64 %M, ptr %p) {
65ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_invariant(
66ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
67ddd4ed99SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]]
68ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
69ddd4ed99SPhilip Reames; CHECK:       vector.body:
70*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
71ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
72*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
73*6ab686ebSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
74ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
75ddd4ed99SPhilip Reames; CHECK:       exit:
76ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
77ddd4ed99SPhilip Reames;
78ddd4ed99SPhilip Reamesentry:
79ddd4ed99SPhilip Reames  %urem = urem i64 %N, %M
80ddd4ed99SPhilip Reames  br label %vector.body
81ddd4ed99SPhilip Reames
82ddd4ed99SPhilip Reamesvector.body:
83ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
84ddd4ed99SPhilip Reames  store i64 0, ptr %p
85ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
86ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
87ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
88ddd4ed99SPhilip Reames
89ddd4ed99SPhilip Reamesexit:
90ddd4ed99SPhilip Reames  ret void
91ddd4ed99SPhilip Reames}
92ddd4ed99SPhilip Reames
93d767b392SPhilip Reames; We have to be careful here as SCEV can only compute a subtraction from
94d767b392SPhilip Reames; two pointers with the same base.  If we hide %end inside a unknown, we
95d767b392SPhilip Reames; can no longer compute the subtract.
96d767b392SPhilip Reamesdefine void @icmp_zero_urem_invariant_ptr(i64 %N, i64 %M, ptr %p) {
97d767b392SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_invariant_ptr(
98d767b392SPhilip Reames; CHECK-NEXT:  entry:
99d767b392SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]]
100d767b392SPhilip Reames; CHECK-NEXT:    [[END:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 [[UREM]]
101d767b392SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
102d767b392SPhilip Reames; CHECK:       vector.body:
103d767b392SPhilip Reames; CHECK-NEXT:    [[IV:%.*]] = phi ptr [ [[P]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[VECTOR_BODY]] ]
104d767b392SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P]], align 8
105d767b392SPhilip Reames; CHECK-NEXT:    [[IV_NEXT]] = getelementptr i64, ptr [[IV]], i64 1
106d767b392SPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]]
107d767b392SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
108d767b392SPhilip Reames; CHECK:       exit:
109d767b392SPhilip Reames; CHECK-NEXT:    ret void
110d767b392SPhilip Reames;
111d767b392SPhilip Reamesentry:
112d767b392SPhilip Reames  %urem = urem i64 %N, %M
113d767b392SPhilip Reames  %end = getelementptr i64, ptr %p, i64 %urem
114d767b392SPhilip Reames  br label %vector.body
115d767b392SPhilip Reames
116d767b392SPhilip Reamesvector.body:
117d767b392SPhilip Reames  %iv = phi ptr [ %p, %entry ], [ %iv.next, %vector.body ]
118d767b392SPhilip Reames  store i64 0, ptr %p
119d767b392SPhilip Reames  %iv.next = getelementptr i64, ptr %iv, i64 1
120d767b392SPhilip Reames  %done = icmp eq ptr %iv.next, %end
121d767b392SPhilip Reames  br i1 %done, label %exit, label %vector.body
122d767b392SPhilip Reames
123d767b392SPhilip Reamesexit:
124d767b392SPhilip Reames  ret void
125d767b392SPhilip Reames}
126d767b392SPhilip Reames
127ddd4ed99SPhilip Reames; Negative test - We can not hoist because we don't know value of %M.
128ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nohoist(i64 %N, i64 %M, ptr %p) {
129ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nohoist(
130ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
131ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
132ddd4ed99SPhilip Reames; CHECK:       vector.body:
133ddd4ed99SPhilip Reames; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[VECTOR_BODY]] ]
134ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
135ddd4ed99SPhilip Reames; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 2
136ddd4ed99SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[M:%.*]]
137ddd4ed99SPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[IV_NEXT]], [[UREM]]
138ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
139ddd4ed99SPhilip Reames; CHECK:       exit:
140ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
141ddd4ed99SPhilip Reames;
142ddd4ed99SPhilip Reamesentry:
143ddd4ed99SPhilip Reames  br label %vector.body
144ddd4ed99SPhilip Reames
145ddd4ed99SPhilip Reamesvector.body:
146ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
147ddd4ed99SPhilip Reames  store i64 0, ptr %p
148ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
149ddd4ed99SPhilip Reames  %urem = urem i64 %N, %M
150ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
151ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
152ddd4ed99SPhilip Reames
153ddd4ed99SPhilip Reamesexit:
154ddd4ed99SPhilip Reames  ret void
155ddd4ed99SPhilip Reames}
156ddd4ed99SPhilip Reames
157ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_nonzero(i64 %N, i64 %M, ptr %p) {
158ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_nonzero(
159ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
160ddd4ed99SPhilip Reames; CHECK-NEXT:    [[NONZERO:%.*]] = add nuw i64 [[M:%.*]], 1
161ddd4ed99SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[NONZERO]]
162ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
163ddd4ed99SPhilip Reames; CHECK:       vector.body:
1643bc09c7dSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
165ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
1663bc09c7dSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
1673bc09c7dSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
168ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
169ddd4ed99SPhilip Reames; CHECK:       exit:
170ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
171ddd4ed99SPhilip Reames;
172ddd4ed99SPhilip Reamesentry:
173ddd4ed99SPhilip Reames  %nonzero = add nuw i64 %M, 1
174ddd4ed99SPhilip Reames  %urem = urem i64 %N, %nonzero
175ddd4ed99SPhilip Reames  br label %vector.body
176ddd4ed99SPhilip Reames
177ddd4ed99SPhilip Reamesvector.body:
178ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
179ddd4ed99SPhilip Reames  store i64 0, ptr %p
180ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
181ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
182ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
183ddd4ed99SPhilip Reames
184ddd4ed99SPhilip Reamesexit:
185ddd4ed99SPhilip Reames  ret void
186ddd4ed99SPhilip Reames}
187ddd4ed99SPhilip Reames
188ddd4ed99SPhilip Reamesdefine void @icmp_zero_urem_vscale(i64 %N, ptr %p) {
189ddd4ed99SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale(
190ddd4ed99SPhilip Reames; CHECK-NEXT:  entry:
191ddd4ed99SPhilip Reames; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
192ddd4ed99SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[VSCALE]]
193ddd4ed99SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
194ddd4ed99SPhilip Reames; CHECK:       vector.body:
1953bc09c7dSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
196ddd4ed99SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
1973bc09c7dSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
1983bc09c7dSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
199ddd4ed99SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
200ddd4ed99SPhilip Reames; CHECK:       exit:
201ddd4ed99SPhilip Reames; CHECK-NEXT:    ret void
202ddd4ed99SPhilip Reames;
203ddd4ed99SPhilip Reamesentry:
204ddd4ed99SPhilip Reames  %vscale = call i64 @llvm.vscale.i64()
205ddd4ed99SPhilip Reames  %urem = urem i64 %N, %vscale
206ddd4ed99SPhilip Reames  br label %vector.body
207ddd4ed99SPhilip Reames
208ddd4ed99SPhilip Reamesvector.body:
209ddd4ed99SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
210ddd4ed99SPhilip Reames  store i64 0, ptr %p
211ddd4ed99SPhilip Reames  %iv.next = add i64 %iv, 2
212ddd4ed99SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
213ddd4ed99SPhilip Reames  br i1 %done, label %exit, label %vector.body
214ddd4ed99SPhilip Reames
215ddd4ed99SPhilip Reamesexit:
216ddd4ed99SPhilip Reames  ret void
217ddd4ed99SPhilip Reames}
218ddd4ed99SPhilip Reames
219c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_mul8(i64 %N, ptr %p) {
220c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_mul8(
221c0df6bc9SPhilip Reames; CHECK-NEXT:  entry:
222c0df6bc9SPhilip Reames; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
223c0df6bc9SPhilip Reames; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i64 [[VSCALE]], 8
224c0df6bc9SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[MUL]]
225c0df6bc9SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
226c0df6bc9SPhilip Reames; CHECK:       vector.body:
227*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
228c0df6bc9SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
229*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
230*6ab686ebSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
231c0df6bc9SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
232c0df6bc9SPhilip Reames; CHECK:       exit:
233c0df6bc9SPhilip Reames; CHECK-NEXT:    ret void
234c0df6bc9SPhilip Reames;
235c0df6bc9SPhilip Reamesentry:
236c0df6bc9SPhilip Reames  %vscale = call i64 @llvm.vscale.i64()
237c0df6bc9SPhilip Reames  %mul = mul nuw nsw i64 %vscale, 8
238c0df6bc9SPhilip Reames  %urem = urem i64 %N, %mul
239c0df6bc9SPhilip Reames  br label %vector.body
240c0df6bc9SPhilip Reames
241c0df6bc9SPhilip Reamesvector.body:
242c0df6bc9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
243c0df6bc9SPhilip Reames  store i64 0, ptr %p
244c0df6bc9SPhilip Reames  %iv.next = add i64 %iv, 2
245c0df6bc9SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
246c0df6bc9SPhilip Reames  br i1 %done, label %exit, label %vector.body
247c0df6bc9SPhilip Reames
248c0df6bc9SPhilip Reamesexit:
249c0df6bc9SPhilip Reames  ret void
250c0df6bc9SPhilip Reames}
251c0df6bc9SPhilip Reames
252c0df6bc9SPhilip Reames
253c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_mul64(i64 %N, ptr %p) {
254c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_mul64(
255c0df6bc9SPhilip Reames; CHECK-NEXT:  entry:
256c0df6bc9SPhilip Reames; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
257c0df6bc9SPhilip Reames; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i64 [[VSCALE]], 64
258c0df6bc9SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[MUL]]
259c0df6bc9SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
260c0df6bc9SPhilip Reames; CHECK:       vector.body:
261*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
262c0df6bc9SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
263*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
264*6ab686ebSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
265c0df6bc9SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
266c0df6bc9SPhilip Reames; CHECK:       exit:
267c0df6bc9SPhilip Reames; CHECK-NEXT:    ret void
268c0df6bc9SPhilip Reames;
269c0df6bc9SPhilip Reamesentry:
270c0df6bc9SPhilip Reames  %vscale = call i64 @llvm.vscale.i64()
271c0df6bc9SPhilip Reames  %mul = mul nuw nsw i64 %vscale, 64
272c0df6bc9SPhilip Reames  %urem = urem i64 %N, %mul
273c0df6bc9SPhilip Reames  br label %vector.body
274c0df6bc9SPhilip Reames
275c0df6bc9SPhilip Reamesvector.body:
276c0df6bc9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
277c0df6bc9SPhilip Reames  store i64 0, ptr %p
278c0df6bc9SPhilip Reames  %iv.next = add i64 %iv, 2
279c0df6bc9SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
280c0df6bc9SPhilip Reames  br i1 %done, label %exit, label %vector.body
281c0df6bc9SPhilip Reames
282c0df6bc9SPhilip Reamesexit:
283c0df6bc9SPhilip Reames  ret void
284c0df6bc9SPhilip Reames}
285c0df6bc9SPhilip Reames
286c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_shl3(i64 %N, ptr %p) {
287c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_shl3(
288c0df6bc9SPhilip Reames; CHECK-NEXT:  entry:
289c0df6bc9SPhilip Reames; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
290c0df6bc9SPhilip Reames; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VSCALE]], 3
291c0df6bc9SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[SHL]]
292c0df6bc9SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
293c0df6bc9SPhilip Reames; CHECK:       vector.body:
294*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
295c0df6bc9SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
296*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
297*6ab686ebSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
298c0df6bc9SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
299c0df6bc9SPhilip Reames; CHECK:       exit:
300c0df6bc9SPhilip Reames; CHECK-NEXT:    ret void
301c0df6bc9SPhilip Reames;
302c0df6bc9SPhilip Reamesentry:
303c0df6bc9SPhilip Reames  %vscale = call i64 @llvm.vscale.i64()
304c0df6bc9SPhilip Reames  %shl = shl i64 %vscale, 3
305c0df6bc9SPhilip Reames  %urem = urem i64 %N, %shl
306c0df6bc9SPhilip Reames  br label %vector.body
307c0df6bc9SPhilip Reames
308c0df6bc9SPhilip Reamesvector.body:
309c0df6bc9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
310c0df6bc9SPhilip Reames  store i64 0, ptr %p
311c0df6bc9SPhilip Reames  %iv.next = add i64 %iv, 2
312c0df6bc9SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
313c0df6bc9SPhilip Reames  br i1 %done, label %exit, label %vector.body
314c0df6bc9SPhilip Reames
315c0df6bc9SPhilip Reamesexit:
316c0df6bc9SPhilip Reames  ret void
317c0df6bc9SPhilip Reames}
318c0df6bc9SPhilip Reames
319c0df6bc9SPhilip Reamesdefine void @icmp_zero_urem_vscale_shl6(i64 %N, ptr %p) {
320c0df6bc9SPhilip Reames; CHECK-LABEL: @icmp_zero_urem_vscale_shl6(
321c0df6bc9SPhilip Reames; CHECK-NEXT:  entry:
322c0df6bc9SPhilip Reames; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
323c0df6bc9SPhilip Reames; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[VSCALE]], 6
324c0df6bc9SPhilip Reames; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[N:%.*]], [[SHL]]
325c0df6bc9SPhilip Reames; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
326c0df6bc9SPhilip Reames; CHECK:       vector.body:
327*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ [[UREM]], [[ENTRY:%.*]] ]
328c0df6bc9SPhilip Reames; CHECK-NEXT:    store i64 0, ptr [[P:%.*]], align 8
329*6ab686ebSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -2
330*6ab686ebSPhilip Reames; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
331c0df6bc9SPhilip Reames; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
332c0df6bc9SPhilip Reames; CHECK:       exit:
333c0df6bc9SPhilip Reames; CHECK-NEXT:    ret void
334c0df6bc9SPhilip Reames;
335c0df6bc9SPhilip Reamesentry:
336c0df6bc9SPhilip Reames  %vscale = call i64 @llvm.vscale.i64()
337c0df6bc9SPhilip Reames  %shl = shl i64 %vscale, 6
338c0df6bc9SPhilip Reames  %urem = urem i64 %N, %shl
339c0df6bc9SPhilip Reames  br label %vector.body
340c0df6bc9SPhilip Reames
341c0df6bc9SPhilip Reamesvector.body:
342c0df6bc9SPhilip Reames  %iv = phi i64 [ 0, %entry ], [ %iv.next, %vector.body ]
343c0df6bc9SPhilip Reames  store i64 0, ptr %p
344c0df6bc9SPhilip Reames  %iv.next = add i64 %iv, 2
345c0df6bc9SPhilip Reames  %done = icmp eq i64 %iv.next, %urem
346c0df6bc9SPhilip Reames  br i1 %done, label %exit, label %vector.body
347c0df6bc9SPhilip Reames
348c0df6bc9SPhilip Reamesexit:
349c0df6bc9SPhilip Reames  ret void
350c0df6bc9SPhilip Reames}
351c0df6bc9SPhilip Reames
3522aed3cdbSPhilip Reames; Loop invariant does not neccessarily mean dominating the loop.  Forming
3532aed3cdbSPhilip Reames; an ICmpZero from this example would be illegal even though the operands
3542aed3cdbSPhilip Reames; to the compare are loop invariant.
3552aed3cdbSPhilip Reamesdefine void @loop_invariant_definition(i64 %arg) {
3562aed3cdbSPhilip Reames; CHECK-LABEL: @loop_invariant_definition(
3572aed3cdbSPhilip Reames; CHECK-NEXT:  entry:
3582aed3cdbSPhilip Reames; CHECK-NEXT:    br label [[T1:%.*]]
3592aed3cdbSPhilip Reames; CHECK:       t1:
3602aed3cdbSPhilip Reames; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[T1]] ], [ -1, [[ENTRY:%.*]] ]
3612aed3cdbSPhilip Reames; CHECK-NEXT:    [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], 1
3622aed3cdbSPhilip Reames; CHECK-NEXT:    br i1 true, label [[T4:%.*]], label [[T1]]
3632aed3cdbSPhilip Reames; CHECK:       t4:
3642aed3cdbSPhilip Reames; CHECK-NEXT:    [[T5:%.*]] = trunc i64 [[LSR_IV_NEXT]] to i32
3652aed3cdbSPhilip Reames; CHECK-NEXT:    [[T6:%.*]] = add i32 [[T5]], 1
3662aed3cdbSPhilip Reames; CHECK-NEXT:    [[T7:%.*]] = icmp eq i32 [[T5]], [[T6]]
3672aed3cdbSPhilip Reames; CHECK-NEXT:    ret void
3682aed3cdbSPhilip Reames;
3692aed3cdbSPhilip Reamesentry:
3702aed3cdbSPhilip Reames  br label %t1
3712aed3cdbSPhilip Reames
3722aed3cdbSPhilip Reamest1:                                                ; preds = %1, %0
3732aed3cdbSPhilip Reames  %t2 = phi i64 [ %t3, %t1 ], [ 0, %entry ]
3742aed3cdbSPhilip Reames  %t3 = add nuw i64 %t2, 1
3752aed3cdbSPhilip Reames  br i1 true, label %t4, label %t1
3762aed3cdbSPhilip Reames
3772aed3cdbSPhilip Reamest4:                                                ; preds = %1
3782aed3cdbSPhilip Reames  %t5 = trunc i64 %t2 to i32
3792aed3cdbSPhilip Reames  %t6 = add i32 %t5, 1
3802aed3cdbSPhilip Reames  %t7 = icmp eq i32 %t5, %t6
3812aed3cdbSPhilip Reames  ret void
3822aed3cdbSPhilip Reames}
3832aed3cdbSPhilip Reames
384ddd4ed99SPhilip Reamesdeclare i64 @llvm.vscale.i64()
385