[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / first-order-recurrence-chains.ll
blob6e054809fbb9507c9db40fb4366d53e611100065
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
5 ; CHECK:       vector.body:
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
27 entry:
28   br label %loop
30 loop:
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
42 exit:
43   ret void
46 define void @test_chained_first_order_recurrences_2(ptr %ptr) {
47 ; CHECK-LABEL: @test_chained_first_order_recurrences_2
48 ; CHECK:       vector.body:
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
70 entry:
71   br label %loop
73 loop:
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
85 exit:
86   ret void
89 define void @test_chained_first_order_recurrences_3(ptr %ptr) {
90 ; CHECK-LABEL: @test_chained_first_order_recurrences_3
91 ; CHECK:       vector.body:
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
118 entry:
119   br label %loop
121 loop:
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
135 exit:
136   ret void
139 define void @test_cyclic_phis(ptr %ptr) {
140 ; CHECK-LABEL: @test_cyclic_phis
141 ; CHECK-NOT: vector.body:
143 entry:
144   br label %loop
146 loop:
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
158 exit:
159   ret void
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
178 entry:
179   br label %loop.1
181 loop.1:
182   %p = phi i16 [ 0, %entry ], [ %p, %loop.1 ]
183   br i1 true, label %loop, label %loop.1
185 loop:
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
196 exit:
197   ret void
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
229 entry:
230   br label %loop
232 loop:
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
246 exit:
247   ret void
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
279 entry:
280   br label %loop
282 loop:
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
296 exit:
297   ret void
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
329 entry:
330   br label %loop
332 loop:
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
346 exit:
347   ret void
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
378 entry:
379   br label %loop
381 loop:
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
394 exit:
395   ret void
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
424 entry:
425   br label %loop
427 loop:
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
440 exit:
441   ret void
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:
448 entry:
449   br label %loop
451 loop:
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
465 exit:
466   ret void
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]]
492 entry:
493   br label %loop
495 loop:
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
506 exit:
507   ret void
510 ; Same as @test_first_order_recurrences_and_induction but with order of phis
511 ; flipped.
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]]
535 entry:
536   br label %loop
538 loop:
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
549 exit:
550   ret void
553 define void @test_first_order_recurrences_and_pointer_induction1(ptr %ptr) {
554 ; CHECK-LABEL: @test_first_order_recurrences_and_pointer_induction1(
555 ; CHECK:       vector.ph:
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]],
578 entry:
579   br label %loop
581 loop:
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
592 exit:
593   ret void
596 ; same as @test_first_order_recurrences_and_pointer_induction1 but with order
597 ; of phis flipped.
598 define void @test_first_order_recurrences_and_pointer_induction2(ptr %ptr) {
599 ; CHECK-LABEL: @test_first_order_recurrences_and_pointer_induction2(
600 ; CHECK:       vector.ph:
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]],
623 entry:
624   br label %loop
626 loop:
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
637 exit:
638   ret void