[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / version-stride-with-integer-casts.ll
blobbb938045a541327ec2dfc1d1dc0d38a57c52bca2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
6 define void @test_versioned_with_sext_use(i32 %offset, ptr %dst) {
7 ; CHECK-LABEL: define void @test_versioned_with_sext_use(
8 ; CHECK-SAME: i32 [[OFFSET:%.*]], ptr [[DST:%.*]]) {
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[OFFSET_EXT:%.*]] = sext i32 [[OFFSET]] to i64
11 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
12 ; CHECK:       outer.header.loopexit:
13 ; CHECK-NEXT:    [[IV_2_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[INNER_LOOP:%.*]] ], [ [[IND_END:%.*]], [[MIDDLE_BLOCK:%.*]] ]
14 ; CHECK-NEXT:    br label [[OUTER_HEADER]]
15 ; CHECK:       outer.header:
16 ; CHECK-NEXT:    [[IV_1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_2_NEXT_LCSSA]], [[OUTER_HEADER_LOOPEXIT:%.*]] ]
17 ; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
18 ; CHECK-NEXT:    br i1 [[C]], label [[INNER_LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
19 ; CHECK:       inner.loop.preheader:
20 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
21 ; CHECK:       vector.scevcheck:
22 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[OFFSET]], 1
23 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
24 ; CHECK:       vector.ph:
25 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 200, [[OFFSET_EXT]]
26 ; CHECK-NEXT:    [[IND_END]] = add i64 [[IV_1]], [[TMP0]]
27 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
28 ; CHECK:       vector.body:
29 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
30 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[INDEX]], [[OFFSET_EXT]]
31 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 [[IV_1]], [[TMP1]]
32 ; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 0, [[OFFSET_EXT]]
33 ; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], [[TMP2]]
34 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i32, ptr [[DST]], i64 [[TMP3]]
35 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0
36 ; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[TMP5]], align 8
37 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
38 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
39 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
40 ; CHECK:       middle.block:
41 ; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER_LOOPEXIT]], label [[SCALAR_PH]]
42 ; CHECK:       scalar.ph:
43 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[IV_1]], [[INNER_LOOP_PREHEADER]] ], [ [[IV_1]], [[VECTOR_SCEVCHECK]] ]
44 ; CHECK-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi i32 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[INNER_LOOP_PREHEADER]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
45 ; CHECK-NEXT:    br label [[INNER_LOOP]]
46 ; CHECK:       inner.loop:
47 ; CHECK-NEXT:    [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
48 ; CHECK-NEXT:    [[IV_3:%.*]] = phi i32 [ [[IV_3_NEXT:%.*]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ]
49 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[DST]], i64 [[IV_2]]
50 ; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 8
51 ; CHECK-NEXT:    [[IV_2_NEXT]] = add i64 [[IV_2]], [[OFFSET_EXT]]
52 ; CHECK-NEXT:    [[IV_3_NEXT]] = add i32 [[IV_3]], 1
53 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV_3]], 200
54 ; CHECK-NEXT:    br i1 [[EC]], label [[OUTER_HEADER_LOOPEXIT]], label [[INNER_LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
55 ; CHECK:       exit:
56 ; CHECK-NEXT:    ret void
58 entry:
59   %offset.ext = sext i32 %offset to i64
60   br label %outer.header
62 outer.header:
63   %iv.1 = phi i64 [ 0, %entry ], [ %iv.2.next, %inner.loop ]
64   %c = call i1 @cond()
65   br i1 %c, label %inner.loop, label %exit
67 inner.loop:
68   %iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]
69   %iv.3 = phi i32 [ 0, %outer.header ], [ %iv.3.next, %inner.loop ]
70   %gep = getelementptr i32, ptr %dst, i64 %iv.2
71   store i32 0, ptr %gep, align 8
72   %iv.2.next = add i64 %iv.2, %offset.ext
73   %iv.3.next = add i32 %iv.3, 1
74   %ec = icmp eq i32 %iv.3, 200
75   br i1 %ec, label %outer.header, label %inner.loop
77 exit:
78   ret void
81 define void @test_versioned_with_zext_use(i32 %offset, ptr %dst) {
82 ; CHECK-LABEL: define void @test_versioned_with_zext_use(
83 ; CHECK-SAME: i32 [[OFFSET:%.*]], ptr [[DST:%.*]]) {
84 ; CHECK-NEXT:  entry:
85 ; CHECK-NEXT:    [[OFFSET_EXT:%.*]] = zext i32 [[OFFSET]] to i64
86 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
87 ; CHECK:       outer.header.loopexit:
88 ; CHECK-NEXT:    [[IV_2_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[INNER_LOOP:%.*]] ], [ [[IND_END:%.*]], [[MIDDLE_BLOCK:%.*]] ]
89 ; CHECK-NEXT:    br label [[OUTER_HEADER]]
90 ; CHECK:       outer.header:
91 ; CHECK-NEXT:    [[IV_1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_2_NEXT_LCSSA]], [[OUTER_HEADER_LOOPEXIT:%.*]] ]
92 ; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
93 ; CHECK-NEXT:    br i1 [[C]], label [[INNER_LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
94 ; CHECK:       inner.loop.preheader:
95 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
96 ; CHECK:       vector.scevcheck:
97 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[OFFSET]], 1
98 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
99 ; CHECK:       vector.ph:
100 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 200, [[OFFSET_EXT]]
101 ; CHECK-NEXT:    [[IND_END]] = add i64 [[IV_1]], [[TMP0]]
102 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
103 ; CHECK:       vector.body:
104 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
105 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[INDEX]], [[OFFSET_EXT]]
106 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 [[IV_1]], [[TMP1]]
107 ; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 0, [[OFFSET_EXT]]
108 ; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], [[TMP2]]
109 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i32, ptr [[DST]], i64 [[TMP3]]
110 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0
111 ; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[TMP5]], align 8
112 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
113 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
114 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
115 ; CHECK:       middle.block:
116 ; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER_LOOPEXIT]], label [[SCALAR_PH]]
117 ; CHECK:       scalar.ph:
118 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[IV_1]], [[INNER_LOOP_PREHEADER]] ], [ [[IV_1]], [[VECTOR_SCEVCHECK]] ]
119 ; CHECK-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi i32 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[INNER_LOOP_PREHEADER]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
120 ; CHECK-NEXT:    br label [[INNER_LOOP]]
121 ; CHECK:       inner.loop:
122 ; CHECK-NEXT:    [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
123 ; CHECK-NEXT:    [[IV_3:%.*]] = phi i32 [ [[IV_3_NEXT:%.*]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ]
124 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[DST]], i64 [[IV_2]]
125 ; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 8
126 ; CHECK-NEXT:    [[IV_2_NEXT]] = add i64 [[IV_2]], [[OFFSET_EXT]]
127 ; CHECK-NEXT:    [[IV_3_NEXT]] = add i32 [[IV_3]], 1
128 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV_3]], 200
129 ; CHECK-NEXT:    br i1 [[EC]], label [[OUTER_HEADER_LOOPEXIT]], label [[INNER_LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
130 ; CHECK:       exit:
131 ; CHECK-NEXT:    ret void
133 entry:
134   %offset.ext = zext i32 %offset to i64
135   br label %outer.header
137 outer.header:
138   %iv.1 = phi i64 [ 0, %entry ], [ %iv.2.next, %inner.loop ]
139   %c = call i1 @cond()
140   br i1 %c, label %inner.loop, label %exit
142 inner.loop:
143   %iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]
144   %iv.3 = phi i32 [ 0, %outer.header ], [ %iv.3.next, %inner.loop ]
145   %gep = getelementptr i32, ptr %dst, i64 %iv.2
146   store i32 0, ptr %gep, align 8
147   %iv.2.next = add i64 %iv.2, %offset.ext
148   %iv.3.next = add i32 %iv.3, 1
149   %ec = icmp eq i32 %iv.3, 200
150   br i1 %ec, label %outer.header, label %inner.loop
152 exit:
153   ret void
156 define void @versioned_sext_use_in_gep(i32 %scale, ptr %dst, i64 %scale.2) {
157 ; CHECK-LABEL: define void @versioned_sext_use_in_gep(
158 ; CHECK-SAME: i32 [[SCALE:%.*]], ptr [[DST:%.*]], i64 [[SCALE_2:%.*]]) {
159 ; CHECK-NEXT:  entry:
160 ; CHECK-NEXT:    [[SCALE_EXT:%.*]] = sext i32 [[SCALE]] to i64
161 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
162 ; CHECK:       vector.scevcheck:
163 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[SCALE]], 1
164 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
165 ; CHECK:       vector.ph:
166 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SCALE_2]]
167 ; CHECK-NEXT:    [[TMP81:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SCALE_2]]
168 ; CHECK-NEXT:    [[TMP82:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SCALE_2]]
169 ; CHECK-NEXT:    [[TMP83:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SCALE_2]]
170 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
171 ; CHECK:       vector.body:
172 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
173 ; CHECK-NEXT:    [[TMP10:%.*]] = add i64 [[INDEX]], 0
174 ; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[INDEX]], 1
175 ; CHECK-NEXT:    [[TMP14:%.*]] = add i64 [[INDEX]], 2
176 ; CHECK-NEXT:    [[TMP16:%.*]] = add i64 [[INDEX]], 3
177 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP10]]
178 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP12]]
179 ; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP14]]
180 ; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP16]]
181 ; CHECK-NEXT:    store ptr [[TMP8]], ptr [[TMP11]], align 8
182 ; CHECK-NEXT:    store ptr [[TMP8]], ptr [[TMP13]], align 8
183 ; CHECK-NEXT:    store ptr [[TMP8]], ptr [[TMP15]], align 8
184 ; CHECK-NEXT:    store ptr [[TMP8]], ptr [[TMP17]], align 8
185 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
186 ; CHECK-NEXT:    [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
187 ; CHECK-NEXT:    br i1 [[TMP18]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
188 ; CHECK:       middle.block:
189 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
190 ; CHECK:       scalar.ph:
191 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 256, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
192 ; CHECK-NEXT:    br label [[LOOP:%.*]]
193 ; CHECK:       loop:
194 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
195 ; CHECK-NEXT:    [[IV_MUL:%.*]] = mul i64 [[IV]], [[SCALE_EXT]]
196 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i8, ptr [[DST]], i64 [[IV_MUL]]
197 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
198 ; CHECK-NEXT:    [[SCALE_MUL:%.*]] = mul i64 [[SCALE_EXT]], [[SCALE_2]]
199 ; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr i8, ptr [[DST]], i64 [[SCALE_MUL]]
200 ; CHECK-NEXT:    store ptr [[GEP_2]], ptr [[GEP_1]], align 8
201 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 256
202 ; CHECK-NEXT:    br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]
203 ; CHECK:       exit:
204 ; CHECK-NEXT:    ret void
206 entry:
207   %scale.ext = sext i32 %scale to i64
208   br label %loop
210 loop:
211   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
212   %iv.mul  = mul i64 %iv, %scale.ext
213   %gep.1 = getelementptr i8, ptr %dst, i64 %iv.mul
214   %iv.next = add i64 %iv, 1
215   %scale.mul = mul i64 %scale.ext, %scale.2
216   %gep.2 = getelementptr i8, ptr %dst, i64 %scale.mul
217   store ptr %gep.2, ptr %gep.1, align 8
218   %ec = icmp eq i64 %iv.next, 256
219   br i1 %ec, label %exit, label %loop
221 exit:
222   ret void
225 declare i1 @cond()
227 define void @test_versioned_with_different_uses(i32 %offset, ptr noalias %dst.1, ptr %dst.2) {
228 ; CHECK-LABEL: define void @test_versioned_with_different_uses(
229 ; CHECK-SAME: i32 [[OFFSET:%.*]], ptr noalias [[DST_1:%.*]], ptr [[DST_2:%.*]]) {
230 ; CHECK-NEXT:  entry:
231 ; CHECK-NEXT:    [[OFFSET_EXT:%.*]] = zext i32 [[OFFSET]] to i64
232 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
233 ; CHECK:       outer.header.loopexit:
234 ; CHECK-NEXT:    [[IV_2_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[INNER_LOOP:%.*]] ], [ [[IND_END:%.*]], [[MIDDLE_BLOCK:%.*]] ]
235 ; CHECK-NEXT:    br label [[OUTER_HEADER]]
236 ; CHECK:       outer.header:
237 ; CHECK-NEXT:    [[IV_1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_2_NEXT_LCSSA]], [[OUTER_HEADER_LOOPEXIT:%.*]] ]
238 ; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
239 ; CHECK-NEXT:    br i1 [[C]], label [[INNER_LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
240 ; CHECK:       inner.loop.preheader:
241 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
242 ; CHECK:       vector.scevcheck:
243 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[OFFSET]], 1
244 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
245 ; CHECK:       vector.ph:
246 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 200, [[OFFSET_EXT]]
247 ; CHECK-NEXT:    [[IND_END]] = add i64 [[IV_1]], [[TMP0]]
248 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
249 ; CHECK:       vector.body:
250 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
251 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[INDEX]], [[OFFSET_EXT]]
252 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 [[IV_1]], [[TMP1]]
253 ; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 0, [[OFFSET_EXT]]
254 ; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], [[TMP2]]
255 ; CHECK-NEXT:    [[OFFSET_IDX2:%.*]] = trunc i64 [[INDEX]] to i32
256 ; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[OFFSET_IDX2]], 0
257 ; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[OFFSET_IDX2]], 1
258 ; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[OFFSET_IDX2]], 2
259 ; CHECK-NEXT:    [[TMP7:%.*]] = add i32 [[OFFSET_IDX2]], 3
260 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP4]]
261 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP5]]
262 ; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP6]]
263 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP7]]
264 ; CHECK-NEXT:    store i32 0, ptr [[TMP8]], align 8
265 ; CHECK-NEXT:    store i32 0, ptr [[TMP9]], align 8
266 ; CHECK-NEXT:    store i32 0, ptr [[TMP10]], align 8
267 ; CHECK-NEXT:    store i32 0, ptr [[TMP11]], align 8
268 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr i32, ptr [[DST_2]], i64 [[TMP3]]
269 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr i32, ptr [[TMP12]], i32 0
270 ; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[TMP13]], align 8
271 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
272 ; CHECK-NEXT:    [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
273 ; CHECK-NEXT:    br i1 [[TMP15]], label [[MIDDLE_BLOCK]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
274 ; CHECK:       middle.block:
275 ; CHECK-NEXT:    br i1 false, label [[OUTER_HEADER_LOOPEXIT]], label [[SCALAR_PH]]
276 ; CHECK:       scalar.ph:
277 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[IV_1]], [[INNER_LOOP_PREHEADER]] ], [ [[IV_1]], [[VECTOR_SCEVCHECK]] ]
278 ; CHECK-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi i32 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[INNER_LOOP_PREHEADER]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
279 ; CHECK-NEXT:    br label [[INNER_LOOP]]
280 ; CHECK:       inner.loop:
281 ; CHECK-NEXT:    [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
282 ; CHECK-NEXT:    [[IV_3:%.*]] = phi i32 [ [[IV_3_NEXT:%.*]], [[INNER_LOOP]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ]
283 ; CHECK-NEXT:    [[IV_MUL:%.*]] = mul i32 [[IV_3]], [[OFFSET]]
284 ; CHECK-NEXT:    [[GEP_MUL:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[IV_MUL]]
285 ; CHECK-NEXT:    store i32 0, ptr [[GEP_MUL]], align 8
286 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[DST_2]], i64 [[IV_2]]
287 ; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 8
288 ; CHECK-NEXT:    [[IV_2_NEXT]] = add i64 [[IV_2]], [[OFFSET_EXT]]
289 ; CHECK-NEXT:    [[IV_3_NEXT]] = add i32 [[IV_3]], 1
290 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV_3]], 200
291 ; CHECK-NEXT:    br i1 [[EC]], label [[OUTER_HEADER_LOOPEXIT]], label [[INNER_LOOP]], !llvm.loop [[LOOP9:![0-9]+]]
292 ; CHECK:       exit:
293 ; CHECK-NEXT:    ret void
295 entry:
296   %offset.ext = zext i32 %offset to i64
297   br label %outer.header
299 outer.header:
300   %iv.1 = phi i64 [ 0, %entry ], [ %iv.2.next, %inner.loop ]
301   %c = call i1 @cond()
302   br i1 %c, label %inner.loop, label %exit
304 inner.loop:
305   %iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]
306   %iv.3 = phi i32 [ 0, %outer.header ], [ %iv.3.next, %inner.loop ]
307   %iv.mul  = mul i32 %iv.3, %offset
308   %gep.mul = getelementptr i8, ptr %dst.1, i32 %iv.mul
309   store i32 0, ptr %gep.mul, align 8
310   %gep = getelementptr i32, ptr %dst.2, i64 %iv.2
311   store i32 0, ptr %gep, align 8
312   %iv.2.next = add i64 %iv.2, %offset.ext
313   %iv.3.next = add i32 %iv.3, 1
314   %ec = icmp eq i32 %iv.3, 200
315   br i1 %ec, label %outer.header, label %inner.loop
317 exit:
318   ret void
321 define void @test_versioned_with_non_ex_use(i32 %offset, ptr noalias %dst.1, ptr %dst.2) {
322 ; CHECK-LABEL: define void @test_versioned_with_non_ex_use(
323 ; CHECK-SAME: i32 [[OFFSET:%.*]], ptr noalias [[DST_1:%.*]], ptr [[DST_2:%.*]]) {
324 ; CHECK-NEXT:  entry:
325 ; CHECK-NEXT:    [[OFFSET_EXT:%.*]] = zext i32 [[OFFSET]] to i64
326 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[OFFSET]], 3
327 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
328 ; CHECK:       vector.scevcheck:
329 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 -3, [[OFFSET]]
330 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[ADD]], 0
331 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[TMP0]], i32 [[ADD]]
332 ; CHECK-NEXT:    [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[TMP2]], i32 200)
333 ; CHECK-NEXT:    [[MUL_RESULT:%.*]] = extractvalue { i32, i1 } [[MUL]], 0
334 ; CHECK-NEXT:    [[MUL_OVERFLOW:%.*]] = extractvalue { i32, i1 } [[MUL]], 1
335 ; CHECK-NEXT:    [[TMP3:%.*]] = sub i32 0, [[MUL_RESULT]]
336 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[MUL_RESULT]], 0
337 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0
338 ; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP1]], i1 [[TMP5]], i1 [[TMP4]]
339 ; CHECK-NEXT:    [[TMP7:%.*]] = or i1 [[TMP6]], [[MUL_OVERFLOW]]
340 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[OFFSET]], 1
341 ; CHECK-NEXT:    [[TMP8:%.*]] = or i1 [[TMP7]], [[IDENT_CHECK]]
342 ; CHECK-NEXT:    br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
343 ; CHECK:       vector.ph:
344 ; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[ADD]], i64 0
345 ; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
346 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
347 ; CHECK:       vector.body:
348 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
349 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
350 ; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[INDEX]], 0
351 ; CHECK-NEXT:    [[TMP10:%.*]] = mul <4 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
352 ; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x i32> [[TMP10]], i32 0
353 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP11]]
354 ; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i32> [[TMP10]], i32 1
355 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP13]]
356 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <4 x i32> [[TMP10]], i32 2
357 ; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP15]]
358 ; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <4 x i32> [[TMP10]], i32 3
359 ; CHECK-NEXT:    [[TMP18:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[TMP17]]
360 ; CHECK-NEXT:    store i32 0, ptr [[TMP12]], align 8
361 ; CHECK-NEXT:    store i32 0, ptr [[TMP14]], align 8
362 ; CHECK-NEXT:    store i32 0, ptr [[TMP16]], align 8
363 ; CHECK-NEXT:    store i32 0, ptr [[TMP18]], align 8
364 ; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr i32, ptr [[DST_2]], i64 [[TMP9]]
365 ; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr i32, ptr [[TMP20]], i32 0
366 ; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[TMP21]], align 8
367 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
368 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], splat (i32 4)
369 ; CHECK-NEXT:    [[TMP22:%.*]] = icmp eq i64 [[INDEX_NEXT]], 200
370 ; CHECK-NEXT:    br i1 [[TMP22]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
371 ; CHECK:       middle.block:
372 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
373 ; CHECK:       scalar.ph:
374 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
375 ; CHECK-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi i32 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
376 ; CHECK-NEXT:    br label [[LOOP:%.*]]
377 ; CHECK:       loop:
378 ; CHECK-NEXT:    [[IV_2:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_2_NEXT:%.*]], [[LOOP]] ]
379 ; CHECK-NEXT:    [[IV_3:%.*]] = phi i32 [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ], [ [[IV_3_NEXT:%.*]], [[LOOP]] ]
380 ; CHECK-NEXT:    [[IV_MUL:%.*]] = mul i32 [[IV_3]], [[ADD]]
381 ; CHECK-NEXT:    [[GEP_MUL:%.*]] = getelementptr i8, ptr [[DST_1]], i32 [[IV_MUL]]
382 ; CHECK-NEXT:    store i32 0, ptr [[GEP_MUL]], align 8
383 ; CHECK-NEXT:    [[IV_2_MUL:%.*]] = mul i64 [[IV_2]], [[OFFSET_EXT]]
384 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[DST_2]], i64 [[IV_2_MUL]]
385 ; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 8
386 ; CHECK-NEXT:    [[IV_2_NEXT]] = add i64 [[IV_2]], 1
387 ; CHECK-NEXT:    [[IV_3_NEXT]] = add i32 [[IV_3]], 1
388 ; CHECK-NEXT:    [[EC:%.*]] = icmp eq i32 [[IV_3]], 200
389 ; CHECK-NEXT:    br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP11:![0-9]+]]
390 ; CHECK:       exit:
391 ; CHECK-NEXT:    ret void
393 entry:
394   %offset.ext = zext i32 %offset to i64
395   %add = add i32 %offset, 3
396   br label %loop
398 loop:
399   %iv.2 = phi i64 [ 0, %entry ], [ %iv.2.next, %loop ]
400   %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ]
401   %iv.mul  = mul i32 %iv.3, %add
402   %gep.mul = getelementptr i8, ptr %dst.1, i32 %iv.mul
403   store i32 0, ptr %gep.mul, align 8
404   %iv.2.mul  = mul i64 %iv.2, %offset.ext
405   %gep = getelementptr i32, ptr %dst.2, i64 %iv.2.mul
406   store i32 0, ptr %gep, align 8
407   %iv.2.next = add i64 %iv.2, 1
408   %iv.3.next = add i32 %iv.3, 1
409   %ec = icmp eq i32 %iv.3, 200
410   br i1 %ec, label %exit, label %loop
412 exit:
413   ret void
416 ; Test case to make sure that uses of versioned strides of type i1 are properly
417 ; extended. From https://github.com/llvm/llvm-project/issues/91369.
418 ; TODO: Better check (udiv i64 15, %g.64) after checking if %g == 1.
419 define void @zext_of_i1_stride(i1 %g, ptr %dst) mustprogress {
420 ; CHECK-LABEL: define void @zext_of_i1_stride(
421 ; CHECK-SAME: i1 [[G:%.*]], ptr [[DST:%.*]]) #[[ATTR0:[0-9]+]] {
422 ; CHECK-NEXT:  entry:
423 ; CHECK-NEXT:    [[G_16:%.*]] = zext i1 [[G]] to i16
424 ; CHECK-NEXT:    [[G_64:%.*]] = zext i1 [[G]] to i64
425 ; CHECK-NEXT:    [[TMP0:%.*]] = udiv i64 15, [[G_64]]
426 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1
427 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
428 ; CHECK:       vector.scevcheck:
429 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i1 [[G]], true
430 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
431 ; CHECK:       vector.ph:
432 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4
433 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]
434 ; CHECK-NEXT:    [[IND_END:%.*]] = mul i64 [[N_VEC]], [[G_64]]
435 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
436 ; CHECK:       vector.body:
437 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
438 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], [[G_64]]
439 ; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 0, [[G_64]]
440 ; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], [[TMP2]]
441 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i16, ptr [[DST]], i64 [[TMP3]]
442 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[TMP4]], i32 0
443 ; CHECK-NEXT:    store <4 x i16> splat (i16 1), ptr [[TMP5]], align 2
444 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
445 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
446 ; CHECK-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
447 ; CHECK:       middle.block:
448 ; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]
449 ; CHECK-NEXT:    br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
450 ; CHECK:       scalar.ph:
451 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
452 ; CHECK-NEXT:    br label [[LOOP:%.*]]
453 ; CHECK:       loop:
454 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
455 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, ptr [[DST]], i64 [[IV]]
456 ; CHECK-NEXT:    store i16 [[G_16]], ptr [[GEP]], align 2
457 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], [[G_64]]
458 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], 16
459 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP13:![0-9]+]]
460 ; CHECK:       exit:
461 ; CHECK-NEXT:    ret void
463 entry:
464   %g.16 = zext i1 %g to i16
465   %g.64 = zext i1 %g to i64
466   br label %loop
468 loop:
469   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
470   %gep = getelementptr inbounds i16, ptr %dst, i64 %iv
471   store i16 %g.16, ptr %gep, align 2
472   %iv.next = add nuw nsw i64 %iv, %g.64
473   %cmp = icmp ult i64 %iv.next, 16
474   br i1 %cmp, label %loop, label %exit
476 exit:
477   ret void
480 ; Test case to make sure that uses of versioned strides of type i1 are properly
481 ; extended.
482 define void @sext_of_i1_stride(i1 %g, ptr %dst) mustprogress {
483 ; CHECK-LABEL: define void @sext_of_i1_stride(
484 ; CHECK-SAME: i1 [[G:%.*]], ptr [[DST:%.*]]) #[[ATTR0]] {
485 ; CHECK-NEXT:  entry:
486 ; CHECK-NEXT:    [[G_16:%.*]] = sext i1 [[G]] to i16
487 ; CHECK-NEXT:    [[G_64:%.*]] = sext i1 [[G]] to i64
488 ; CHECK-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[G_64]], i64 16)
489 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[UMAX]], -1
490 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[TMP0]], [[G_64]]
491 ; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
492 ; CHECK-NEXT:    br i1 true, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
493 ; CHECK:       vector.scevcheck:
494 ; CHECK-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i1 [[G]], true
495 ; CHECK-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
496 ; CHECK:       vector.ph:
497 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 4
498 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
499 ; CHECK-NEXT:    [[IND_END:%.*]] = mul i64 [[N_VEC]], [[G_64]]
500 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
501 ; CHECK:       vector.body:
502 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
503 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], [[G_64]]
504 ; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 0, [[G_64]]
505 ; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], [[TMP3]]
506 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[DST]], i64 [[TMP4]]
507 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i16, ptr [[TMP5]], i32 0
508 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i16, ptr [[TMP6]], i32 -3
509 ; CHECK-NEXT:    store <4 x i16> splat (i16 -1), ptr [[TMP7]], align 2
510 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
511 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
512 ; CHECK:       middle.block:
513 ; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
514 ; CHECK-NEXT:    br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
515 ; CHECK:       scalar.ph:
516 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
517 ; CHECK-NEXT:    br label [[LOOP:%.*]]
518 ; CHECK:       loop:
519 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
520 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, ptr [[DST]], i64 [[IV]]
521 ; CHECK-NEXT:    store i16 [[G_16]], ptr [[GEP]], align 2
522 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], [[G_64]]
523 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV_NEXT]], 16
524 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP15:![0-9]+]]
525 ; CHECK:       exit:
526 ; CHECK-NEXT:    ret void
528 entry:
529   %g.16 = sext i1 %g to i16
530   %g.64 = sext i1 %g to i64
531   br label %loop
533 loop:
534   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
535   %gep = getelementptr inbounds i16, ptr %dst, i64 %iv
536   store i16 %g.16, ptr %gep, align 2
537   %iv.next = add nuw nsw i64 %iv, %g.64
538   %cmp = icmp ult i64 %iv.next, 16
539   br i1 %cmp, label %loop, label %exit
541 exit:
542   ret void
547 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
548 ; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
549 ; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
550 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
551 ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
552 ; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}
553 ; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
554 ; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META1]]}
555 ; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]}
556 ; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META1]]}
557 ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]}
558 ; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META1]]}
559 ; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]}
560 ; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META1]]}
561 ; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]}
562 ; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META1]]}