3 ; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize \
4 ; RUN: -force-tail-folding-style=data-with-evl \
5 ; RUN: -prefer-predicate-over-epilogue=predicate-dont-vectorize \
6 ; RUN: -mtriple=riscv64 -mattr=+v -riscv-v-vector-bits-max=128 -disable-output < %s 2>&1 | FileCheck --check-prefixes=IF-EVL-OUTLOOP %s
8 ; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize \
9 ; RUN: -prefer-inloop-reductions \
10 ; RUN: -force-tail-folding-style=data-with-evl \
11 ; RUN: -prefer-predicate-over-epilogue=predicate-dont-vectorize \
12 ; RUN: -mtriple=riscv64 -mattr=+v -riscv-v-vector-bits-max=128 -disable-output < %s 2>&1 | FileCheck --check-prefixes=IF-EVL-INLOOP %s
14 ; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize \
15 ; RUN: -force-tail-folding-style=none \
16 ; RUN: -prefer-predicate-over-epilogue=predicate-else-scalar-epilogue \
17 ; RUN: -mtriple=riscv64 -mattr=+v -riscv-v-vector-bits-max=128 -disable-output < %s 2>&1 | FileCheck --check-prefixes=NO-VP-OUTLOOP %s
19 ; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize \
20 ; RUN: -prefer-inloop-reductions \
21 ; RUN: -force-tail-folding-style=none \
22 ; RUN: -prefer-predicate-over-epilogue=predicate-else-scalar-epilogue \
23 ; RUN: -mtriple=riscv64 -mattr=+v -riscv-v-vector-bits-max=128 -disable-output < %s 2>&1 | FileCheck --check-prefixes=NO-VP-INLOOP %s
26 define i32 @reduction(ptr %a, i64 %n, i32 %start) {
27 ; IF-EVL-OUTLOOP-NOT: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
29 ; IF-EVL-INLOOP: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
30 ; IF-EVL-INLOOP-NEXT: Live-in vp<[[VFUF:%[0-9]+]]> = VF * UF
31 ; IF-EVL-INLOOP-NEXT: Live-in vp<[[VTC:%[0-9]+]]> = vector-trip-count
32 ; IF-EVL-INLOOP-NEXT: Live-in ir<%n> = original trip-count
33 ; IF-EVL-INLOOP-EMPTY:
34 ; IF-EVL-INLOOP: vector.ph:
35 ; IF-EVL-INLOOP-NEXT: Successor(s): vector loop
36 ; IF-EVL-INLOOP-EMPTY:
37 ; IF-EVL-INLOOP-NEXT: <x1> vector loop: {
38 ; IF-EVL-INLOOP-NEXT: vector.body:
39 ; IF-EVL-INLOOP-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
40 ; IF-EVL-INLOOP-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%[0-9]+]]>
41 ; IF-EVL-INLOOP-NEXT: WIDEN-REDUCTION-PHI ir<[[RDX_PHI:%.+]]> = phi ir<%start>, ir<[[RDX_NEXT:%.+]]>
42 ; IF-EVL-INLOOP-NEXT: EMIT vp<[[EVL:%.+]]> = EXPLICIT-VECTOR-LENGTH vp<[[EVL_PHI]]>, ir<%n>
43 ; IF-EVL-INLOOP-NEXT: vp<[[ST:%[0-9]+]]> = SCALAR-STEPS vp<[[EVL_PHI]]>, ir<1>
44 ; IF-EVL-INLOOP-NEXT: CLONE ir<[[GEP1:%.+]]> = getelementptr inbounds ir<%a>, vp<[[ST]]>
45 ; IF-EVL-INLOOP-NEXT: vp<[[PTR1:%[0-9]+]]> = vector-pointer ir<[[GEP1]]>
46 ; IF-EVL-INLOOP-NEXT: WIDEN ir<[[LD1:%.+]]> = vp.load vp<[[PTR1]]>, vp<[[EVL]]>
47 ; IF-EVL-INLOOP-NEXT: REDUCE ir<[[ADD:%.+]]> = ir<[[RDX_PHI]]> + vp.reduce.add (ir<[[LD1]]>, vp<[[EVL]]>)
48 ; IF-EVL-INLOOP-NEXT: SCALAR-CAST vp<[[CAST:%[0-9]+]]> = zext vp<[[EVL]]> to i64
49 ; IF-EVL-INLOOP-NEXT: EMIT vp<[[IV_NEXT]]> = add vp<[[CAST]]>, vp<[[EVL_PHI]]>
50 ; IF-EVL-INLOOP-NEXT: EMIT vp<[[IV_NEXT_EXIT:%[0-9]+]]> = add vp<[[IV]]>, vp<[[VFUF]]>
51 ; IF-EVL-INLOOP-NEXT: EMIT branch-on-count vp<[[IV_NEXT_EXIT]]>, vp<[[VTC]]>
52 ; IF-EVL-INLOOP-NEXT: No successors
53 ; IF-EVL-INLOOP-NEXT: }
54 ; IF-EVL-INLOOP-NEXT: Successor(s): middle.block
55 ; IF-EVL-INLOOP-EMPTY:
56 ; IF-EVL-INLOOP-NEXT: middle.block:
57 ; IF-EVL-INLOOP-NEXT: EMIT vp<[[RDX:%.+]]> = compute-reduction-result ir<[[RDX_PHI]]>, ir<[[ADD]]>
58 ; IF-EVL-INLOOP-NEXT: EMIT branch-on-cond ir<true>
59 ; IF-EVL-INLOOP-NEXT: Successor(s): ir-bb<for.end>, scalar.ph
60 ; IF-EVL-INLOOP-EMPTY:
61 ; IF-EVL-INLOOP-NEXT: ir-bb<for.end>:
62 ; IF-EVL-INLOOP-NEXT: No successors
63 ; IF-EVL-INLOOP-EMPTY:
64 ; IF-EVL-INLOOP-NEXT: scalar.ph:
65 ; IF-EVL-INLOOP-NEXT: No successors
66 ; IF-EVL-INLOOP-EMPTY:
67 ; IF-EVL-INLOOP-NEXT: Live-out i32 %add.lcssa = vp<[[RDX]]>
68 ; IF-EVL-INLOOP-NEXT: }
71 ; NO-VP-OUTLOOP: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF>=1' {
72 ; NO-VP-OUTLOOP-NEXT: Live-in vp<[[VFUF:%[0-9]+]]> = VF * UF
73 ; NO-VP-OUTLOOP-NEXT: Live-in vp<[[VTC:%[0-9]+]]> = vector-trip-count
74 ; NO-VP-OUTLOOP-NEXT: Live-in ir<%n> = original trip-count
75 ; NO-VP-OUTLOOP-EMPTY:
76 ; NO-VP-OUTLOOP: vector.ph:
77 ; NO-VP-OUTLOOP-NEXT: Successor(s): vector loop
78 ; NO-VP-OUTLOOP-EMPTY:
79 ; NO-VP-OUTLOOP-NEXT: <x1> vector loop: {
80 ; NO-VP-OUTLOOP-NEXT: vector.body:
81 ; NO-VP-OUTLOOP-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
82 ; NO-VP-OUTLOOP-NEXT: WIDEN-REDUCTION-PHI ir<[[RDX_PHI:%.+]]> = phi ir<%start>, ir<[[RDX_NEXT:%.+]]>
83 ; NO-VP-OUTLOOP-NEXT: vp<[[ST:%[0-9]+]]> = SCALAR-STEPS vp<[[IV]]>, ir<1>
84 ; NO-VP-OUTLOOP-NEXT: CLONE ir<[[GEP1:%.+]]> = getelementptr inbounds ir<%a>, vp<[[ST]]>
85 ; NO-VP-OUTLOOP-NEXT: vp<[[PTR1:%[0-9]+]]> = vector-pointer ir<[[GEP1]]>
86 ; NO-VP-OUTLOOP-NEXT: WIDEN ir<[[LD1:%.+]]> = load vp<[[PTR1]]>
87 ; NO-VP-OUTLOOP-NEXT: WIDEN ir<[[ADD:%.+]]> = add ir<[[LD1]]>, ir<[[RDX_PHI]]>
88 ; NO-VP-OUTLOOP-NEXT: EMIT vp<[[IV_NEXT_EXIT:%[0-9]+]]> = add nuw vp<[[IV]]>, vp<[[VFUF]]>
89 ; NO-VP-OUTLOOP-NEXT: EMIT branch-on-count vp<[[IV_NEXT_EXIT]]>, vp<[[VTC]]>
90 ; NO-VP-OUTLOOP-NEXT: No successors
91 ; NO-VP-OUTLOOP-NEXT: }
92 ; NO-VP-OUTLOOP-NEXT: Successor(s): middle.block
93 ; NO-VP-OUTLOOP-EMPTY:
94 ; NO-VP-OUTLOOP-NEXT: middle.block:
95 ; NO-VP-OUTLOOP-NEXT: EMIT vp<[[RDX:%.+]]> = compute-reduction-result ir<[[RDX_PHI]]>, ir<[[ADD]]>
96 ; NO-VP-OUTLOOP-NEXT: EMIT vp<[[BOC:%.+]]> = icmp eq ir<%n>, vp<[[VTC]]>
97 ; NO-VP-OUTLOOP-NEXT: EMIT branch-on-cond vp<[[BOC]]>
98 ; NO-VP-OUTLOOP-NEXT: Successor(s): ir-bb<for.end>, scalar.ph
99 ; NO-VP-OUTLOOP-EMPTY:
100 ; NO-VP-OUTLOOP-NEXT: ir-bb<for.end>:
101 ; NO-VP-OUTLOOP-NEXT: No successors
102 ; NO-VP-OUTLOOP-EMPTY:
103 ; NO-VP-OUTLOOP-NEXT: scalar.ph:
104 ; NO-VP-OUTLOOP-NEXT: No successors
105 ; NO-VP-OUTLOOP-EMPTY:
106 ; NO-VP-OUTLOOP-NEXT: Live-out i32 %add.lcssa = vp<[[RDX]]>
107 ; NO-VP-OUTLOOP-NEXT: }
110 ; NO-VP-INLOOP: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF>=1' {
111 ; NO-VP-INLOOP-NEXT: Live-in vp<[[VFUF:%[0-9]+]]> = VF * UF
112 ; NO-VP-INLOOP-NEXT: Live-in vp<[[VTC:%[0-9]+]]> = vector-trip-count
113 ; NO-VP-INLOOP-NEXT: Live-in ir<%n> = original trip-count
114 ; NO-VP-INLOOP-EMPTY:
115 ; NO-VP-INLOOP: vector.ph:
116 ; NO-VP-INLOOP-NEXT: Successor(s): vector loop
117 ; NO-VP-INLOOP-EMPTY:
118 ; NO-VP-INLOOP-NEXT: <x1> vector loop: {
119 ; NO-VP-INLOOP-NEXT: vector.body:
120 ; NO-VP-INLOOP-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
121 ; NO-VP-INLOOP-NEXT: WIDEN-REDUCTION-PHI ir<[[RDX_PHI:%.+]]> = phi ir<%start>, ir<[[RDX_NEXT:%.+]]>
122 ; NO-VP-INLOOP-NEXT: vp<[[ST:%[0-9]+]]> = SCALAR-STEPS vp<[[IV]]>, ir<1>
123 ; NO-VP-INLOOP-NEXT: CLONE ir<[[GEP1:%.+]]> = getelementptr inbounds ir<%a>, vp<[[ST]]>
124 ; NO-VP-INLOOP-NEXT: vp<[[PTR1:%[0-9]+]]> = vector-pointer ir<[[GEP1]]>
125 ; NO-VP-INLOOP-NEXT: WIDEN ir<[[LD1:%.+]]> = load vp<[[PTR1]]>
126 ; NO-VP-INLOOP-NEXT: REDUCE ir<[[ADD:%.+]]> = ir<[[RDX_PHI]]> + reduce.add (ir<[[LD1]]>)
127 ; NO-VP-INLOOP-NEXT: EMIT vp<[[IV_NEXT_EXIT:%[0-9]+]]> = add nuw vp<[[IV]]>, vp<[[VFUF]]>
128 ; NO-VP-INLOOP-NEXT: EMIT branch-on-count vp<[[IV_NEXT_EXIT]]>, vp<[[VTC]]>
129 ; NO-VP-INLOOP-NEXT: No successors
130 ; NO-VP-INLOOP-NEXT: }
131 ; NO-VP-INLOOP-NEXT: Successor(s): middle.block
132 ; NO-VP-INLOOP-EMPTY:
133 ; NO-VP-INLOOP-NEXT: middle.block:
134 ; NO-VP-INLOOP-NEXT: EMIT vp<[[RDX:%.+]]> = compute-reduction-result ir<[[RDX_PHI]]>, ir<[[ADD]]>
135 ; NO-VP-INLOOP-NEXT: EMIT vp<[[BOC:%.+]]> = icmp eq ir<%n>, vp<[[VTC]]>
136 ; NO-VP-INLOOP-NEXT: EMIT branch-on-cond vp<[[BOC]]>
137 ; NO-VP-INLOOP-NEXT: Successor(s): ir-bb<for.end>, scalar.ph
138 ; NO-VP-INLOOP-EMPTY:
139 ; NO-VP-INLOOP-NEXT: ir-bb<for.end>:
140 ; NO-VP-INLOOP-NEXT: No successors
141 ; NO-VP-INLOOP-EMPTY:
142 ; NO-VP-INLOOP-NEXT: scalar.ph:
143 ; NO-VP-INLOOP-NEXT: No successors
144 ; NO-VP-INLOOP-EMPTY:
145 ; NO-VP-INLOOP-NEXT: Live-out i32 %add.lcssa = vp<[[RDX]]>
146 ; NO-VP-INLOOP-NEXT: }
152 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
153 %rdx = phi i32 [ %start, %entry ], [ %add, %for.body ]
154 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %iv
155 %0 = load i32, ptr %arrayidx, align 4
156 %add = add nsw i32 %0, %rdx
157 %iv.next = add nuw nsw i64 %iv, 1
158 %exitcond.not = icmp eq i64 %iv.next, %n
159 br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !0
165 !0 = distinct !{!0, !1}
166 !1 = !{!"llvm.loop.vectorize.enable", i1 true}