1 ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s
3 define void @test_chained_first_order_recurrences_1(ptr %ptr) {
4 ; CHECK-LABEL: @test_chained_first_order_recurrences_1
6 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
7 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
8 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
9 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
10 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
11 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
12 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
13 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
14 ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
15 ; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i16> [[TMP4]], [[TMP5]]
16 ; CHECK-NEXT: store <4 x i16> [[TMP6]], ptr [[TMP2]], align 2
17 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
18 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
19 ; CHECK-NEXT: br i1 [[TMP8]], label %middle.block, label %vector.body
20 ; CHECK: middle.block:
21 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
22 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
23 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
24 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT2:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
25 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
31 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
32 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
33 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
34 %iv.next = add nuw nsw i64 %iv, 1
35 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
36 %for.1.next = load i16, ptr %gep.ptr, align 2
37 %add = add i16 %for.1, %for.2
38 store i16 %add, ptr %gep.ptr
39 %exitcond.not = icmp eq i64 %iv.next, 1000
40 br i1 %exitcond.not, label %exit, label %loop
46 define void @test_chained_first_order_recurrences_2(ptr %ptr) {
47 ; CHECK-LABEL: @test_chained_first_order_recurrences_2
49 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
50 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
51 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
52 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
53 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
54 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
55 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
56 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
57 ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
58 ; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i16> [[TMP4]], [[TMP5]]
59 ; CHECK-NEXT: store <4 x i16> [[TMP6]], ptr [[TMP2]], align 2
60 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
61 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
62 ; CHECK-NEXT: br i1 [[TMP8]], label %middle.block, label %vector.body, !llvm.loop [[LOOP4:![0-9]+]]
63 ; CHECK: middle.block:
64 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
65 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
66 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
67 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT2:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
68 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI3:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
74 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
75 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
76 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
77 %iv.next = add nuw nsw i64 %iv, 1
78 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
79 %for.1.next = load i16, ptr %gep.ptr, align 2
80 %add = add i16 %for.1, %for.2
81 store i16 %add, ptr %gep.ptr
82 %exitcond.not = icmp eq i64 %iv.next, 1000
83 br i1 %exitcond.not, label %exit, label %loop
89 define void @test_chained_first_order_recurrences_3(ptr %ptr) {
90 ; CHECK-LABEL: @test_chained_first_order_recurrences_3
92 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
93 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
94 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
95 ; CHECK-NEXT: [[VECTOR_RECUR2:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP5:%.*]], %vector.body ]
96 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
97 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
98 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
99 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
100 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
101 ; CHECK-NEXT: [[TMP5]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
102 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR2]], <4 x i16> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
103 ; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i16> [[TMP4]], [[TMP5]]
104 ; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i16> [[TMP7]], [[TMP6]]
105 ; CHECK-NEXT: store <4 x i16> [[TMP8]], ptr [[TMP2]], align 2
106 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
107 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
108 ; CHECK-NEXT: br i1 [[TMP10]], label %middle.block, label %vector.body, !llvm.loop [[LOOP6:![0-9]+]]
109 ; CHECK: middle.block:
110 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
111 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
112 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
113 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
114 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI4:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
115 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3
116 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2
122 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
123 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
124 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ]
125 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
126 %iv.next = add nuw nsw i64 %iv, 1
127 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
128 %for.1.next = load i16, ptr %gep.ptr, align 2
129 %add.1 = add i16 %for.1, %for.2
130 %add.2 = add i16 %add.1, %for.3
131 store i16 %add.2, ptr %gep.ptr
132 %exitcond.not = icmp eq i64 %iv.next, 1000
133 br i1 %exitcond.not, label %exit, label %loop
139 define void @test_cyclic_phis(ptr %ptr) {
140 ; CHECK-LABEL: @test_cyclic_phis
141 ; CHECK-NOT: vector.body:
147 %for.1 = phi i16 [ 22, %entry ], [ %for.2, %loop ]
148 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
149 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
150 %iv.next = add nuw nsw i64 %iv, 1
151 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
152 %for.1.next = load i16, ptr %gep.ptr, align 2
153 %add = add i16 %for.1, %for.2
154 store i16 %add, ptr %gep.ptr
155 %exitcond.not = icmp eq i64 %iv.next, 1000
156 br i1 %exitcond.not, label %exit, label %loop
162 define void @test_first_order_recurrences_incoming_cycle_preheader(ptr %ptr) {
163 ; CHECK-LABEL: @test_first_order_recurrences_incoming_cycle_preheader
164 ; CHECK: vector.body:
165 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
166 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 0>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
167 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
168 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
169 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
170 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
171 ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
172 ; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i16> [[TMP4]], <i16 10, i16 10, i16 10, i16 10>
173 ; CHECK-NEXT: store <4 x i16> [[TMP5]], ptr [[TMP2]], align 2
174 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
175 ; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
176 ; CHECK-NEXT: br i1 [[TMP7]], label %middle.block, label %vector.body
182 %p = phi i16 [ 0, %entry ], [ %p, %loop.1 ]
183 br i1 true, label %loop, label %loop.1
186 %for.1 = phi i16 [ %p, %loop.1 ], [ %for.1.next, %loop ]
187 %iv = phi i64 [ 0, %loop.1 ], [ %iv.next, %loop ]
188 %iv.next = add nuw nsw i64 %iv, 1
189 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
190 %for.1.next = load i16, ptr %gep.ptr, align 2
191 %add = add i16 %for.1, 10
192 store i16 %add, ptr %gep.ptr
193 %exitcond.not = icmp eq i64 %iv.next, 1000
194 br i1 %exitcond.not, label %exit, label %loop
200 define void @test_chained_first_order_recurrences_3_reordered_1(ptr %ptr) {
201 ; CHECK-LABEL: @test_chained_first_order_recurrences_3_reordered_1
202 ; CHECK: vector.body:
203 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
204 ; CHECK-NEXT: [[VECTOR_RECUR2:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP5:%.*]], %vector.body ]
205 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
206 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
207 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
208 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
209 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
210 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
211 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
212 ; CHECK-NEXT: [[TMP5]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
213 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR2]], <4 x i16> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
214 ; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i16> [[TMP4]], [[TMP5]]
215 ; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i16> [[TMP7]], [[TMP6]]
216 ; CHECK-NEXT: store <4 x i16> [[TMP8]], ptr [[TMP2]], align 2
217 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
218 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
219 ; CHECK-NEXT: br i1 [[TMP10]], label %middle.block, label %vector.body, !llvm.loop [[LOOP6:![0-9]+]]
220 ; CHECK: middle.block:
221 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
222 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3
223 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2
224 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
225 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI4:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
226 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
227 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
233 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ]
234 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
235 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
236 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
237 %iv.next = add nuw nsw i64 %iv, 1
238 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
239 %for.1.next = load i16, ptr %gep.ptr, align 2
240 %add.1 = add i16 %for.1, %for.2
241 %add.2 = add i16 %add.1, %for.3
242 store i16 %add.2, ptr %gep.ptr
243 %exitcond.not = icmp eq i64 %iv.next, 1000
244 br i1 %exitcond.not, label %exit, label %loop
250 define void @test_chained_first_order_recurrences_3_reordered_2(ptr %ptr) {
251 ; CHECK-LABEL: @test_chained_first_order_recurrences_3_reordered_2
252 ; CHECK: vector.body:
253 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
254 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
255 ; CHECK-NEXT: [[VECTOR_RECUR2:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP5:%.*]], %vector.body ]
256 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
257 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
258 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
259 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
260 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
261 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
262 ; CHECK-NEXT: [[TMP5]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
263 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR2]], <4 x i16> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
264 ; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i16> [[TMP4]], [[TMP5]]
265 ; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i16> [[TMP7]], [[TMP6]]
266 ; CHECK-NEXT: store <4 x i16> [[TMP8]], ptr [[TMP2]], align 2
267 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
268 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
269 ; CHECK-NEXT: br i1 [[TMP10]], label %middle.block, label %vector.body, !llvm.loop [[LOOP6:![0-9]+]]
270 ; CHECK: middle.block:
271 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
272 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
273 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI4:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
274 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3
275 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2
276 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
277 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
283 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
284 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ]
285 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
286 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
287 %iv.next = add nuw nsw i64 %iv, 1
288 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
289 %for.1.next = load i16, ptr %gep.ptr, align 2
290 %add.1 = add i16 %for.1, %for.2
291 %add.2 = add i16 %add.1, %for.3
292 store i16 %add.2, ptr %gep.ptr
293 %exitcond.not = icmp eq i64 %iv.next, 1000
294 br i1 %exitcond.not, label %exit, label %loop
300 define void @test_chained_first_order_recurrences_3_for2_no_other_uses(ptr %ptr) {
301 ; CHECK-LABEL: @test_chained_first_order_recurrences_3_for2_no_other_uses
302 ; CHECK: vector.body:
303 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
304 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
305 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
306 ; CHECK-NEXT: [[VECTOR_RECUR2:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP5:%.*]], %vector.body ]
307 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
308 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
309 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
310 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
311 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
312 ; CHECK-NEXT: [[TMP5]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
313 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR2]], <4 x i16> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
314 ; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i16> [[TMP4]], <i16 10, i16 10, i16 10, i16 10>
315 ; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i16> [[TMP7]], [[TMP6]]
316 ; CHECK-NEXT: store <4 x i16> [[TMP8]], ptr [[TMP2]], align 2
317 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
318 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
319 ; CHECK-NEXT: br i1 [[TMP10]], label %middle.block, label %vector.body, !llvm.loop [[LOOP6:![0-9]+]]
320 ; CHECK: middle.block:
321 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
322 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
323 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
324 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
325 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI4:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
326 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3
327 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2
333 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
334 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
335 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ]
336 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
337 %iv.next = add nuw nsw i64 %iv, 1
338 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
339 %for.1.next = load i16, ptr %gep.ptr, align 2
340 %add.1 = add i16 %for.1, 10
341 %add.2 = add i16 %add.1, %for.3
342 store i16 %add.2, ptr %gep.ptr
343 %exitcond.not = icmp eq i64 %iv.next, 1000
344 br i1 %exitcond.not, label %exit, label %loop
350 define void @test_chained_first_order_recurrences_3_for1_for2_no_other_uses(ptr %ptr) {
351 ; CHECK-LABEL: @test_chained_first_order_recurrences_3_for1_for2_no_other_uses
352 ; CHECK: vector.body:
353 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
354 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 22>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
355 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
356 ; CHECK-NEXT: [[VECTOR_RECUR2:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 33>, %vector.ph ], [ [[TMP5:%.*]], %vector.body ]
357 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
358 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 [[TMP0]]
359 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 0
360 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, ptr [[TMP2]], align 2
361 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
362 ; CHECK-NEXT: [[TMP5]] = shufflevector <4 x i16> [[VECTOR_RECUR1]], <4 x i16> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
363 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR2]], <4 x i16> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
364 ; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i16> [[TMP6]], <i16 10, i16 10, i16 10, i16 10>
365 ; CHECK-NEXT: store <4 x i16> [[TMP8]], ptr [[TMP2]], align 2
366 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
367 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
368 ; CHECK-NEXT: br i1 [[TMP10]], label %middle.block, label %vector.body, !llvm.loop [[LOOP6:![0-9]+]]
369 ; CHECK: middle.block:
370 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
371 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 3
372 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i16> [[WIDE_LOAD]], i32 2
373 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT3:%.*]] = extractelement <4 x i16> [[TMP4]], i32 3
374 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI4:%.*]] = extractelement <4 x i16> [[TMP4]], i32 2
375 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT7:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3
376 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI8:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2
382 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ]
383 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ]
384 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ]
385 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
386 %iv.next = add nuw nsw i64 %iv, 1
387 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
388 %for.1.next = load i16, ptr %gep.ptr, align 2
389 %add.1 = add i16 %for.3, 10
390 store i16 %add.1, ptr %gep.ptr
391 %exitcond.not = icmp eq i64 %iv.next, 1000
392 br i1 %exitcond.not, label %exit, label %loop
398 define void @test_chained_first_order_recurrence_sink_users_1(double* %ptr) {
399 ; CHECK-LABEL: @test_chained_first_order_recurrence_sink_users_1
400 ; CHECK: vector.body:
401 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
402 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x double> [ <double poison, double poison, double poison, double 1.000000e+01>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ]
403 ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x double> [ <double poison, double poison, double poison, double 2.000000e+01>, %vector.ph ], [ [[TMP4:%.*]], %vector.body ]
404 ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
405 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
406 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds double, ptr [[PTR:%.*]], i64 [[TMP0]]
407 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 0
408 ; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x double>, ptr [[TMP2]], align 8
409 ; CHECK-NEXT: [[TMP4]] = shufflevector <4 x double> [[VECTOR_RECUR]], <4 x double> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
410 ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x double> [[VECTOR_RECUR1]], <4 x double> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
411 ; CHECK-NEXT: [[TMP6:%.*]] = fadd <4 x double> <double 1.000000e+01, double 1.000000e+01, double 1.000000e+01, double 1.000000e+01>, [[TMP5]]
412 ; CHECK-NEXT: [[TMP7:%.*]] = fadd <4 x double> [[TMP6]], [[TMP4]]
413 ; CHECK-NEXT: store <4 x double> [[TMP7]], ptr [[TMP2]], align 8
414 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
415 ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 996
416 ; CHECK-NEXT: br i1 [[TMP9]], label %middle.block, label %vector.body, !llvm.loop [[LOOP10:![0-9]+]]
417 ; CHECK: middle.block:
418 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 999, 996
419 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x double> [[WIDE_LOAD]], i32 3
420 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x double> [[WIDE_LOAD]], i32 2
421 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT2:%.*]] = extractelement <4 x double> [[TMP4]], i32 3
422 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI3:%.*]] = extractelement <4 x double> [[TMP4]], i32 2
428 %for.1 = phi double [ 10.0, %entry ], [ %for.1.next, %loop ]
429 %for.2 = phi double [ 20.0, %entry ], [ %for.1, %loop ]
430 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
431 %add.1 = fadd double 10.0, %for.2
432 %add.2 = fadd double %add.1, %for.1
433 %iv.next = add nuw nsw i64 %iv, 1
434 %gep.ptr = getelementptr inbounds double, double* %ptr, i64 %iv
435 %for.1.next = load double, double* %gep.ptr, align 8
436 store double %add.2, double* %gep.ptr
437 %exitcond.not = icmp eq i64 %iv.next, 1000
438 br i1 %exitcond.not, label %exit, label %loop
444 define void @test_first_order_recurrences_and_reduction(ptr %ptr) {
445 ; CHECK-LABEL: @test_first_order_recurrences_and_reduction(
446 ; CHECK-NOT: vector.body:
452 %for.1 = phi i16 [ 22, %entry ], [ %red, %loop ]
453 %red = phi i16 [ 33, %entry ], [ %red.next, %loop ]
454 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
455 %iv.next = add nuw nsw i64 %iv, 1
456 %gep.ptr = getelementptr inbounds i16, ptr %ptr, i64 %iv
457 %lv = load i16, ptr %gep.ptr
458 %for.1.next = load i16, ptr %gep.ptr, align 2
459 %add.1 = add i16 %for.1, 10
460 %red.next = add i16 %red, %lv
461 store i16 %add.1, ptr %gep.ptr
462 %exitcond.not = icmp eq i64 %iv.next, 1000
463 br i1 %exitcond.not, label %exit, label %loop
469 define void @test_first_order_recurrences_and_induction(ptr %ptr) {
470 ; CHECK-LABEL: @test_first_order_recurrences_and_induction(
471 ; CHECK: vector.body:
472 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
473 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 22>, %vector.ph ], [ [[VEC_IND:%.*]], %vector.body ]
474 ; CHECK-NEXT: [[VEC_IND]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %vector.ph ], [ [[VEC_IND_NEXT:%.*]], %vector.body ]
475 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
476 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i64> [[VECTOR_RECUR]], <4 x i64> [[VEC_IND]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
477 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[PTR:%.*]], i64 [[TMP0]]
478 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
479 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 2
480 ; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i64> [[TMP1]], <i64 10, i64 10, i64 10, i64 10>
481 ; CHECK-NEXT: store <4 x i64> [[TMP4]], ptr [[TMP3]], align 4
482 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
483 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], <i64 4, i64 4, i64 4, i64 4>
484 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
485 ; CHECK-NEXT: br i1 [[TMP5]], label %middle.block, label %vector.body
486 ; CHECK: middle.block:
487 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
488 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3
489 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 2
490 ; CHECK-NEXT: br i1 [[CMP_N]]
496 %for.1 = phi i64 [ 22, %entry ], [ %iv, %loop ]
497 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
498 %iv.next = add nuw nsw i64 %iv, 1
499 %gep.ptr = getelementptr inbounds i64, ptr %ptr, i64 %iv
500 %for.1.next = load i64, ptr %gep.ptr, align 2
501 %add.1 = add i64 %for.1, 10
502 store i64 %add.1, ptr %gep.ptr
503 %exitcond.not = icmp eq i64 %iv.next, 1000
504 br i1 %exitcond.not, label %exit, label %loop
510 ; Same as @test_first_order_recurrences_and_induction but with order of phis
512 define void @test_first_order_recurrences_and_induction2(ptr %ptr) {
513 ; CHECK-LABEL: @test_first_order_recurrences_and_induction2(
514 ; CHECK: vector.body:
515 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
516 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %vector.ph ], [ [[VEC_IND_NEXT:%.*]], %vector.body ]
517 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 22>, %vector.ph ], [ [[VEC_IND]], %vector.body ]
518 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
519 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i64> [[VECTOR_RECUR]], <4 x i64> [[VEC_IND]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
520 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[PTR:%.*]], i64 [[TMP0]]
521 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
522 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 2
523 ; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i64> [[TMP1]], <i64 10, i64 10, i64 10, i64 10>
524 ; CHECK-NEXT: store <4 x i64> [[TMP4]], ptr [[TMP3]], align 4
525 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
526 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], <i64 4, i64 4, i64 4, i64 4>
527 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
528 ; CHECK-NEXT: br i1 [[TMP5]], label %middle.block, label %vector.body
529 ; CHECK: middle.block:
530 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
531 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 3
532 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i64> [[VEC_IND]], i32 2
533 ; CHECK-NEXT: br i1 [[CMP_N]]
539 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
540 %for.1 = phi i64 [ 22, %entry ], [ %iv, %loop ]
541 %iv.next = add nuw nsw i64 %iv, 1
542 %gep.ptr = getelementptr inbounds i64, ptr %ptr, i64 %iv
543 %for.1.next = load i64, ptr %gep.ptr, align 2
544 %add.1 = add i64 %for.1, 10
545 store i64 %add.1, ptr %gep.ptr
546 %exitcond.not = icmp eq i64 %iv.next, 1000
547 br i1 %exitcond.not, label %exit, label %loop
553 define void @test_first_order_recurrences_and_pointer_induction1(ptr %ptr) {
554 ; CHECK-LABEL: @test_first_order_recurrences_and_pointer_induction1(
556 ; CHECK-NEXT: [[IND_END:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 4000
557 ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
558 ; CHECK: vector.body:
559 ; CHECK-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[PTR]], %vector.ph ], [ [[PTR_IND:%.*]], %vector.body ]
560 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
561 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x ptr> [ <ptr poison, ptr poison, ptr poison, ptr null>, %vector.ph ], [ [[TMP0:%.*]], %vector.body ]
562 ; CHECK-NEXT: [[TMP0]] = getelementptr i8, ptr [[POINTER_PHI]], <4 x i64> <i64 0, i64 4, i64 8, i64 12>
563 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 0
564 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x ptr> [[VECTOR_RECUR]], <4 x ptr> [[TMP0]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
565 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds ptr, ptr [[PTR]], i64 [[TMP1]]
566 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i32 0
567 ; CHECK-NEXT: store <4 x ptr> [[TMP0]], ptr [[TMP4]], align 8
568 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
569 ; CHECK-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i64 16
570 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
571 ; CHECK-NEXT: br i1 [[TMP5]], label %middle.block, label %vector.body
572 ; CHECK: middle.block:
573 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
574 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x ptr> [[TMP0]], i32 3
575 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x ptr> [[TMP0]], i32 2
576 ; CHECK-NEXT: br i1 [[CMP_N]],
582 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
583 %for.1 = phi ptr [ null, %entry ], [ %ptr.iv, %loop ]
584 %ptr.iv = phi ptr [ %ptr, %entry ], [ %ptr.iv.next, %loop ]
585 %iv.next = add nuw nsw i64 %iv, 1
586 %gep.ptr = getelementptr inbounds ptr, ptr %ptr, i64 %iv
587 store ptr %ptr.iv, ptr %gep.ptr
588 %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
589 %exitcond.not = icmp eq i64 %iv.next, 1000
590 br i1 %exitcond.not, label %exit, label %loop
596 ; same as @test_first_order_recurrences_and_pointer_induction1 but with order
598 define void @test_first_order_recurrences_and_pointer_induction2(ptr %ptr) {
599 ; CHECK-LABEL: @test_first_order_recurrences_and_pointer_induction2(
601 ; CHECK-NEXT: [[IND_END:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 4000
602 ; CHECK-NEXT: br label %vector.body
603 ; CHECK: vector.body:
604 ; CHECK-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[PTR]], %vector.ph ], [ [[PTR_IND:%.*]], %vector.body ]
605 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
606 ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x ptr> [ <ptr poison, ptr poison, ptr poison, ptr null>, %vector.ph ], [ [[TMP0:%.*]], %vector.body ]
607 ; CHECK-NEXT: [[TMP0]] = getelementptr i8, ptr [[POINTER_PHI]], <4 x i64> <i64 0, i64 4, i64 8, i64 12>
608 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 0
609 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x ptr> [[VECTOR_RECUR]], <4 x ptr> [[TMP0]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
610 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds ptr, ptr [[PTR]], i64 [[TMP1]]
611 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[TMP3]], i32 0
612 ; CHECK-NEXT: store <4 x ptr> [[TMP0]], ptr [[TMP4]], align 8
613 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
614 ; CHECK-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i64 16
615 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
616 ; CHECK-NEXT: br i1 [[TMP5]], label %middle.block, label %vector.body
617 ; CHECK: middle.block:
618 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1000, 1000
619 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x ptr> [[TMP0]], i32 3
620 ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x ptr> [[TMP0]], i32 2
621 ; CHECK-NEXT: br i1 [[CMP_N]],
627 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
628 %ptr.iv = phi ptr [ %ptr, %entry ], [ %ptr.iv.next, %loop ]
629 %for.1 = phi ptr [ null, %entry ], [ %ptr.iv, %loop ]
630 %iv.next = add nuw nsw i64 %iv, 1
631 %gep.ptr = getelementptr inbounds ptr, ptr %ptr, i64 %iv
632 store ptr %ptr.iv, ptr %gep.ptr
633 %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
634 %exitcond.not = icmp eq i64 %iv.next, 1000
635 br i1 %exitcond.not, label %exit, label %loop