@@ -220,6 +220,72 @@ exit:
220220 ret i32 %res
221221}
222222
223+ define <4 x i32 > @test_vector_add_reduction (ptr %a , i64 %n ) {
224+ ; CHECK-LABEL: define <4 x i32> @test_vector_add_reduction(
225+ ; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {
226+ ; CHECK-NEXT: [[ENTRY:.*]]:
227+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N]], -1
228+ ; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[N]], 1
229+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
230+ ; CHECK-NEXT: br i1 [[TMP1]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]]
231+ ; CHECK: [[ENTRY_NEW]]:
232+ ; CHECK-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
233+ ; CHECK-NEXT: br label %[[LOOP:.*]]
234+ ; CHECK: [[LOOP]]:
235+ ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], %[[LOOP]] ]
236+ ; CHECK-NEXT: [[RDX_1:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY_NEW]] ], [ [[RDX_NEXT_1:%.*]], %[[LOOP]] ]
237+ ; CHECK-NEXT: [[RDX:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY_NEW]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]
238+ ; CHECK-NEXT: [[NITER:%.*]] = phi i64 [ 0, %[[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], %[[LOOP]] ]
239+ ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[A]], i64 [[IV]]
240+ ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[GEP_A]], align 16
241+ ; CHECK-NEXT: [[RDX_NEXT]] = add <4 x i32> [[RDX]], [[TMP2]]
242+ ; CHECK-NEXT: [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
243+ ; CHECK-NEXT: [[GEP_A_1:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[A]], i64 [[IV_NEXT]]
244+ ; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, ptr [[GEP_A_1]], align 16
245+ ; CHECK-NEXT: [[RDX_NEXT_1]] = add <4 x i32> [[RDX_1]], [[TMP3]]
246+ ; CHECK-NEXT: [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
247+ ; CHECK-NEXT: [[NITER_NEXT_1]] = add i64 [[NITER]], 2
248+ ; CHECK-NEXT: [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
249+ ; CHECK-NEXT: br i1 [[NITER_NCMP_1]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
250+ ; CHECK: [[EXIT_UNR_LCSSA]]:
251+ ; CHECK-NEXT: [[RES_PH:%.*]] = phi <4 x i32> [ [[RDX_NEXT_1]], %[[LOOP]] ]
252+ ; CHECK-NEXT: [[IV_UNR:%.*]] = phi i64 [ [[IV_NEXT_1]], %[[LOOP]] ]
253+ ; CHECK-NEXT: [[RDX_UNR:%.*]] = phi <4 x i32> [ [[RDX_NEXT_1]], %[[LOOP]] ]
254+ ; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i32> [[RDX_NEXT_1]], [[RDX_NEXT]]
255+ ; CHECK-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
256+ ; CHECK-NEXT: br i1 [[LCMP_MOD]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]]
257+ ; CHECK: [[LOOP_EPIL_PREHEADER]]:
258+ ; CHECK-NEXT: [[IV_EPIL_INIT:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_UNR]], %[[EXIT_UNR_LCSSA]] ]
259+ ; CHECK-NEXT: [[RDX_EPIL_INIT:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[BIN_RDX]], %[[EXIT_UNR_LCSSA]] ]
260+ ; CHECK-NEXT: [[LCMP_MOD2:%.*]] = icmp ne i64 [[XTRAITER]], 0
261+ ; CHECK-NEXT: call void @llvm.assume(i1 [[LCMP_MOD2]])
262+ ; CHECK-NEXT: br label %[[LOOP_EPIL:.*]]
263+ ; CHECK: [[LOOP_EPIL]]:
264+ ; CHECK-NEXT: [[GEP_A_EPIL:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[A]], i64 [[IV_EPIL_INIT]]
265+ ; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i32>, ptr [[GEP_A_EPIL]], align 16
266+ ; CHECK-NEXT: [[RDX_NEXT_EPIL:%.*]] = add <4 x i32> [[RDX_EPIL_INIT]], [[TMP4]]
267+ ; CHECK-NEXT: br label %[[EXIT]]
268+ ; CHECK: [[EXIT]]:
269+ ; CHECK-NEXT: [[RES:%.*]] = phi <4 x i32> [ [[BIN_RDX]], %[[EXIT_UNR_LCSSA]] ], [ [[RDX_NEXT_EPIL]], %[[LOOP_EPIL]] ]
270+ ; CHECK-NEXT: ret <4 x i32> [[RES]]
271+ ;
272+ entry:
273+ br label %loop
274+
275+ loop:
276+ %iv = phi i64 [ 0 , %entry ], [ %iv.next , %loop ]
277+ %rdx = phi <4 x i32 > [ zeroinitializer , %entry ], [ %rdx.next , %loop ]
278+ %gep.a = getelementptr inbounds nuw <4 x i32 >, ptr %a , i64 %iv
279+ %1 = load <4 x i32 >, ptr %gep.a , align 16
280+ %rdx.next = add <4 x i32 > %rdx , %1
281+ %iv.next = add nuw nsw i64 %iv , 1
282+ %ec = icmp eq i64 %iv.next , %n
283+ br i1 %ec , label %exit , label %loop , !llvm.loop !0
284+
285+ exit:
286+ %res = phi <4 x i32 > [ %rdx.next , %loop ]
287+ ret <4 x i32 > %res
288+ }
223289
224290
225291!0 = distinct !{!0 , !1 }
@@ -234,4 +300,5 @@ exit:
234300; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]}
235301; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
236302; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]]}
303+ ; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}
237304;.
0 commit comments