1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; This test verifies that the loop vectorizer will not vectorizes low trip count
3; loops that require runtime checks (Trip count is computed with profile info).
4; REQUIRES: asserts
5; RUN: opt < %s -loop-vectorize -loop-vectorize-with-block-frequency -S | FileCheck %s
6
7target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128"
8
9@tab = common global [32 x i8] zeroinitializer, align 1
10
11define i32 @foo_low_trip_count1(i32 %bound) {
12; Simple loop with low tripcount. Should not be vectorized.
13; CHECK-LABEL: @foo_low_trip_count1(
14; CHECK-NEXT:  entry:
15; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[BOUND:%.*]], 1
16; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
17; CHECK:       vector.ph:
18; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i32 [[TMP0]], 3
19; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 4
20; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]
21; CHECK-NEXT:    [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP0]], 1
22; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i32 0
23; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
24; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
25; CHECK:       vector.body:
26; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
27; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
28; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
29; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 1
30; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 2
31; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[INDEX]], 3
32; CHECK-NEXT:    [[TMP5:%.*]] = icmp ule <4 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
33; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
34; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
35; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
36; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP4]]
37; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
38; CHECK-NEXT:    br i1 [[TMP10]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
39; CHECK:       pred.load.if:
40; CHECK-NEXT:    [[TMP11:%.*]] = load i8, i8* [[TMP6]], align 1
41; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x i8> poison, i8 [[TMP11]], i32 0
42; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
43; CHECK:       pred.load.continue:
44; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP12]], [[PRED_LOAD_IF]] ]
45; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
46; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
47; CHECK:       pred.load.if1:
48; CHECK-NEXT:    [[TMP15:%.*]] = load i8, i8* [[TMP7]], align 1
49; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x i8> [[TMP13]], i8 [[TMP15]], i32 1
50; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
51; CHECK:       pred.load.continue2:
52; CHECK-NEXT:    [[TMP17:%.*]] = phi <4 x i8> [ [[TMP13]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], [[PRED_LOAD_IF1]] ]
53; CHECK-NEXT:    [[TMP18:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
54; CHECK-NEXT:    br i1 [[TMP18]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
55; CHECK:       pred.load.if3:
56; CHECK-NEXT:    [[TMP19:%.*]] = load i8, i8* [[TMP8]], align 1
57; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP17]], i8 [[TMP19]], i32 2
58; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
59; CHECK:       pred.load.continue4:
60; CHECK-NEXT:    [[TMP21:%.*]] = phi <4 x i8> [ [[TMP17]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP20]], [[PRED_LOAD_IF3]] ]
61; CHECK-NEXT:    [[TMP22:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
62; CHECK-NEXT:    br i1 [[TMP22]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
63; CHECK:       pred.load.if5:
64; CHECK-NEXT:    [[TMP23:%.*]] = load i8, i8* [[TMP9]], align 1
65; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP23]], i32 3
66; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
67; CHECK:       pred.load.continue6:
68; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i8> [ [[TMP21]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
69; CHECK-NEXT:    [[TMP26:%.*]] = icmp eq <4 x i8> [[TMP25]], zeroinitializer
70; CHECK-NEXT:    [[TMP27:%.*]] = select <4 x i1> [[TMP26]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
71; CHECK-NEXT:    [[TMP28:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
72; CHECK-NEXT:    br i1 [[TMP28]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
73; CHECK:       pred.store.if:
74; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i8> [[TMP27]], i32 0
75; CHECK-NEXT:    store i8 [[TMP29]], i8* [[TMP6]], align 1
76; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
77; CHECK:       pred.store.continue:
78; CHECK-NEXT:    [[TMP30:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
79; CHECK-NEXT:    br i1 [[TMP30]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
80; CHECK:       pred.store.if7:
81; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i8> [[TMP27]], i32 1
82; CHECK-NEXT:    store i8 [[TMP31]], i8* [[TMP7]], align 1
83; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE8]]
84; CHECK:       pred.store.continue8:
85; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
86; CHECK-NEXT:    br i1 [[TMP32]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
87; CHECK:       pred.store.if9:
88; CHECK-NEXT:    [[TMP33:%.*]] = extractelement <4 x i8> [[TMP27]], i32 2
89; CHECK-NEXT:    store i8 [[TMP33]], i8* [[TMP8]], align 1
90; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE10]]
91; CHECK:       pred.store.continue10:
92; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
93; CHECK-NEXT:    br i1 [[TMP34]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
94; CHECK:       pred.store.if11:
95; CHECK-NEXT:    [[TMP35:%.*]] = extractelement <4 x i8> [[TMP27]], i32 3
96; CHECK-NEXT:    store i8 [[TMP35]], i8* [[TMP9]], align 1
97; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE12]]
98; CHECK:       pred.store.continue12:
99; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
100; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
101; CHECK-NEXT:    [[TMP36:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
102; CHECK-NEXT:    br i1 [[TMP36]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !prof [[PROF0:![0-9]+]], !llvm.loop [[LOOP1:![0-9]+]]
103; CHECK:       middle.block:
104; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
105; CHECK:       scalar.ph:
106; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
107; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
108; CHECK:       for.body:
109; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
110; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
111; CHECK-NEXT:    [[TMP37:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
112; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP37]], 0
113; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
114; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
115; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
116; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], [[BOUND]]
117; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !prof [[PROF3:![0-9]+]], !llvm.loop [[LOOP4:![0-9]+]]
118; CHECK:       for.end:
119; CHECK-NEXT:    ret i32 0
120;
121
122entry:
123  br label %for.body
124
125for.body:                                         ; preds = %for.body, %entry
126  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
127  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
128  %0 = load i8, i8* %arrayidx, align 1
129  %cmp1 = icmp eq i8 %0, 0
130  %. = select i1 %cmp1, i8 2, i8 1
131  store i8 %., i8* %arrayidx, align 1
132  %inc = add nsw i32 %i.08, 1
133  %exitcond = icmp eq i32 %i.08, %bound
134  br i1 %exitcond, label %for.end, label %for.body, !prof !1
135
136for.end:                                          ; preds = %for.body
137  ret i32 0
138}
139
140define i32 @foo_low_trip_count2(i32 %bound) !prof !0 {
141; The loop has a same invocation count with the function, but has a low
142; trip_count per invocation and not worth to vectorize.
143; CHECK-LABEL: @foo_low_trip_count2(
144; CHECK-NEXT:  entry:
145; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[BOUND:%.*]], 1
146; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
147; CHECK:       vector.ph:
148; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i32 [[TMP0]], 3
149; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 4
150; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]
151; CHECK-NEXT:    [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP0]], 1
152; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i32 0
153; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
154; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
155; CHECK:       vector.body:
156; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
157; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
158; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
159; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 1
160; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 2
161; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[INDEX]], 3
162; CHECK-NEXT:    [[TMP5:%.*]] = icmp ule <4 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
163; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
164; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
165; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
166; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP4]]
167; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
168; CHECK-NEXT:    br i1 [[TMP10]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
169; CHECK:       pred.load.if:
170; CHECK-NEXT:    [[TMP11:%.*]] = load i8, i8* [[TMP6]], align 1
171; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x i8> poison, i8 [[TMP11]], i32 0
172; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
173; CHECK:       pred.load.continue:
174; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP12]], [[PRED_LOAD_IF]] ]
175; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
176; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
177; CHECK:       pred.load.if1:
178; CHECK-NEXT:    [[TMP15:%.*]] = load i8, i8* [[TMP7]], align 1
179; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x i8> [[TMP13]], i8 [[TMP15]], i32 1
180; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
181; CHECK:       pred.load.continue2:
182; CHECK-NEXT:    [[TMP17:%.*]] = phi <4 x i8> [ [[TMP13]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], [[PRED_LOAD_IF1]] ]
183; CHECK-NEXT:    [[TMP18:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
184; CHECK-NEXT:    br i1 [[TMP18]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
185; CHECK:       pred.load.if3:
186; CHECK-NEXT:    [[TMP19:%.*]] = load i8, i8* [[TMP8]], align 1
187; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP17]], i8 [[TMP19]], i32 2
188; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
189; CHECK:       pred.load.continue4:
190; CHECK-NEXT:    [[TMP21:%.*]] = phi <4 x i8> [ [[TMP17]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP20]], [[PRED_LOAD_IF3]] ]
191; CHECK-NEXT:    [[TMP22:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
192; CHECK-NEXT:    br i1 [[TMP22]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
193; CHECK:       pred.load.if5:
194; CHECK-NEXT:    [[TMP23:%.*]] = load i8, i8* [[TMP9]], align 1
195; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP23]], i32 3
196; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
197; CHECK:       pred.load.continue6:
198; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i8> [ [[TMP21]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
199; CHECK-NEXT:    [[TMP26:%.*]] = icmp eq <4 x i8> [[TMP25]], zeroinitializer
200; CHECK-NEXT:    [[TMP27:%.*]] = select <4 x i1> [[TMP26]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
201; CHECK-NEXT:    [[TMP28:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
202; CHECK-NEXT:    br i1 [[TMP28]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
203; CHECK:       pred.store.if:
204; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i8> [[TMP27]], i32 0
205; CHECK-NEXT:    store i8 [[TMP29]], i8* [[TMP6]], align 1
206; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
207; CHECK:       pred.store.continue:
208; CHECK-NEXT:    [[TMP30:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
209; CHECK-NEXT:    br i1 [[TMP30]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
210; CHECK:       pred.store.if7:
211; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i8> [[TMP27]], i32 1
212; CHECK-NEXT:    store i8 [[TMP31]], i8* [[TMP7]], align 1
213; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE8]]
214; CHECK:       pred.store.continue8:
215; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
216; CHECK-NEXT:    br i1 [[TMP32]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
217; CHECK:       pred.store.if9:
218; CHECK-NEXT:    [[TMP33:%.*]] = extractelement <4 x i8> [[TMP27]], i32 2
219; CHECK-NEXT:    store i8 [[TMP33]], i8* [[TMP8]], align 1
220; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE10]]
221; CHECK:       pred.store.continue10:
222; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
223; CHECK-NEXT:    br i1 [[TMP34]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
224; CHECK:       pred.store.if11:
225; CHECK-NEXT:    [[TMP35:%.*]] = extractelement <4 x i8> [[TMP27]], i32 3
226; CHECK-NEXT:    store i8 [[TMP35]], i8* [[TMP9]], align 1
227; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE12]]
228; CHECK:       pred.store.continue12:
229; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
230; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
231; CHECK-NEXT:    [[TMP36:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
232; CHECK-NEXT:    br i1 [[TMP36]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !prof [[PROF0]], !llvm.loop [[LOOP7:![0-9]+]]
233; CHECK:       middle.block:
234; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
235; CHECK:       scalar.ph:
236; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
237; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
238; CHECK:       for.body:
239; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
240; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
241; CHECK-NEXT:    [[TMP37:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
242; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP37]], 0
243; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
244; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
245; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
246; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], [[BOUND]]
247; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !prof [[PROF3]], !llvm.loop [[LOOP8:![0-9]+]]
248; CHECK:       for.end:
249; CHECK-NEXT:    ret i32 0
250;
251
252entry:
253  br label %for.body
254
255for.body:                                         ; preds = %for.body, %entry
256  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
257  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
258  %0 = load i8, i8* %arrayidx, align 1
259  %cmp1 = icmp eq i8 %0, 0
260  %. = select i1 %cmp1, i8 2, i8 1
261  store i8 %., i8* %arrayidx, align 1
262  %inc = add nsw i32 %i.08, 1
263  %exitcond = icmp eq i32 %i.08, %bound
264  br i1 %exitcond, label %for.end, label %for.body, !prof !1
265
266for.end:                                          ; preds = %for.body
267  ret i32 0
268}
269
270define i32 @foo_low_trip_count3(i1 %cond, i32 %bound) !prof !0 {
271; The loop has low invocation count compare to the function invocation count,
272; but has a high trip count per invocation. Vectorize it.
273; CHECK-LABEL: @foo_low_trip_count3(
274; CHECK-NEXT:  entry:
275; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR_PREHEADER:%.*]], label [[FOR_END:%.*]], !prof [[PROF9:![0-9]+]]
276; CHECK:       for.preheader:
277; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[BOUND:%.*]], 1
278; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 4
279; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
280; CHECK:       vector.ph:
281; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 4
282; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[N_MOD_VF]]
283; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
284; CHECK:       vector.body:
285; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
286; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
287; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
288; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i32 0
289; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>*
290; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP4]], align 1
291; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
292; CHECK-NEXT:    [[TMP6:%.*]] = select <4 x i1> [[TMP5]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
293; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>*
294; CHECK-NEXT:    store <4 x i8> [[TMP6]], <4 x i8>* [[TMP7]], align 1
295; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
296; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
297; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !prof [[PROF10:![0-9]+]], !llvm.loop [[LOOP11:![0-9]+]]
298; CHECK:       middle.block:
299; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i32 [[TMP0]], [[N_VEC]]
300; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END_LOOPEXIT:%.*]], label [[SCALAR_PH]]
301; CHECK:       scalar.ph:
302; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[FOR_PREHEADER]] ]
303; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
304; CHECK:       for.body:
305; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
306; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
307; CHECK-NEXT:    [[TMP9:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
308; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP9]], 0
309; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
310; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
311; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
312; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], [[BOUND]]
313; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT]], label [[FOR_BODY]], !prof [[PROF12:![0-9]+]], !llvm.loop [[LOOP13:![0-9]+]]
314; CHECK:       for.end.loopexit:
315; CHECK-NEXT:    br label [[FOR_END]]
316; CHECK:       for.end:
317; CHECK-NEXT:    ret i32 0
318;
319entry:
320  br i1 %cond, label %for.preheader, label %for.end, !prof !2
321
322for.preheader:
323  br label %for.body
324
325for.body:                                         ; preds = %for.body, %entry
326  %i.08 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
327  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
328  %0 = load i8, i8* %arrayidx, align 1
329  %cmp1 = icmp eq i8 %0, 0
330  %. = select i1 %cmp1, i8 2, i8 1
331  store i8 %., i8* %arrayidx, align 1
332  %inc = add nsw i32 %i.08, 1
333  %exitcond = icmp eq i32 %i.08, %bound
334  br i1 %exitcond, label %for.end, label %for.body, !prof !3
335
336for.end:                                          ; preds = %for.body
337  ret i32 0
338}
339
340define i32 @foo_low_trip_count_icmp_sgt(i32 %bound) {
341; Simple loop with low tripcount and inequality test for exit.
342; Should not be vectorized.
343; CHECK-LABEL: @foo_low_trip_count_icmp_sgt(
344; CHECK-NEXT:  entry:
345; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[BOUND:%.*]], i32 -1)
346; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 2
347; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
348; CHECK:       vector.ph:
349; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i32 [[TMP0]], 3
350; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 4
351; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]
352; CHECK-NEXT:    [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP0]], 1
353; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i32 0
354; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
355; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
356; CHECK:       vector.body:
357; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
358; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
359; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 0
360; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 1
361; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 2
362; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[INDEX]], 3
363; CHECK-NEXT:    [[TMP5:%.*]] = icmp ule <4 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
364; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
365; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
366; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
367; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP4]]
368; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
369; CHECK-NEXT:    br i1 [[TMP10]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
370; CHECK:       pred.load.if:
371; CHECK-NEXT:    [[TMP11:%.*]] = load i8, i8* [[TMP6]], align 1
372; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x i8> poison, i8 [[TMP11]], i32 0
373; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
374; CHECK:       pred.load.continue:
375; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP12]], [[PRED_LOAD_IF]] ]
376; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
377; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
378; CHECK:       pred.load.if1:
379; CHECK-NEXT:    [[TMP15:%.*]] = load i8, i8* [[TMP7]], align 1
380; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x i8> [[TMP13]], i8 [[TMP15]], i32 1
381; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
382; CHECK:       pred.load.continue2:
383; CHECK-NEXT:    [[TMP17:%.*]] = phi <4 x i8> [ [[TMP13]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], [[PRED_LOAD_IF1]] ]
384; CHECK-NEXT:    [[TMP18:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
385; CHECK-NEXT:    br i1 [[TMP18]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
386; CHECK:       pred.load.if3:
387; CHECK-NEXT:    [[TMP19:%.*]] = load i8, i8* [[TMP8]], align 1
388; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP17]], i8 [[TMP19]], i32 2
389; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
390; CHECK:       pred.load.continue4:
391; CHECK-NEXT:    [[TMP21:%.*]] = phi <4 x i8> [ [[TMP17]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP20]], [[PRED_LOAD_IF3]] ]
392; CHECK-NEXT:    [[TMP22:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
393; CHECK-NEXT:    br i1 [[TMP22]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
394; CHECK:       pred.load.if5:
395; CHECK-NEXT:    [[TMP23:%.*]] = load i8, i8* [[TMP9]], align 1
396; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP23]], i32 3
397; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
398; CHECK:       pred.load.continue6:
399; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i8> [ [[TMP21]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
400; CHECK-NEXT:    [[TMP26:%.*]] = icmp eq <4 x i8> [[TMP25]], zeroinitializer
401; CHECK-NEXT:    [[TMP27:%.*]] = select <4 x i1> [[TMP26]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
402; CHECK-NEXT:    [[TMP28:%.*]] = extractelement <4 x i1> [[TMP5]], i32 0
403; CHECK-NEXT:    br i1 [[TMP28]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
404; CHECK:       pred.store.if:
405; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i8> [[TMP27]], i32 0
406; CHECK-NEXT:    store i8 [[TMP29]], i8* [[TMP6]], align 1
407; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
408; CHECK:       pred.store.continue:
409; CHECK-NEXT:    [[TMP30:%.*]] = extractelement <4 x i1> [[TMP5]], i32 1
410; CHECK-NEXT:    br i1 [[TMP30]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
411; CHECK:       pred.store.if7:
412; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i8> [[TMP27]], i32 1
413; CHECK-NEXT:    store i8 [[TMP31]], i8* [[TMP7]], align 1
414; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE8]]
415; CHECK:       pred.store.continue8:
416; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i1> [[TMP5]], i32 2
417; CHECK-NEXT:    br i1 [[TMP32]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
418; CHECK:       pred.store.if9:
419; CHECK-NEXT:    [[TMP33:%.*]] = extractelement <4 x i8> [[TMP27]], i32 2
420; CHECK-NEXT:    store i8 [[TMP33]], i8* [[TMP8]], align 1
421; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE10]]
422; CHECK:       pred.store.continue10:
423; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i1> [[TMP5]], i32 3
424; CHECK-NEXT:    br i1 [[TMP34]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
425; CHECK:       pred.store.if11:
426; CHECK-NEXT:    [[TMP35:%.*]] = extractelement <4 x i8> [[TMP27]], i32 3
427; CHECK-NEXT:    store i8 [[TMP35]], i8* [[TMP9]], align 1
428; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE12]]
429; CHECK:       pred.store.continue12:
430; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
431; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
432; CHECK-NEXT:    [[TMP36:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
433; CHECK-NEXT:    br i1 [[TMP36]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !prof [[PROF0]], !llvm.loop [[LOOP14:![0-9]+]]
434; CHECK:       middle.block:
435; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
436; CHECK:       scalar.ph:
437; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
438; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
439; CHECK:       for.body:
440; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
441; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
442; CHECK-NEXT:    [[TMP37:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
443; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP37]], 0
444; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
445; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
446; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
447; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp sgt i32 [[I_08]], [[BOUND]]
448; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !prof [[PROF3]], !llvm.loop [[LOOP15:![0-9]+]]
449; CHECK:       for.end:
450; CHECK-NEXT:    ret i32 0
451;
452
453entry:
454  br label %for.body
455
456for.body:                                         ; preds = %for.body, %entry
457  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
458  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
459  %0 = load i8, i8* %arrayidx, align 1
460  %cmp1 = icmp eq i8 %0, 0
461  %. = select i1 %cmp1, i8 2, i8 1
462  store i8 %., i8* %arrayidx, align 1
463  %inc = add nsw i32 %i.08, 1
464  %exitcond = icmp sgt i32 %i.08, %bound
465  br i1 %exitcond, label %for.end, label %for.body, !prof !1
466
467for.end:                                          ; preds = %for.body
468  ret i32 0
469}
470
471define i32 @const_low_trip_count() {
472; Simple loop with constant, small trip count and no profiling info.
473; CHECK-LABEL: @const_low_trip_count(
474; CHECK-NEXT:  entry:
475; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
476; CHECK:       vector.ph:
477; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
478; CHECK:       vector.body:
479; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
480; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
481; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
482; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 1
483; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 2
484; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 3
485; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule <4 x i32> [[VEC_IND]], <i32 2, i32 2, i32 2, i32 2>
486; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
487; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
488; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
489; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
490; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
491; CHECK-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
492; CHECK:       pred.load.if:
493; CHECK-NEXT:    [[TMP10:%.*]] = load i8, i8* [[TMP5]], align 1
494; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i8> poison, i8 [[TMP10]], i32 0
495; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
496; CHECK:       pred.load.continue:
497; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP11]], [[PRED_LOAD_IF]] ]
498; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
499; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
500; CHECK:       pred.load.if1:
501; CHECK-NEXT:    [[TMP14:%.*]] = load i8, i8* [[TMP6]], align 1
502; CHECK-NEXT:    [[TMP15:%.*]] = insertelement <4 x i8> [[TMP12]], i8 [[TMP14]], i32 1
503; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
504; CHECK:       pred.load.continue2:
505; CHECK-NEXT:    [[TMP16:%.*]] = phi <4 x i8> [ [[TMP12]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
506; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
507; CHECK-NEXT:    br i1 [[TMP17]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
508; CHECK:       pred.load.if3:
509; CHECK-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP7]], align 1
510; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> [[TMP16]], i8 [[TMP18]], i32 2
511; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
512; CHECK:       pred.load.continue4:
513; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i8> [ [[TMP16]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
514; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
515; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
516; CHECK:       pred.load.if5:
517; CHECK-NEXT:    [[TMP22:%.*]] = load i8, i8* [[TMP8]], align 1
518; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP22]], i32 3
519; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
520; CHECK:       pred.load.continue6:
521; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x i8> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
522; CHECK-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i8> [[TMP24]], zeroinitializer
523; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP25]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
524; CHECK-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
525; CHECK-NEXT:    br i1 [[TMP27]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
526; CHECK:       pred.store.if:
527; CHECK-NEXT:    [[TMP28:%.*]] = extractelement <4 x i8> [[TMP26]], i32 0
528; CHECK-NEXT:    store i8 [[TMP28]], i8* [[TMP5]], align 1
529; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
530; CHECK:       pred.store.continue:
531; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
532; CHECK-NEXT:    br i1 [[TMP29]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
533; CHECK:       pred.store.if7:
534; CHECK-NEXT:    [[TMP30:%.*]] = extractelement <4 x i8> [[TMP26]], i32 1
535; CHECK-NEXT:    store i8 [[TMP30]], i8* [[TMP6]], align 1
536; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE8]]
537; CHECK:       pred.store.continue8:
538; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
539; CHECK-NEXT:    br i1 [[TMP31]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
540; CHECK:       pred.store.if9:
541; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i8> [[TMP26]], i32 2
542; CHECK-NEXT:    store i8 [[TMP32]], i8* [[TMP7]], align 1
543; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE10]]
544; CHECK:       pred.store.continue10:
545; CHECK-NEXT:    [[TMP33:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
546; CHECK-NEXT:    br i1 [[TMP33]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
547; CHECK:       pred.store.if11:
548; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i8> [[TMP26]], i32 3
549; CHECK-NEXT:    store i8 [[TMP34]], i8* [[TMP8]], align 1
550; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE12]]
551; CHECK:       pred.store.continue12:
552; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
553; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
554; CHECK-NEXT:    [[TMP35:%.*]] = icmp eq i32 [[INDEX_NEXT]], 4
555; CHECK-NEXT:    br i1 [[TMP35]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
556; CHECK:       middle.block:
557; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
558; CHECK:       scalar.ph:
559; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 4, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
560; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
561; CHECK:       for.body:
562; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
563; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
564; CHECK-NEXT:    [[TMP36:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
565; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP36]], 0
566; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
567; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
568; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
569; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[I_08]], 2
570; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP17:![0-9]+]]
571; CHECK:       for.end:
572; CHECK-NEXT:    ret i32 0
573;
574
575entry:
576  br label %for.body
577
578for.body:                                         ; preds = %for.body, %entry
579  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
580  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
581  %0 = load i8, i8* %arrayidx, align 1
582  %cmp1 = icmp eq i8 %0, 0
583  %. = select i1 %cmp1, i8 2, i8 1
584  store i8 %., i8* %arrayidx, align 1
585  %inc = add nsw i32 %i.08, 1
586  %exitcond = icmp slt i32 %i.08, 2
587  br i1 %exitcond, label %for.body, label %for.end
588
589for.end:                                          ; preds = %for.body
590  ret i32 0
591}
592
593define i32 @const_large_trip_count() {
594; Simple loop with constant large trip count and no profiling info.
595; CHECK-LABEL: @const_large_trip_count(
596; CHECK-NEXT:  entry:
597; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
598; CHECK:       vector.ph:
599; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
600; CHECK:       vector.body:
601; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
602; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
603; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
604; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i32 0
605; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
606; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP3]], align 1
607; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
608; CHECK-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[TMP4]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
609; CHECK-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
610; CHECK-NEXT:    store <4 x i8> [[TMP5]], <4 x i8>* [[TMP6]], align 1
611; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
612; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
613; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
614; CHECK:       middle.block:
615; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i32 1001, 1000
616; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
617; CHECK:       scalar.ph:
618; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
619; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
620; CHECK:       for.body:
621; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
622; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
623; CHECK-NEXT:    [[TMP8:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
624; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP8]], 0
625; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
626; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
627; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
628; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[I_08]], 1000
629; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP19:![0-9]+]]
630; CHECK:       for.end:
631; CHECK-NEXT:    ret i32 0
632;
633
634entry:
635  br label %for.body
636
637for.body:                                         ; preds = %for.body, %entry
638  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
639  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
640  %0 = load i8, i8* %arrayidx, align 1
641  %cmp1 = icmp eq i8 %0, 0
642  %. = select i1 %cmp1, i8 2, i8 1
643  store i8 %., i8* %arrayidx, align 1
644  %inc = add nsw i32 %i.08, 1
645  %exitcond = icmp slt i32 %i.08, 1000
646  br i1 %exitcond, label %for.body, label %for.end
647
648for.end:                                          ; preds = %for.body
649  ret i32 0
650}
651
652define i32 @const_small_trip_count_step() {
653; Simple loop with static, small trip count and no profiling info.
654; CHECK-LABEL: @const_small_trip_count_step(
655; CHECK-NEXT:  entry:
656; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
657; CHECK:       vector.ph:
658; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
659; CHECK:       vector.body:
660; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
661; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i32 [[INDEX]], 5
662; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[OFFSET_IDX]], 0
663; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[OFFSET_IDX]], 5
664; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[OFFSET_IDX]], 10
665; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[OFFSET_IDX]], 15
666; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[INDEX]], i32 0
667; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
668; CHECK-NEXT:    [[VEC_IV:%.*]] = add <4 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3>
669; CHECK-NEXT:    [[TMP4:%.*]] = icmp ule <4 x i32> [[VEC_IV]], <i32 2, i32 2, i32 2, i32 2>
670; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
671; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
672; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
673; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
674; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
675; CHECK-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
676; CHECK:       pred.load.if:
677; CHECK-NEXT:    [[TMP10:%.*]] = load i8, i8* [[TMP5]], align 1
678; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i8> poison, i8 [[TMP10]], i32 0
679; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
680; CHECK:       pred.load.continue:
681; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP11]], [[PRED_LOAD_IF]] ]
682; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
683; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
684; CHECK:       pred.load.if1:
685; CHECK-NEXT:    [[TMP14:%.*]] = load i8, i8* [[TMP6]], align 1
686; CHECK-NEXT:    [[TMP15:%.*]] = insertelement <4 x i8> [[TMP12]], i8 [[TMP14]], i32 1
687; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
688; CHECK:       pred.load.continue2:
689; CHECK-NEXT:    [[TMP16:%.*]] = phi <4 x i8> [ [[TMP12]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
690; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
691; CHECK-NEXT:    br i1 [[TMP17]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
692; CHECK:       pred.load.if3:
693; CHECK-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP7]], align 1
694; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> [[TMP16]], i8 [[TMP18]], i32 2
695; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
696; CHECK:       pred.load.continue4:
697; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i8> [ [[TMP16]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
698; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
699; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
700; CHECK:       pred.load.if5:
701; CHECK-NEXT:    [[TMP22:%.*]] = load i8, i8* [[TMP8]], align 1
702; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP22]], i32 3
703; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
704; CHECK:       pred.load.continue6:
705; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x i8> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
706; CHECK-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i8> [[TMP24]], zeroinitializer
707; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP25]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
708; CHECK-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
709; CHECK-NEXT:    br i1 [[TMP27]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
710; CHECK:       pred.store.if:
711; CHECK-NEXT:    [[TMP28:%.*]] = extractelement <4 x i8> [[TMP26]], i32 0
712; CHECK-NEXT:    store i8 [[TMP28]], i8* [[TMP5]], align 1
713; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE]]
714; CHECK:       pred.store.continue:
715; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
716; CHECK-NEXT:    br i1 [[TMP29]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
717; CHECK:       pred.store.if7:
718; CHECK-NEXT:    [[TMP30:%.*]] = extractelement <4 x i8> [[TMP26]], i32 1
719; CHECK-NEXT:    store i8 [[TMP30]], i8* [[TMP6]], align 1
720; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE8]]
721; CHECK:       pred.store.continue8:
722; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
723; CHECK-NEXT:    br i1 [[TMP31]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
724; CHECK:       pred.store.if9:
725; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i8> [[TMP26]], i32 2
726; CHECK-NEXT:    store i8 [[TMP32]], i8* [[TMP7]], align 1
727; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE10]]
728; CHECK:       pred.store.continue10:
729; CHECK-NEXT:    [[TMP33:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
730; CHECK-NEXT:    br i1 [[TMP33]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
731; CHECK:       pred.store.if11:
732; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i8> [[TMP26]], i32 3
733; CHECK-NEXT:    store i8 [[TMP34]], i8* [[TMP8]], align 1
734; CHECK-NEXT:    br label [[PRED_STORE_CONTINUE12]]
735; CHECK:       pred.store.continue12:
736; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
737; CHECK-NEXT:    [[TMP35:%.*]] = icmp eq i32 [[INDEX_NEXT]], 4
738; CHECK-NEXT:    br i1 [[TMP35]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
739; CHECK:       middle.block:
740; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
741; CHECK:       scalar.ph:
742; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 20, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
743; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
744; CHECK:       for.body:
745; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
746; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
747; CHECK-NEXT:    [[TMP36:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
748; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP36]], 0
749; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
750; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
751; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 5
752; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[I_08]], 10
753; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP21:![0-9]+]]
754; CHECK:       for.end:
755; CHECK-NEXT:    ret i32 0
756;
757
758entry:
759  br label %for.body
760
761for.body:                                         ; preds = %for.body, %entry
762  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
763  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
764  %0 = load i8, i8* %arrayidx, align 1
765  %cmp1 = icmp eq i8 %0, 0
766  %. = select i1 %cmp1, i8 2, i8 1
767  store i8 %., i8* %arrayidx, align 1
768  %inc = add nsw i32 %i.08, 5
769  %exitcond = icmp slt i32 %i.08, 10
770  br i1 %exitcond, label %for.body, label %for.end
771
772for.end:                                          ; preds = %for.body
773  ret i32 0
774}
775
776define i32 @const_trip_over_profile() {
777; constant trip count takes precedence over profile data
778; CHECK-LABEL: @const_trip_over_profile(
779; CHECK-NEXT:  entry:
780; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
781; CHECK:       vector.ph:
782; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
783; CHECK:       vector.body:
784; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
785; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
786; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
787; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i32 0
788; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
789; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP3]], align 1
790; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
791; CHECK-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[TMP4]], <4 x i8> <i8 2, i8 2, i8 2, i8 2>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>
792; CHECK-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
793; CHECK-NEXT:    store <4 x i8> [[TMP5]], <4 x i8>* [[TMP6]], align 1
794; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
795; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
796; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
797; CHECK:       middle.block:
798; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i32 1001, 1000
799; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
800; CHECK:       scalar.ph:
801; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
802; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
803; CHECK:       for.body:
804; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
805; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
806; CHECK-NEXT:    [[TMP8:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
807; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP8]], 0
808; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
809; CHECK-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
810; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
811; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[I_08]], 1000
812; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !prof [[PROF3]], !llvm.loop [[LOOP23:![0-9]+]]
813; CHECK:       for.end:
814; CHECK-NEXT:    ret i32 0
815;
816
817entry:
818  br label %for.body
819
820for.body:                                         ; preds = %for.body, %entry
821  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
822  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
823  %0 = load i8, i8* %arrayidx, align 1
824  %cmp1 = icmp eq i8 %0, 0
825  %. = select i1 %cmp1, i8 2, i8 1
826  store i8 %., i8* %arrayidx, align 1
827  %inc = add nsw i32 %i.08, 1
828  %exitcond = icmp slt i32 %i.08, 1000
829  br i1 %exitcond, label %for.body, label %for.end, !prof !1
830
831for.end:                                          ; preds = %for.body
832  ret i32 0
833}
834
835; original loop has latchExitWeight=10 and backedgeTakenWeight=10,000,
836; therefore estimatedBackedgeTakenCount=1,000 and estimatedTripCount=1,001.
837; Vectorizing by 4 produces estimatedTripCounts of 1,001/4=250 and 1,001%4=1
838; for vectorized and remainder loops, respectively, therefore their
839; estimatedBackedgeTakenCounts are 249 and 0, and so the weights recorded with
840; loop invocation weights of 10 are the above {10, 2490} and {10, 0}.
841
842!0 = !{!"function_entry_count", i64 100}
843!1 = !{!"branch_weights", i32 100, i32 0}
844!2 = !{!"branch_weights", i32 10, i32 90}
845!3 = !{!"branch_weights", i32 10, i32 10000}
846