1*cee313d2SEric Christopher; This test verifies that the loop vectorizer will not vectorizes low trip count
2*cee313d2SEric Christopher; loops that require runtime checks (Trip count is computed with profile info).
3*cee313d2SEric Christopher; REQUIRES: asserts
4*cee313d2SEric Christopher; RUN: opt < %s -loop-vectorize -loop-vectorize-with-block-frequency -S | FileCheck %s
5*cee313d2SEric Christopher
6*cee313d2SEric Christophertarget datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128"
7*cee313d2SEric Christopher
8*cee313d2SEric Christopher@tab = common global [32 x i8] zeroinitializer, align 1
9*cee313d2SEric Christopher
10*cee313d2SEric Christopherdefine i32 @foo_low_trip_count1(i32 %bound) {
11*cee313d2SEric Christopher; Simple loop with low tripcount. Should not be vectorized.
12*cee313d2SEric Christopher
13*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count1(
14*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8>
15*cee313d2SEric Christopher
16*cee313d2SEric Christopherentry:
17*cee313d2SEric Christopher  br label %for.body
18*cee313d2SEric Christopher
19*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
20*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
21*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
22*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
23*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
24*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
25*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
26*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
27*cee313d2SEric Christopher  %exitcond = icmp eq i32 %i.08, %bound
28*cee313d2SEric Christopher  br i1 %exitcond, label %for.end, label %for.body, !prof !1
29*cee313d2SEric Christopher
30*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
31*cee313d2SEric Christopher  ret i32 0
32*cee313d2SEric Christopher}
33*cee313d2SEric Christopher
34*cee313d2SEric Christopherdefine i32 @foo_low_trip_count2(i32 %bound) !prof !0 {
35*cee313d2SEric Christopher; The loop has a same invocation count with the function, but has a low
36*cee313d2SEric Christopher; trip_count per invocation and not worth to vectorize.
37*cee313d2SEric Christopher
38*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count2(
39*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8>
40*cee313d2SEric Christopher
41*cee313d2SEric Christopherentry:
42*cee313d2SEric Christopher  br label %for.body
43*cee313d2SEric Christopher
44*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
45*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
46*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
47*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
48*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
49*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
50*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
51*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
52*cee313d2SEric Christopher  %exitcond = icmp eq i32 %i.08, %bound
53*cee313d2SEric Christopher  br i1 %exitcond, label %for.end, label %for.body, !prof !1
54*cee313d2SEric Christopher
55*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
56*cee313d2SEric Christopher  ret i32 0
57*cee313d2SEric Christopher}
58*cee313d2SEric Christopher
59*cee313d2SEric Christopherdefine i32 @foo_low_trip_count3(i1 %cond, i32 %bound) !prof !0 {
60*cee313d2SEric Christopher; The loop has low invocation count compare to the function invocation count,
61*cee313d2SEric Christopher; but has a high trip count per invocation. Vectorize it.
62*cee313d2SEric Christopher
63*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count3(
64*cee313d2SEric Christopher; CHECK: vector.body:
65*cee313d2SEric Christopher
66*cee313d2SEric Christopherentry:
67*cee313d2SEric Christopher  br i1 %cond, label %for.preheader, label %for.end, !prof !2
68*cee313d2SEric Christopher
69*cee313d2SEric Christopherfor.preheader:
70*cee313d2SEric Christopher  br label %for.body
71*cee313d2SEric Christopher
72*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
73*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
74*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
75*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
76*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
77*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
78*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
79*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
80*cee313d2SEric Christopher  %exitcond = icmp eq i32 %i.08, %bound
81*cee313d2SEric Christopher  br i1 %exitcond, label %for.end, label %for.body, !prof !3
82*cee313d2SEric Christopher
83*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
84*cee313d2SEric Christopher  ret i32 0
85*cee313d2SEric Christopher}
86*cee313d2SEric Christopher
87*cee313d2SEric Christopherdefine i32 @foo_low_trip_count_icmp_sgt(i32 %bound) {
88*cee313d2SEric Christopher; Simple loop with low tripcount and inequality test for exit.
89*cee313d2SEric Christopher; Should not be vectorized.
90*cee313d2SEric Christopher
91*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count_icmp_sgt(
92*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8>
93*cee313d2SEric Christopher
94*cee313d2SEric Christopherentry:
95*cee313d2SEric Christopher  br label %for.body
96*cee313d2SEric Christopher
97*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
98*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
99*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
100*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
101*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
102*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
103*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
104*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
105*cee313d2SEric Christopher  %exitcond = icmp sgt i32 %i.08, %bound
106*cee313d2SEric Christopher  br i1 %exitcond, label %for.end, label %for.body, !prof !1
107*cee313d2SEric Christopher
108*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
109*cee313d2SEric Christopher  ret i32 0
110*cee313d2SEric Christopher}
111*cee313d2SEric Christopher
112*cee313d2SEric Christopherdefine i32 @const_low_trip_count() {
113*cee313d2SEric Christopher; Simple loop with constant, small trip count and no profiling info.
114*cee313d2SEric Christopher
115*cee313d2SEric Christopher; CHECK-LABEL: @const_low_trip_count
116*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8>
117*cee313d2SEric Christopher
118*cee313d2SEric Christopherentry:
119*cee313d2SEric Christopher  br label %for.body
120*cee313d2SEric Christopher
121*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
122*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
123*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
124*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
125*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
126*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
127*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
128*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
129*cee313d2SEric Christopher  %exitcond = icmp slt i32 %i.08, 2
130*cee313d2SEric Christopher  br i1 %exitcond, label %for.body, label %for.end
131*cee313d2SEric Christopher
132*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
133*cee313d2SEric Christopher  ret i32 0
134*cee313d2SEric Christopher}
135*cee313d2SEric Christopher
136*cee313d2SEric Christopherdefine i32 @const_large_trip_count() {
137*cee313d2SEric Christopher; Simple loop with constant large trip count and no profiling info.
138*cee313d2SEric Christopher
139*cee313d2SEric Christopher; CHECK-LABEL: @const_large_trip_count
140*cee313d2SEric Christopher; CHECK: <{{[0-9]+}} x i8>
141*cee313d2SEric Christopher
142*cee313d2SEric Christopherentry:
143*cee313d2SEric Christopher  br label %for.body
144*cee313d2SEric Christopher
145*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
146*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
147*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
148*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
149*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
150*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
151*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
152*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
153*cee313d2SEric Christopher  %exitcond = icmp slt i32 %i.08, 1000
154*cee313d2SEric Christopher  br i1 %exitcond, label %for.body, label %for.end
155*cee313d2SEric Christopher
156*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
157*cee313d2SEric Christopher  ret i32 0
158*cee313d2SEric Christopher}
159*cee313d2SEric Christopher
160*cee313d2SEric Christopherdefine i32 @const_small_trip_count_step() {
161*cee313d2SEric Christopher; Simple loop with static, small trip count and no profiling info.
162*cee313d2SEric Christopher
163*cee313d2SEric Christopher; CHECK-LABEL: @const_small_trip_count_step
164*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8>
165*cee313d2SEric Christopher
166*cee313d2SEric Christopherentry:
167*cee313d2SEric Christopher  br label %for.body
168*cee313d2SEric Christopher
169*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
170*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
171*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
172*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
173*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
174*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
175*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
176*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 5
177*cee313d2SEric Christopher  %exitcond = icmp slt i32 %i.08, 10
178*cee313d2SEric Christopher  br i1 %exitcond, label %for.body, label %for.end
179*cee313d2SEric Christopher
180*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
181*cee313d2SEric Christopher  ret i32 0
182*cee313d2SEric Christopher}
183*cee313d2SEric Christopher
184*cee313d2SEric Christopherdefine i32 @const_trip_over_profile() {
185*cee313d2SEric Christopher; constant trip count takes precedence over profile data
186*cee313d2SEric Christopher
187*cee313d2SEric Christopher; CHECK-LABEL: @const_trip_over_profile
188*cee313d2SEric Christopher; CHECK: <{{[0-9]+}} x i8>
189*cee313d2SEric Christopher
190*cee313d2SEric Christopherentry:
191*cee313d2SEric Christopher  br label %for.body
192*cee313d2SEric Christopher
193*cee313d2SEric Christopherfor.body:                                         ; preds = %for.body, %entry
194*cee313d2SEric Christopher  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
195*cee313d2SEric Christopher  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
196*cee313d2SEric Christopher  %0 = load i8, i8* %arrayidx, align 1
197*cee313d2SEric Christopher  %cmp1 = icmp eq i8 %0, 0
198*cee313d2SEric Christopher  %. = select i1 %cmp1, i8 2, i8 1
199*cee313d2SEric Christopher  store i8 %., i8* %arrayidx, align 1
200*cee313d2SEric Christopher  %inc = add nsw i32 %i.08, 1
201*cee313d2SEric Christopher  %exitcond = icmp slt i32 %i.08, 1000
202*cee313d2SEric Christopher  br i1 %exitcond, label %for.body, label %for.end, !prof !1
203*cee313d2SEric Christopher
204*cee313d2SEric Christopherfor.end:                                          ; preds = %for.body
205*cee313d2SEric Christopher  ret i32 0
206*cee313d2SEric Christopher}
207*cee313d2SEric Christopher
208*cee313d2SEric Christopher!0 = !{!"function_entry_count", i64 100}
209*cee313d2SEric Christopher!1 = !{!"branch_weights", i32 100, i32 0}
210*cee313d2SEric Christopher!2 = !{!"branch_weights", i32 10, i32 90}
211*cee313d2SEric Christopher!3 = !{!"branch_weights", i32 10, i32 10000}
212