1; RUN: opt < %s -passes='loop-vectorize' -enable-epilogue-vectorization -S | FileCheck %s
2
3; TODO: For now test for the `-epilogue-vectorization-minimum-VF` option. In
4; the future we need to replace this with a more meaningful test of the
5; epilogue vectorization cost-model.
6; RUN: opt < %s -passes='loop-vectorize' -enable-epilogue-vectorization -epilogue-vectorization-minimum-VF=4 -S | FileCheck %s --check-prefix=CHECK-MIN-4
7; RUN: opt < %s -passes='loop-vectorize' -enable-epilogue-vectorization -S | FileCheck %s --check-prefix=CHECK-MIN-D
8
9target datalayout = "e-m:e-i64:64-n32:64"
10target triple = "powerpc64le-unknown-linux-gnu"
11
12; Do not vectorize epilogues for loops with minsize attribute
13; CHECK-LABLE: @f1
14; CHECK-NOT: vector.main.loop.iter.check
15; CHECK-NOT: vec.epilog.iter.check
16; CHECK-NOT: vec.epilog.ph
17; CHECK-NOT: vec.epilog.vector.body
18; CHECK-NOT: vec.epilog.middle.block
19
20define dso_local void @f1(float* noalias %aa, float* noalias %bb, float* noalias %cc, i32 signext %N) #0 {
21entry:
22  %cmp1 = icmp sgt i32 %N, 0
23  br i1 %cmp1, label %for.body.preheader, label %for.end
24
25for.body.preheader:                               ; preds = %entry
26  %wide.trip.count = zext i32 %N to i64
27  br label %for.body
28
29for.body:                                         ; preds = %for.body.preheader, %for.body
30  %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
31  %arrayidx = getelementptr inbounds float, float* %bb, i64 %indvars.iv
32  %0 = load float, float* %arrayidx, align 4
33  %arrayidx2 = getelementptr inbounds float, float* %cc, i64 %indvars.iv
34  %1 = load float, float* %arrayidx2, align 4
35  %add = fadd fast float %0, %1
36  %arrayidx4 = getelementptr inbounds float, float* %aa, i64 %indvars.iv
37  store float %add, float* %arrayidx4, align 4
38  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
39  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count
40  br i1 %exitcond, label %for.body, label %for.end.loopexit
41
42for.end.loopexit:                                 ; preds = %for.body
43  br label %for.end
44
45for.end:                                          ; preds = %for.end.loopexit, %entry
46  ret void
47}
48
49; Do not vectorize epilogues for loops with optsize attribute
50; CHECK-LABLE: @f2
51; CHECK-NOT: vector.main.loop.iter.check
52; CHECK-NOT: vec.epilog.iter.check
53; CHECK-NOT: vec.epilog.ph
54; CHECK-NOT: vec.epilog.vector.body
55; CHECK-NOT: vec.epilog.middle.block
56
57define dso_local void @f2(float* noalias %aa, float* noalias %bb, float* noalias %cc, i32 signext %N) #1 {
58entry:
59  %cmp1 = icmp sgt i32 %N, 0
60  br i1 %cmp1, label %for.body.preheader, label %for.end
61
62for.body.preheader:                               ; preds = %entry
63  %wide.trip.count = zext i32 %N to i64
64  br label %for.body
65
66for.body:                                         ; preds = %for.body.preheader, %for.body
67  %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
68  %arrayidx = getelementptr inbounds float, float* %bb, i64 %indvars.iv
69  %0 = load float, float* %arrayidx, align 4
70  %arrayidx2 = getelementptr inbounds float, float* %cc, i64 %indvars.iv
71  %1 = load float, float* %arrayidx2, align 4
72  %add = fadd fast float %0, %1
73  %arrayidx4 = getelementptr inbounds float, float* %aa, i64 %indvars.iv
74  store float %add, float* %arrayidx4, align 4
75  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
76  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count
77  br i1 %exitcond, label %for.body, label %for.end.loopexit
78
79for.end.loopexit:                                 ; preds = %for.body
80  br label %for.end
81
82for.end:                                          ; preds = %for.end.loopexit, %entry
83  ret void
84}
85
86; Do not vectorize the epilogue for loops with VF less than the default -epilogue-vectorization-minimum-VF of 16.
87; CHECK-MIN-D-LABLE: @f3
88; CHECK-MIN-D-NOT: vector.main.loop.iter.check
89; CHECK-MIN-D-NOT: vec.epilog.iter.check
90; CHECK-MIN-D-NOT: vec.epilog.ph
91; CHECK-MIN-D-NOT: vec.epilog.vector.body
92; CHECK-MIN-D-NOT: vec.epilog.middle.block
93
94; Specify a smaller minimum VF (via `-epilogue-vectorization-minimum-VF=4`) and
95; make sure the epilogue gets vectorized in that case.
96; CHECK-MIN-D-LABLE: @f3
97; CHECK-MIN-4: vector.main.loop.iter.check
98; CHECK-MIN-4: vec.epilog.iter.check
99; CHECK-MIN-4: vec.epilog.ph
100; CHECK-MIN-4: vec.epilog.vector.body
101; CHECK-MIN-4: vec.epilog.middle.block
102
103define dso_local void @f3(float* noalias %aa, float* noalias %bb, float* noalias %cc, i32 signext %N) {
104entry:
105  %cmp1 = icmp sgt i32 %N, 0
106  br i1 %cmp1, label %for.body.preheader, label %for.end
107
108for.body.preheader:                               ; preds = %entry
109  %wide.trip.count = zext i32 %N to i64
110  br label %for.body
111
112for.body:                                         ; preds = %for.body.preheader, %for.body
113  %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
114  %arrayidx = getelementptr inbounds float, float* %bb, i64 %indvars.iv
115  %0 = load float, float* %arrayidx, align 4
116  %arrayidx2 = getelementptr inbounds float, float* %cc, i64 %indvars.iv
117  %1 = load float, float* %arrayidx2, align 4
118  %add = fadd fast float %0, %1
119  %arrayidx4 = getelementptr inbounds float, float* %aa, i64 %indvars.iv
120  store float %add, float* %arrayidx4, align 4
121  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
122  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count
123  br i1 %exitcond, label %for.body, label %for.end.loopexit
124
125for.end.loopexit:                                 ; preds = %for.body
126  br label %for.end
127
128for.end:                                          ; preds = %for.end.loopexit, %entry
129  ret void
130}
131
132attributes #0 = { minsize }
133attributes #1 = { optsize }