Skip to content

Commit b2c9464

Browse files
fhahnmahesh-attarde
authored andcommitted
[LV] Extend test coverage for tail-folding with recurrences.
Add additional test coverage for tail-folding loops with first-order recurrences and users outside the loop. Test a combination of vectorization factors and interleave counts. Also update check lines in reduction-order.ll and adjust naming for clarity. This adds extra test coverage for llvm#149042.
1 parent e54d6d0 commit b2c9464

File tree

2 files changed

+317
-43
lines changed

2 files changed

+317
-43
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
2+
; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -prefer-predicate-over-epilogue=predicate-dont-vectorize -S %s | FileCheck --check-prefix=VF2IC1 %s
3+
; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=2 -prefer-predicate-over-epilogue=predicate-dont-vectorize -S %s | FileCheck --check-prefix=VF2IC2 %s
4+
; RUN: opt -passes=loop-vectorize -force-vector-width=1 -force-vector-interleave=2 -prefer-predicate-over-epilogue=predicate-dont-vectorize -S %s | FileCheck --check-prefix=VF1IC2 %s
5+
6+
define i32 @FOR_used_outside(ptr noalias %A, ptr noalias %B, i64 %n) {
7+
; VF2IC1-LABEL: define i32 @FOR_used_outside(
8+
; VF2IC1-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
9+
; VF2IC1-NEXT: [[ENTRY:.*]]:
10+
; VF2IC1-NEXT: br label %[[LOOP:.*]]
11+
; VF2IC1: [[LOOP]]:
12+
; VF2IC1-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
13+
; VF2IC1-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
14+
; VF2IC1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP1]]
15+
; VF2IC1-NEXT: [[TMP10]] = load i32, ptr [[TMP9]], align 4
16+
; VF2IC1-NEXT: [[TMP23:%.*]] = add nsw i32 [[FOR]], [[TMP10]]
17+
; VF2IC1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP1]]
18+
; VF2IC1-NEXT: store i32 [[TMP23]], ptr [[TMP20]], align 4
19+
; VF2IC1-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP1]], 1
20+
; VF2IC1-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
21+
; VF2IC1-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
22+
; VF2IC1: [[FOR_END]]:
23+
; VF2IC1-NEXT: [[TMP32:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
24+
; VF2IC1-NEXT: ret i32 [[TMP32]]
25+
;
26+
; VF2IC2-LABEL: define i32 @FOR_used_outside(
27+
; VF2IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
28+
; VF2IC2-NEXT: [[ENTRY:.*]]:
29+
; VF2IC2-NEXT: br label %[[LOOP:.*]]
30+
; VF2IC2: [[LOOP]]:
31+
; VF2IC2-NEXT: [[TMP3:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
32+
; VF2IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP23:%.*]], %[[LOOP]] ]
33+
; VF2IC2-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP3]]
34+
; VF2IC2-NEXT: [[TMP23]] = load i32, ptr [[TMP22]], align 4
35+
; VF2IC2-NEXT: [[TMP47:%.*]] = add nsw i32 [[FOR]], [[TMP23]]
36+
; VF2IC2-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP3]]
37+
; VF2IC2-NEXT: store i32 [[TMP47]], ptr [[TMP44]], align 4
38+
; VF2IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP3]], 1
39+
; VF2IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
40+
; VF2IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
41+
; VF2IC2: [[FOR_END]]:
42+
; VF2IC2-NEXT: [[TMP66:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
43+
; VF2IC2-NEXT: ret i32 [[TMP66]]
44+
;
45+
; VF1IC2-LABEL: define i32 @FOR_used_outside(
46+
; VF1IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
47+
; VF1IC2-NEXT: [[ENTRY:.*]]:
48+
; VF1IC2-NEXT: br label %[[LOOP:.*]]
49+
; VF1IC2: [[LOOP]]:
50+
; VF1IC2-NEXT: [[TMP0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
51+
; VF1IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP7:%.*]], %[[LOOP]] ]
52+
; VF1IC2-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP0]]
53+
; VF1IC2-NEXT: [[TMP7]] = load i32, ptr [[TMP6]], align 4
54+
; VF1IC2-NEXT: [[TMP12:%.*]] = add nsw i32 [[FOR]], [[TMP7]]
55+
; VF1IC2-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP0]]
56+
; VF1IC2-NEXT: store i32 [[TMP12]], ptr [[TMP11]], align 4
57+
; VF1IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP0]], 1
58+
; VF1IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
59+
; VF1IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
60+
; VF1IC2: [[FOR_END]]:
61+
; VF1IC2-NEXT: [[TMP30:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
62+
; VF1IC2-NEXT: ret i32 [[TMP30]]
63+
;
64+
entry:
65+
br label %loop
66+
67+
loop:
68+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
69+
%for = phi i32 [ 33, %entry ], [ %for.next, %loop ]
70+
%gep.A = getelementptr inbounds nuw i32, ptr %A, i64 %iv
71+
%for.next = load i32, ptr %gep.A, align 4
72+
%add = add nsw i32 %for, %for.next
73+
%gep.B = getelementptr inbounds nuw i32, ptr %B, i64 %iv
74+
store i32 %add, ptr %gep.B, align 4
75+
%iv.next = add nuw nsw i64 %iv, 1
76+
%ec = icmp eq i64 %iv.next, %n
77+
br i1 %ec, label %for.end, label %loop
78+
79+
for.end:
80+
ret i32 %for
81+
}
82+
83+
define i32 @FOR_next_used_outside(ptr noalias %A, ptr noalias %B, i64 %n) {
84+
; VF2IC1-LABEL: define i32 @FOR_next_used_outside(
85+
; VF2IC1-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
86+
; VF2IC1-NEXT: [[ENTRY:.*]]:
87+
; VF2IC1-NEXT: br label %[[LOOP:.*]]
88+
; VF2IC1: [[LOOP]]:
89+
; VF2IC1-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
90+
; VF2IC1-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
91+
; VF2IC1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP1]]
92+
; VF2IC1-NEXT: [[TMP10]] = load i32, ptr [[TMP9]], align 4
93+
; VF2IC1-NEXT: [[TMP23:%.*]] = add nsw i32 [[FOR]], [[TMP10]]
94+
; VF2IC1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP1]]
95+
; VF2IC1-NEXT: store i32 [[TMP23]], ptr [[TMP20]], align 4
96+
; VF2IC1-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP1]], 1
97+
; VF2IC1-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
98+
; VF2IC1-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
99+
; VF2IC1: [[FOR_END]]:
100+
; VF2IC1-NEXT: [[TMP28:%.*]] = phi i32 [ [[TMP10]], %[[LOOP]] ]
101+
; VF2IC1-NEXT: ret i32 [[TMP28]]
102+
;
103+
; VF2IC2-LABEL: define i32 @FOR_next_used_outside(
104+
; VF2IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
105+
; VF2IC2-NEXT: [[ENTRY:.*]]:
106+
; VF2IC2-NEXT: br label %[[LOOP:.*]]
107+
; VF2IC2: [[LOOP]]:
108+
; VF2IC2-NEXT: [[TMP3:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
109+
; VF2IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP23:%.*]], %[[LOOP]] ]
110+
; VF2IC2-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP3]]
111+
; VF2IC2-NEXT: [[TMP23]] = load i32, ptr [[TMP22]], align 4
112+
; VF2IC2-NEXT: [[TMP47:%.*]] = add nsw i32 [[FOR]], [[TMP23]]
113+
; VF2IC2-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP3]]
114+
; VF2IC2-NEXT: store i32 [[TMP47]], ptr [[TMP44]], align 4
115+
; VF2IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP3]], 1
116+
; VF2IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
117+
; VF2IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
118+
; VF2IC2: [[FOR_END]]:
119+
; VF2IC2-NEXT: [[TMP62:%.*]] = phi i32 [ [[TMP23]], %[[LOOP]] ]
120+
; VF2IC2-NEXT: ret i32 [[TMP62]]
121+
;
122+
; VF1IC2-LABEL: define i32 @FOR_next_used_outside(
123+
; VF1IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
124+
; VF1IC2-NEXT: [[ENTRY:.*]]:
125+
; VF1IC2-NEXT: br label %[[LOOP:.*]]
126+
; VF1IC2: [[LOOP]]:
127+
; VF1IC2-NEXT: [[TMP0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
128+
; VF1IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP7:%.*]], %[[LOOP]] ]
129+
; VF1IC2-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP0]]
130+
; VF1IC2-NEXT: [[TMP7]] = load i32, ptr [[TMP6]], align 4
131+
; VF1IC2-NEXT: [[TMP12:%.*]] = add nsw i32 [[FOR]], [[TMP7]]
132+
; VF1IC2-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP0]]
133+
; VF1IC2-NEXT: store i32 [[TMP12]], ptr [[TMP11]], align 4
134+
; VF1IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP0]], 1
135+
; VF1IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
136+
; VF1IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
137+
; VF1IC2: [[FOR_END]]:
138+
; VF1IC2-NEXT: [[TMP27:%.*]] = phi i32 [ [[TMP7]], %[[LOOP]] ]
139+
; VF1IC2-NEXT: ret i32 [[TMP27]]
140+
;
141+
entry:
142+
br label %loop
143+
144+
loop:
145+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
146+
%for = phi i32 [ 33, %entry ], [ %for.next, %loop ]
147+
%gep.A = getelementptr inbounds nuw i32, ptr %A, i64 %iv
148+
%for.next = load i32, ptr %gep.A, align 4
149+
%add = add nsw i32 %for, %for.next
150+
%gep.B = getelementptr inbounds nuw i32, ptr %B, i64 %iv
151+
store i32 %add, ptr %gep.B, align 4
152+
%iv.next = add nuw nsw i64 %iv, 1
153+
%ec = icmp eq i64 %iv.next, %n
154+
br i1 %ec, label %for.end, label %loop
155+
156+
for.end:
157+
ret i32 %for.next
158+
}
159+
160+
define i32 @FOR_and_next_used_outside(ptr noalias %A, ptr noalias %B, i64 %n) {
161+
; VF2IC1-LABEL: define i32 @FOR_and_next_used_outside(
162+
; VF2IC1-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
163+
; VF2IC1-NEXT: [[ENTRY:.*]]:
164+
; VF2IC1-NEXT: br label %[[LOOP:.*]]
165+
; VF2IC1: [[LOOP]]:
166+
; VF2IC1-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
167+
; VF2IC1-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP10:%.*]], %[[LOOP]] ]
168+
; VF2IC1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP1]]
169+
; VF2IC1-NEXT: [[TMP10]] = load i32, ptr [[TMP9]], align 4
170+
; VF2IC1-NEXT: [[TMP23:%.*]] = add nsw i32 [[FOR]], [[TMP10]]
171+
; VF2IC1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP1]]
172+
; VF2IC1-NEXT: store i32 [[TMP23]], ptr [[TMP20]], align 4
173+
; VF2IC1-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP1]], 1
174+
; VF2IC1-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
175+
; VF2IC1-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
176+
; VF2IC1: [[FOR_END]]:
177+
; VF2IC1-NEXT: [[TMP32:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
178+
; VF2IC1-NEXT: [[TMP33:%.*]] = phi i32 [ [[TMP10]], %[[LOOP]] ]
179+
; VF2IC1-NEXT: [[RES:%.*]] = add i32 [[TMP32]], [[TMP33]]
180+
; VF2IC1-NEXT: ret i32 [[RES]]
181+
;
182+
; VF2IC2-LABEL: define i32 @FOR_and_next_used_outside(
183+
; VF2IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
184+
; VF2IC2-NEXT: [[ENTRY:.*]]:
185+
; VF2IC2-NEXT: br label %[[LOOP:.*]]
186+
; VF2IC2: [[LOOP]]:
187+
; VF2IC2-NEXT: [[TMP3:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
188+
; VF2IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP23:%.*]], %[[LOOP]] ]
189+
; VF2IC2-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP3]]
190+
; VF2IC2-NEXT: [[TMP23]] = load i32, ptr [[TMP22]], align 4
191+
; VF2IC2-NEXT: [[TMP47:%.*]] = add nsw i32 [[FOR]], [[TMP23]]
192+
; VF2IC2-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP3]]
193+
; VF2IC2-NEXT: store i32 [[TMP47]], ptr [[TMP44]], align 4
194+
; VF2IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP3]], 1
195+
; VF2IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
196+
; VF2IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
197+
; VF2IC2: [[FOR_END]]:
198+
; VF2IC2-NEXT: [[TMP66:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
199+
; VF2IC2-NEXT: [[TMP71:%.*]] = phi i32 [ [[TMP23]], %[[LOOP]] ]
200+
; VF2IC2-NEXT: [[RES:%.*]] = add i32 [[TMP66]], [[TMP71]]
201+
; VF2IC2-NEXT: ret i32 [[RES]]
202+
;
203+
; VF1IC2-LABEL: define i32 @FOR_and_next_used_outside(
204+
; VF1IC2-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) {
205+
; VF1IC2-NEXT: [[ENTRY:.*]]:
206+
; VF1IC2-NEXT: br label %[[LOOP:.*]]
207+
; VF1IC2: [[LOOP]]:
208+
; VF1IC2-NEXT: [[TMP0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
209+
; VF1IC2-NEXT: [[FOR:%.*]] = phi i32 [ 33, %[[ENTRY]] ], [ [[TMP7:%.*]], %[[LOOP]] ]
210+
; VF1IC2-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP0]]
211+
; VF1IC2-NEXT: [[TMP7]] = load i32, ptr [[TMP6]], align 4
212+
; VF1IC2-NEXT: [[TMP12:%.*]] = add nsw i32 [[FOR]], [[TMP7]]
213+
; VF1IC2-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i64 [[TMP0]]
214+
; VF1IC2-NEXT: store i32 [[TMP12]], ptr [[TMP11]], align 4
215+
; VF1IC2-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[TMP0]], 1
216+
; VF1IC2-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
217+
; VF1IC2-NEXT: br i1 [[EC]], label %[[FOR_END:.*]], label %[[LOOP]]
218+
; VF1IC2: [[FOR_END]]:
219+
; VF1IC2-NEXT: [[TMP30:%.*]] = phi i32 [ [[FOR]], %[[LOOP]] ]
220+
; VF1IC2-NEXT: [[TMP33:%.*]] = phi i32 [ [[TMP7]], %[[LOOP]] ]
221+
; VF1IC2-NEXT: [[RES:%.*]] = add i32 [[TMP30]], [[TMP33]]
222+
; VF1IC2-NEXT: ret i32 [[RES]]
223+
;
224+
entry:
225+
br label %loop
226+
227+
loop:
228+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
229+
%for = phi i32 [ 33, %entry ], [ %for.next, %loop ]
230+
%gep.A = getelementptr inbounds nuw i32, ptr %A, i64 %iv
231+
%for.next = load i32, ptr %gep.A, align 4
232+
%add = add nsw i32 %for, %for.next
233+
%gep.B = getelementptr inbounds nuw i32, ptr %B, i64 %iv
234+
store i32 %add, ptr %gep.B, align 4
235+
%iv.next = add nuw nsw i64 %iv, 1
236+
%ec = icmp eq i64 %iv.next, %n
237+
br i1 %ec, label %for.end, label %loop
238+
239+
for.end:
240+
%res = add i32 %for, %for.next
241+
ret i32 %res
242+
}
243+
244+

llvm/test/Transforms/LoopVectorize/reduction-order.ll

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,93 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
12
; RUN: opt -passes='loop-vectorize' -force-vector-width=4 -force-vector-interleave=1 -S < %s 2>&1 | FileCheck %s
23

34
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
45

56
; Make sure the selects generated from reduction are always emitted
67
; in deterministic order.
7-
; CHECK-LABEL: @foo(
8-
; CHECK: vector.body:
9-
; CHECK: [[VEC_PHI_1:%.+]] = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ [[ADD_5:%.+]], %vector.body ]
10-
; CHECK: [[VEC_PHI_2:%.+]] = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ [[ADD_3:%.+]], %vector.body ]
11-
; CHECK: icmp ule <4 x i64>
12-
; CHECK-NEXT: [[ADD_3]] = add <4 x i32> splat (i32 3), [[VEC_PHI_2]]
13-
; CHECK-NEXT: [[ADD_5]] = add <4 x i32> [[VEC_PHI_1]], splat (i32 5)
14-
; CHECK: select <4 x i1> {{.*}}, <4 x i32> [[ADD_5]], <4 x i32>
15-
; CHECK-NEXT: select <4 x i1> {{.*}}, <4 x i32> [[ADD_3]], <4 x i32>
16-
; CHECK: br i1 {{.*}}, label %middle.block, label %vector.body
178
;
18-
define internal i64 @foo(ptr %t0) !prof !1 {
19-
t16:
20-
br label %t20
21-
22-
t17: ; preds = %t20
23-
%t18 = phi i32 [ %t24, %t20 ]
24-
%t19 = phi i32 [ %t28, %t20 ]
25-
br label %t31
9+
define i32 @foo() !prof !1 {
10+
; CHECK-LABEL: define i32 @foo() {{.*}}{
11+
; CHECK-NEXT: [[T16:.*:]]
12+
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
13+
; CHECK: [[VECTOR_PH]]:
14+
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
15+
; CHECK: [[VECTOR_BODY]]:
16+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
17+
; CHECK-NEXT: [[VEC_PHI_1:%.*]] = phi <4 x i32> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[ADD_5:%.*]], %[[VECTOR_BODY]] ]
18+
; CHECK-NEXT: [[VEC_PHI_2:%.*]] = phi <4 x i32> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[ADD_3:%.*]], %[[VECTOR_BODY]] ]
19+
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i64 0
20+
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
21+
; CHECK-NEXT: [[VEC_IV:%.*]] = add <4 x i64> [[BROADCAST_SPLAT]], <i64 0, i64 1, i64 2, i64 3>
22+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule <4 x i64> [[VEC_IV]], splat (i64 9)
23+
; CHECK-NEXT: [[ADD_3]] = add <4 x i32> splat (i32 3), [[VEC_PHI_2]]
24+
; CHECK-NEXT: [[ADD_5]] = add <4 x i32> [[VEC_PHI_1]], splat (i32 5)
25+
; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD_5]], <4 x i32> [[VEC_PHI_1]]
26+
; CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD_3]], <4 x i32> [[VEC_PHI_2]]
27+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
28+
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 12
29+
; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]]
30+
; CHECK: [[MIDDLE_BLOCK]]:
31+
; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP3]])
32+
; CHECK-NEXT: [[TMP7:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP4]])
33+
; CHECK-NEXT: br label %[[EXIT:.*]]
34+
; CHECK: [[EXIT]]:
35+
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP7]], [[TMP6]]
36+
; CHECK-NEXT: ret i32 [[ADD]]
37+
;
38+
entry:
39+
br label %loop
2640

27-
t20: ; preds = %t20, %t16
28-
%t21 = phi i64 [ 0, %t16 ], [ %t29, %t20 ]
29-
%t22 = phi i32 [ 0, %t16 ], [ %t28, %t20 ]
30-
%t23 = phi i32 [ 0, %t16 ], [ %t24, %t20 ]
31-
%t24 = add i32 3, %t23
32-
%t28 = add i32 %t22, 5
33-
%t29 = add nuw nsw i64 %t21, 1
34-
%t30 = icmp eq i64 %t29, 10
35-
br i1 %t30, label %t17, label %t20, !prof !2
41+
loop:
42+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
43+
%red.1 = phi i32 [ 0, %entry ], [ %red.1.next, %loop ]
44+
%red.2 = phi i32 [ 0, %entry ], [ %red.2.next, %loop ]
45+
%red.2.next = add i32 3, %red.2
46+
%red.1.next = add i32 %red.1, 5
47+
%iv.next = add nuw nsw i64 %iv, 1
48+
%ec = icmp eq i64 %iv.next, 10
49+
br i1 %ec, label %exit, label %loop, !prof !2
3650

37-
t31:
38-
ret i64 undef
51+
exit:
52+
%r.2 = phi i32 [ %red.2.next, %loop ]
53+
%r.1 = phi i32 [ %red.1.next, %loop ]
54+
%add = add i32 %r.2, %r.1
55+
ret i32 %add
3956
}
4057

4158
; Make sure we do not fail when checking for ordered reduction. This test just
4259
; exercises the path and bails out without performing vectorization.
43-
; CHECK-LABEL: quux
44-
; CHECK-NOT: fadd <4 x
45-
define void @quux(i1 %arg) {
46-
bb:
60+
define double @quux(i1 %arg) {
61+
; CHECK-LABEL: define double @quux(
62+
; CHECK-SAME: i1 [[ARG:%.*]]) {
63+
; CHECK-NEXT: [[ENTRY:.*]]:
64+
; CHECK-NEXT: br label %[[HEADER:.*]]
65+
; CHECK: [[HEADER]]:
66+
; CHECK-NEXT: [[TMP5:%.*]] = phi double [ 1.300000e+01, %[[ENTRY]] ], [ [[TMP:%.*]], %[[LATCH:.*]] ]
67+
; CHECK-NEXT: [[TMP6:%.*]] = fadd double [[TMP5]], 1.000000e+00
68+
; CHECK-NEXT: br label %[[LATCH]]
69+
; CHECK: [[LATCH]]:
70+
; CHECK-NEXT: [[TMP]] = phi double [ [[TMP6]], %[[HEADER]] ]
71+
; CHECK-NEXT: br i1 [[ARG]], label %[[HEADER]], label %[[EXIT:.*]]
72+
; CHECK: [[EXIT]]:
73+
; CHECK-NEXT: [[R:%.*]] = phi double [ [[TMP]], %[[LATCH]] ]
74+
; CHECK-NEXT: ret double [[R]]
75+
;
76+
entry:
4777
br label %header
4878

49-
latch: ; preds = %header
50-
%tmp = phi double [ %tmp6, %header ]
51-
br i1 %arg, label %header, label %bb2
52-
53-
bb2: ; preds = %latch
54-
%tmp3 = phi double [ %tmp, %latch ]
55-
ret void
56-
57-
header: ; preds = %latch, %bb
58-
%tmp5 = phi double [ 1.300000e+01, %bb ], [ %tmp, %latch ]
79+
header:
80+
%tmp5 = phi double [ 1.300000e+01, %entry ], [ %tmp, %latch ]
5981
%tmp6 = fadd double %tmp5, 1.000000e+00
6082
br label %latch
83+
84+
latch:
85+
%tmp = phi double [ %tmp6, %header ]
86+
br i1 %arg, label %header, label %exit
87+
88+
exit:
89+
%r = phi double [ %tmp, %latch ]
90+
ret double %r
6191
}
6292

6393
!1 = !{!"function_entry_count", i64 801}

0 commit comments

Comments
 (0)