Skip to content

Commit 34d5bcd

Browse files
authored
[VPlan] Add VPlan printing test for epilogue vectorization (NFC). (#219578)
Print the final VPlans for the main and the epilogue vector loop, to show what epilogue vectorization models in VPlan and what is left to be patched up in the generated IR after executing the plans.
1 parent 02c5537 commit 34d5bcd

1 file changed

Lines changed: 301 additions & 0 deletions

File tree

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
; RUN: opt -passes=loop-vectorize -force-vector-width=8 -enable-epilogue-vectorization \
2+
; RUN: -epilogue-vectorization-force-VF=4 -vplan-print-metadata=false -disable-output \
3+
; RUN: -vplan-print-after=printFinalVPlan %s 2>&1 | FileCheck %s
4+
5+
; Check how plans for epilogue vectorization are represented in VPlan.
6+
7+
define i64 @resume_values(ptr noalias %A, i64 %n) {
8+
; CHECK-LABEL: VPlan for loop in 'resume_values'
9+
; CHECK: VPlan 'Final VPlan for VF={8},UF={1}' {
10+
; CHECK-NEXT: Live-in ir<%n> = original trip-count
11+
; CHECK-EMPTY:
12+
; CHECK-NEXT: ir-bb<entry>:
13+
; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%n>, ir<4>
14+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>
15+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.main.loop.iter.check
16+
; CHECK-EMPTY:
17+
; CHECK-NEXT: vector.main.loop.iter.check:
18+
; CHECK-NEXT: EMIT vp<%min.iters.check>.1 = icmp ult ir<%n>, ir<8>
19+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>.1
20+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph
21+
; CHECK-EMPTY:
22+
; CHECK-NEXT: vector.ph:
23+
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = and ir<%n>, ir<7>
24+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%n>, vp<[[VP4]]>
25+
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = reduction-start-vector ir<5>, ir<0>, ir<1>
26+
; CHECK-NEXT: Successor(s): vector.body
27+
; CHECK-EMPTY:
28+
; CHECK-NEXT: vector.body:
29+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
30+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi (add) vp<[[VP5]]>, ir<%red.next>
31+
; CHECK-NEXT: CLONE ir<%gep> = getelementptr inbounds ir<%A>, vp<%index>
32+
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep>
33+
; CHECK-NEXT: WIDEN ir<%red.next> = add ir<%red>, ir<%l>
34+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<8>
35+
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec>
36+
; CHECK-NEXT: EMIT branch-on-cond vp<[[VP6]]>
37+
; CHECK-NEXT: Successor(s): middle.block, vector.body
38+
; CHECK-EMPTY:
39+
; CHECK-NEXT: middle.block:
40+
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = compute-reduction-result (add) ir<%red.next>
41+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<%n.vec>
42+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
43+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<scalar.ph>
44+
; CHECK-EMPTY:
45+
; CHECK-NEXT: ir-bb<exit>:
46+
; CHECK-NEXT: IR %red.next.lcssa = phi i64 [ %red.next, %loop ] (extra operand: vp<[[VP8]]> from middle.block)
47+
; CHECK-NEXT: No successors
48+
; CHECK-EMPTY:
49+
; CHECK-NEXT: ir-bb<scalar.ph>:
50+
; CHECK-NEXT: EMIT-SCALAR vp<%vec.epilog.resume.val> = phi [ vp<%n.vec>, middle.block ], [ ir<0>, ir-bb<entry> ], [ ir<0>, vector.main.loop.iter.check ]
51+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP8]]>, middle.block ], [ ir<5>, ir-bb<entry> ], [ ir<5>, vector.main.loop.iter.check ]
52+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP10:%[0-9]+]]> = resume-for-epilogue vp<%vec.epilog.resume.val>, ir<0>
53+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP11:%[0-9]+]]> = resume-for-epilogue vp<%vec.epilog.resume.val>, ir<0>
54+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP12:%[0-9]+]]> = resume-for-epilogue vp<%bc.merge.rdx>, ir<5>
55+
; CHECK-NEXT: Successor(s): ir-bb<loop>
56+
; CHECK-EMPTY:
57+
; CHECK-NEXT: ir-bb<loop>:
58+
; CHECK-NEXT: IR %iv = phi i64 [ 0, %scalar.ph ], [ %iv.next, %loop ] (extra operand: vp<%vec.epilog.resume.val> from ir-bb<scalar.ph>)
59+
; CHECK-NEXT: IR %red = phi i64 [ 5, %scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<scalar.ph>)
60+
; CHECK-NEXT: IR %gep = getelementptr inbounds i64, ptr %A, i64 %iv
61+
; CHECK-NEXT: IR %l = load i64, ptr %gep, align 4
62+
; CHECK-NEXT: IR %red.next = add i64 %red, %l
63+
; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
64+
; CHECK-NEXT: IR %ec = icmp eq i64 %iv.next, %n
65+
; CHECK-NEXT: No successors
66+
; CHECK-NEXT: }
67+
;
68+
; CHECK-LABEL: VPlan for loop in 'resume_values'
69+
; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' {
70+
; CHECK-NEXT: Live-in ir<%n> = original trip-count
71+
; CHECK-EMPTY:
72+
; CHECK-NEXT: ir-bb<vec.epilog.iter.check>:
73+
; CHECK-NEXT: IR %vec.epilog.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %iter.check ], [ 0, %vector.main.loop.iter.check ]
74+
; CHECK-NEXT: IR %bc.merge.rdx = phi i64 [ %4, %middle.block ], [ 5, %iter.check ], [ 5, %vector.main.loop.iter.check ]
75+
; CHECK-NEXT: EMIT vp<%min.epilog.iters.check> = icmp ult ir<%0>, ir<4>
76+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.epilog.iters.check>
77+
; CHECK-NEXT: Successor(s): ir-bb<vec.epilog.scalar.ph>, vec.epilog.ph
78+
; CHECK-EMPTY:
79+
; CHECK-NEXT: vec.epilog.ph:
80+
; CHECK-NEXT: EMIT vp<[[VP3:%[0-9]+]]> = and ir<%n>, ir<3>
81+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%n>, vp<[[VP3]]>
82+
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = reduction-start-vector ir<%bc.merge.rdx>, ir<0>, ir<1>
83+
; CHECK-NEXT: Successor(s): vec.epilog.vector.body
84+
; CHECK-EMPTY:
85+
; CHECK-NEXT: vec.epilog.vector.body:
86+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<%vec.epilog.resume.val>, vec.epilog.ph ], [ vp<%index.next>, vec.epilog.vector.body ]
87+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi (add) vp<[[VP4]]>, ir<%red.next>
88+
; CHECK-NEXT: CLONE ir<%gep> = getelementptr inbounds ir<%A>, vp<%index>
89+
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep>
90+
; CHECK-NEXT: WIDEN ir<%red.next> = add ir<%red>, ir<%l>
91+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<4>
92+
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec>
93+
; CHECK-NEXT: EMIT branch-on-cond vp<[[VP5]]>
94+
; CHECK-NEXT: Successor(s): vec.epilog.middle.block, vec.epilog.vector.body
95+
; CHECK-EMPTY:
96+
; CHECK-NEXT: vec.epilog.middle.block:
97+
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = compute-reduction-result (add) ir<%red.next>
98+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<%n.vec>
99+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
100+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<vec.epilog.scalar.ph>
101+
; CHECK-EMPTY:
102+
; CHECK-NEXT: ir-bb<exit>:
103+
; CHECK-NEXT: IR %red.next.lcssa = phi i64 [ %red.next, %loop ], [ %4, %middle.block ] (extra operand: vp<[[VP7]]> from vec.epilog.middle.block)
104+
; CHECK-NEXT: No successors
105+
; CHECK-EMPTY:
106+
; CHECK-NEXT: ir-bb<vec.epilog.scalar.ph>:
107+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%n.vec>, vec.epilog.middle.block ], [ ir<0>, ir-bb<vec.epilog.iter.check> ]
108+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP7]]>, vec.epilog.middle.block ], [ ir<5>, ir-bb<vec.epilog.iter.check> ]
109+
; CHECK-NEXT: Successor(s): ir-bb<loop>
110+
; CHECK-EMPTY:
111+
; CHECK-NEXT: ir-bb<loop>:
112+
; CHECK-NEXT: IR %iv = phi i64 [ %vec.epilog.resume.val, %vec.epilog.scalar.ph ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from ir-bb<vec.epilog.scalar.ph>)
113+
; CHECK-NEXT: IR %red = phi i64 [ %bc.merge.rdx, %vec.epilog.scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<vec.epilog.scalar.ph>)
114+
; CHECK-NEXT: IR %gep = getelementptr inbounds i64, ptr %A, i64 %iv
115+
; CHECK-NEXT: IR %l = load i64, ptr %gep, align 4
116+
; CHECK-NEXT: IR %red.next = add i64 %red, %l
117+
; CHECK-NEXT: IR %iv.next = add i64 %iv, 1
118+
; CHECK-NEXT: IR %ec = icmp eq i64 %iv.next, %n
119+
; CHECK-NEXT: No successors
120+
; CHECK-NEXT: }
121+
;
122+
entry:
123+
br label %loop
124+
125+
loop:
126+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
127+
%red = phi i64 [ 5, %entry ], [ %red.next, %loop ]
128+
%gep = getelementptr inbounds i64, ptr %A, i64 %iv
129+
%l = load i64, ptr %gep
130+
%red.next = add i64 %red, %l
131+
%iv.next = add i64 %iv, 1
132+
%ec = icmp eq i64 %iv.next, %n
133+
br i1 %ec, label %exit, label %loop
134+
135+
exit:
136+
ret i64 %red.next
137+
}
138+
139+
; Same, but with SCEV and memory runtime checks, which also bypass both vector
140+
; loops.
141+
define i64 @bypass_blocks(ptr %A, ptr %B, i32 %n) {
142+
; CHECK-LABEL: VPlan for loop in 'bypass_blocks'
143+
; CHECK: VPlan 'Final VPlan for VF={8},UF={1}' {
144+
; CHECK-NEXT: Live-in ir<%n> = original trip-count
145+
; CHECK-EMPTY:
146+
; CHECK-NEXT: ir-bb<entry>:
147+
; CHECK-NEXT: IR %A2 = ptrtoaddr ptr %A to i64
148+
; CHECK-NEXT: IR %B1 = ptrtoaddr ptr %B to i64
149+
; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%n>, ir<4>
150+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>
151+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, ir-bb<vector.scevcheck>
152+
; CHECK-EMPTY:
153+
; CHECK-NEXT: ir-bb<vector.scevcheck>:
154+
; CHECK-NEXT: IR %0 = add i32 %n, -1
155+
; CHECK-NEXT: IR %1 = icmp slt i32 %0, 0
156+
; CHECK-NEXT: EMIT branch-on-cond ir<%1>
157+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, ir-bb<vector.memcheck>
158+
; CHECK-EMPTY:
159+
; CHECK-NEXT: ir-bb<vector.memcheck>:
160+
; CHECK-NEXT: IR %2 = sub i64 %B1, %A2
161+
; CHECK-NEXT: IR %3 = sub i64 %2, 1
162+
; CHECK-NEXT: IR %diff.check = icmp ult i64 %3, 63
163+
; CHECK-NEXT: EMIT branch-on-cond ir<%diff.check>
164+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.main.loop.iter.check
165+
; CHECK-EMPTY:
166+
; CHECK-NEXT: vector.main.loop.iter.check:
167+
; CHECK-NEXT: EMIT vp<%min.iters.check>.1 = icmp ult ir<%n>, ir<8>
168+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>.1
169+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph
170+
; CHECK-EMPTY:
171+
; CHECK-NEXT: vector.ph:
172+
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = and ir<%n>, ir<7>
173+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%n>, vp<[[VP6]]>
174+
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = reduction-start-vector ir<0>, ir<0>, ir<1>
175+
; CHECK-NEXT: Successor(s): vector.body
176+
; CHECK-EMPTY:
177+
; CHECK-NEXT: vector.body:
178+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
179+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi (add) vp<[[VP7]]>, ir<%red.next>
180+
; CHECK-NEXT: EMIT-SCALAR ir<%iv.ext> = sext vp<%index> to i64
181+
; CHECK-NEXT: CLONE ir<%gep.a> = getelementptr inbounds ir<%A>, ir<%iv.ext>
182+
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep.a>
183+
; CHECK-NEXT: WIDEN ir<%red.next> = add ir<%red>, ir<%l>
184+
; CHECK-NEXT: CLONE ir<%gep.b> = getelementptr inbounds ir<%B>, ir<%iv.ext>
185+
; CHECK-NEXT: WIDEN store ir<%gep.b>, ir<%l>
186+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<8>
187+
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec>
188+
; CHECK-NEXT: EMIT branch-on-cond vp<[[VP8]]>
189+
; CHECK-NEXT: Successor(s): middle.block, vector.body
190+
; CHECK-EMPTY:
191+
; CHECK-NEXT: middle.block:
192+
; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = compute-reduction-result (add) ir<%red.next>
193+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<%n.vec>
194+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
195+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<scalar.ph>
196+
; CHECK-EMPTY:
197+
; CHECK-NEXT: ir-bb<exit>:
198+
; CHECK-NEXT: IR %red.next.lcssa = phi i64 [ %red.next, %loop ] (extra operand: vp<[[VP10]]> from middle.block)
199+
; CHECK-NEXT: No successors
200+
; CHECK-EMPTY:
201+
; CHECK-NEXT: ir-bb<scalar.ph>:
202+
; CHECK-NEXT: EMIT-SCALAR vp<%vec.epilog.resume.val> = phi [ vp<%n.vec>, middle.block ], [ ir<0>, ir-bb<entry> ], [ ir<0>, ir-bb<vector.scevcheck> ], [ ir<0>, ir-bb<vector.memcheck> ], [ ir<0>, vector.main.loop.iter.check ]
203+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP10]]>, middle.block ], [ ir<0>, ir-bb<entry> ], [ ir<0>, ir-bb<vector.scevcheck> ], [ ir<0>, ir-bb<vector.memcheck> ], [ ir<0>, vector.main.loop.iter.check ]
204+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP12:%[0-9]+]]> = resume-for-epilogue vp<%vec.epilog.resume.val>, ir<0>
205+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP13:%[0-9]+]]> = resume-for-epilogue vp<%vec.epilog.resume.val>, ir<0>
206+
; CHECK-NEXT: EMIT-SCALAR vp<[[VP14:%[0-9]+]]> = resume-for-epilogue vp<%bc.merge.rdx>, ir<0>
207+
; CHECK-NEXT: Successor(s): ir-bb<loop>
208+
; CHECK-EMPTY:
209+
; CHECK-NEXT: ir-bb<loop>:
210+
; CHECK-NEXT: IR %iv = phi i32 [ 0, %scalar.ph ], [ %iv.next, %loop ] (extra operand: vp<%vec.epilog.resume.val> from ir-bb<scalar.ph>)
211+
; CHECK-NEXT: IR %red = phi i64 [ 0, %scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<scalar.ph>)
212+
; CHECK-NEXT: IR %iv.ext = sext i32 %iv to i64
213+
; CHECK-NEXT: IR %gep.a = getelementptr inbounds i64, ptr %A, i64 %iv.ext
214+
; CHECK-NEXT: IR %l = load i64, ptr %gep.a, align 4
215+
; CHECK-NEXT: IR %red.next = add i64 %red, %l
216+
; CHECK-NEXT: IR %gep.b = getelementptr inbounds i64, ptr %B, i64 %iv.ext
217+
; CHECK-NEXT: IR store i64 %l, ptr %gep.b, align 4
218+
; CHECK-NEXT: IR %iv.next = add i32 %iv, 1
219+
; CHECK-NEXT: IR %ec = icmp eq i32 %iv.next, %n
220+
; CHECK-NEXT: No successors
221+
; CHECK-NEXT: }
222+
;
223+
; CHECK-LABEL: VPlan for loop in 'bypass_blocks'
224+
; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' {
225+
; CHECK-NEXT: Live-in ir<%n> = original trip-count
226+
; CHECK-EMPTY:
227+
; CHECK-NEXT: ir-bb<vec.epilog.iter.check>:
228+
; CHECK-NEXT: IR %vec.epilog.resume.val = phi i32 [ %n.vec, %middle.block ], [ 0, %iter.check ], [ 0, %vector.scevcheck ], [ 0, %vector.memcheck ], [ 0, %vector.main.loop.iter.check ]
229+
; CHECK-NEXT: IR %bc.merge.rdx = phi i64 [ %10, %middle.block ], [ 0, %iter.check ], [ 0, %vector.scevcheck ], [ 0, %vector.memcheck ], [ 0, %vector.main.loop.iter.check ]
230+
; CHECK-NEXT: EMIT vp<%min.epilog.iters.check> = icmp ult ir<%4>, ir<4>
231+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.epilog.iters.check>
232+
; CHECK-NEXT: Successor(s): ir-bb<vec.epilog.scalar.ph>, vec.epilog.ph
233+
; CHECK-EMPTY:
234+
; CHECK-NEXT: vec.epilog.ph:
235+
; CHECK-NEXT: EMIT vp<[[VP3:%[0-9]+]]> = and ir<%n>, ir<3>
236+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%n>, vp<[[VP3]]>
237+
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = reduction-start-vector ir<%bc.merge.rdx>, ir<0>, ir<1>
238+
; CHECK-NEXT: Successor(s): vec.epilog.vector.body
239+
; CHECK-EMPTY:
240+
; CHECK-NEXT: vec.epilog.vector.body:
241+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<%vec.epilog.resume.val>, vec.epilog.ph ], [ vp<%index.next>, vec.epilog.vector.body ]
242+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi (add) vp<[[VP4]]>, ir<%red.next>
243+
; CHECK-NEXT: EMIT-SCALAR ir<%iv.ext> = sext vp<%index> to i64
244+
; CHECK-NEXT: CLONE ir<%gep.a> = getelementptr inbounds ir<%A>, ir<%iv.ext>
245+
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep.a>
246+
; CHECK-NEXT: WIDEN ir<%red.next> = add ir<%red>, ir<%l>
247+
; CHECK-NEXT: CLONE ir<%gep.b> = getelementptr inbounds ir<%B>, ir<%iv.ext>
248+
; CHECK-NEXT: WIDEN store ir<%gep.b>, ir<%l>
249+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<4>
250+
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec>
251+
; CHECK-NEXT: EMIT branch-on-cond vp<[[VP5]]>
252+
; CHECK-NEXT: Successor(s): vec.epilog.middle.block, vec.epilog.vector.body
253+
; CHECK-EMPTY:
254+
; CHECK-NEXT: vec.epilog.middle.block:
255+
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = compute-reduction-result (add) ir<%red.next>
256+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<%n.vec>
257+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
258+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<vec.epilog.scalar.ph>
259+
; CHECK-EMPTY:
260+
; CHECK-NEXT: ir-bb<exit>:
261+
; CHECK-NEXT: IR %red.next.lcssa = phi i64 [ %red.next, %loop ], [ %10, %middle.block ] (extra operand: vp<[[VP7]]> from vec.epilog.middle.block)
262+
; CHECK-NEXT: No successors
263+
; CHECK-EMPTY:
264+
; CHECK-NEXT: ir-bb<vec.epilog.scalar.ph>:
265+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%n.vec>, vec.epilog.middle.block ], [ ir<0>, ir-bb<vec.epilog.iter.check> ]
266+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP7]]>, vec.epilog.middle.block ], [ ir<0>, ir-bb<vec.epilog.iter.check> ]
267+
; CHECK-NEXT: Successor(s): ir-bb<loop>
268+
; CHECK-EMPTY:
269+
; CHECK-NEXT: ir-bb<loop>:
270+
; CHECK-NEXT: IR %iv = phi i32 [ %vec.epilog.resume.val, %vec.epilog.scalar.ph ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from ir-bb<vec.epilog.scalar.ph>)
271+
; CHECK-NEXT: IR %red = phi i64 [ %bc.merge.rdx, %vec.epilog.scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<vec.epilog.scalar.ph>)
272+
; CHECK-NEXT: IR %iv.ext = sext i32 %iv to i64
273+
; CHECK-NEXT: IR %gep.a = getelementptr inbounds i64, ptr %A, i64 %iv.ext
274+
; CHECK-NEXT: IR %l = load i64, ptr %gep.a, align 4
275+
; CHECK-NEXT: IR %red.next = add i64 %red, %l
276+
; CHECK-NEXT: IR %gep.b = getelementptr inbounds i64, ptr %B, i64 %iv.ext
277+
; CHECK-NEXT: IR store i64 %l, ptr %gep.b, align 4
278+
; CHECK-NEXT: IR %iv.next = add i32 %iv, 1
279+
; CHECK-NEXT: IR %ec = icmp eq i32 %iv.next, %n
280+
; CHECK-NEXT: No successors
281+
; CHECK-NEXT: }
282+
;
283+
entry:
284+
br label %loop
285+
286+
loop:
287+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
288+
%red = phi i64 [ 0, %entry ], [ %red.next, %loop ]
289+
%iv.ext = sext i32 %iv to i64
290+
%gep.a = getelementptr inbounds i64, ptr %A, i64 %iv.ext
291+
%l = load i64, ptr %gep.a
292+
%red.next = add i64 %red, %l
293+
%gep.b = getelementptr inbounds i64, ptr %B, i64 %iv.ext
294+
store i64 %l, ptr %gep.b
295+
%iv.next = add i32 %iv, 1
296+
%ec = icmp eq i32 %iv.next, %n
297+
br i1 %ec, label %exit, label %loop
298+
299+
exit:
300+
ret i64 %red.next
301+
}

0 commit comments

Comments
 (0)