1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -enable-new-pm=0 -loop-vectorize -S | FileCheck %s -check-prefixes=DEFAULT,PGSO
3; RUN: opt < %s -enable-new-pm=0 -loop-vectorize -pgso -S | FileCheck %s -check-prefixes=DEFAULT,PGSO
4; RUN: opt < %s -enable-new-pm=0 -loop-vectorize -pgso=false -S | FileCheck %s -check-prefixes=DEFAULT,NPGSO
5; RUN: opt < %s -passes='require<profile-summary>,loop-vectorize' -S | FileCheck %s -check-prefixes=DEFAULT,PGSO
6; RUN: opt < %s -passes='require<profile-summary>,loop-vectorize' -pgso -S | FileCheck %s -check-prefixes=DEFAULT,PGSO
7; RUN: opt < %s -passes='require<profile-summary>,loop-vectorize' -pgso=false -S | FileCheck %s -check-prefixes=DEFAULT,NPGSO
8
9; REQUIRES: asserts
10
11; This test verifies that the loop vectorizer will NOT produce a tail
12; loop with the optimize for size or the minimize size attributes.
13
14target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128"
15
16@tab = common global [32 x i8] zeroinitializer, align 1
17
18define i32 @foo_optsize() #0 {
19; DEFAULT-LABEL: @foo_optsize(
20; DEFAULT-NEXT:  entry:
21; DEFAULT-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
22; DEFAULT:       vector.ph:
23; DEFAULT-NEXT:    br label [[VECTOR_BODY:%.*]]
24; DEFAULT:       vector.body:
25; DEFAULT-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
26; DEFAULT-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
27; DEFAULT-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
28; DEFAULT-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 1
29; DEFAULT-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 2
30; DEFAULT-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 3
31; DEFAULT-NEXT:    [[TMP4:%.*]] = icmp ule <4 x i32> [[VEC_IND]], <i32 202, i32 202, i32 202, i32 202>
32; DEFAULT-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
33; DEFAULT-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
34; DEFAULT-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
35; DEFAULT-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
36; DEFAULT-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
37; DEFAULT-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
38; DEFAULT:       pred.load.if:
39; DEFAULT-NEXT:    [[TMP10:%.*]] = load i8, i8* [[TMP5]], align 1
40; DEFAULT-NEXT:    [[TMP11:%.*]] = insertelement <4 x i8> poison, i8 [[TMP10]], i32 0
41; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE]]
42; DEFAULT:       pred.load.continue:
43; DEFAULT-NEXT:    [[TMP12:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP11]], [[PRED_LOAD_IF]] ]
44; DEFAULT-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
45; DEFAULT-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
46; DEFAULT:       pred.load.if1:
47; DEFAULT-NEXT:    [[TMP14:%.*]] = load i8, i8* [[TMP6]], align 1
48; DEFAULT-NEXT:    [[TMP15:%.*]] = insertelement <4 x i8> [[TMP12]], i8 [[TMP14]], i32 1
49; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
50; DEFAULT:       pred.load.continue2:
51; DEFAULT-NEXT:    [[TMP16:%.*]] = phi <4 x i8> [ [[TMP12]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
52; DEFAULT-NEXT:    [[TMP17:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
53; DEFAULT-NEXT:    br i1 [[TMP17]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
54; DEFAULT:       pred.load.if3:
55; DEFAULT-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP7]], align 1
56; DEFAULT-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> [[TMP16]], i8 [[TMP18]], i32 2
57; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
58; DEFAULT:       pred.load.continue4:
59; DEFAULT-NEXT:    [[TMP20:%.*]] = phi <4 x i8> [ [[TMP16]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
60; DEFAULT-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
61; DEFAULT-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
62; DEFAULT:       pred.load.if5:
63; DEFAULT-NEXT:    [[TMP22:%.*]] = load i8, i8* [[TMP8]], align 1
64; DEFAULT-NEXT:    [[TMP23:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP22]], i32 3
65; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
66; DEFAULT:       pred.load.continue6:
67; DEFAULT-NEXT:    [[TMP24:%.*]] = phi <4 x i8> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
68; DEFAULT-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i8> [[TMP24]], zeroinitializer
69; DEFAULT-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>
70; DEFAULT-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
71; DEFAULT-NEXT:    br i1 [[TMP27]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
72; DEFAULT:       pred.store.if:
73; DEFAULT-NEXT:    [[TMP28:%.*]] = extractelement <4 x i8> [[TMP26]], i32 0
74; DEFAULT-NEXT:    store i8 [[TMP28]], i8* [[TMP5]], align 1
75; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE]]
76; DEFAULT:       pred.store.continue:
77; DEFAULT-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
78; DEFAULT-NEXT:    br i1 [[TMP29]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
79; DEFAULT:       pred.store.if7:
80; DEFAULT-NEXT:    [[TMP30:%.*]] = extractelement <4 x i8> [[TMP26]], i32 1
81; DEFAULT-NEXT:    store i8 [[TMP30]], i8* [[TMP6]], align 1
82; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE8]]
83; DEFAULT:       pred.store.continue8:
84; DEFAULT-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
85; DEFAULT-NEXT:    br i1 [[TMP31]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
86; DEFAULT:       pred.store.if9:
87; DEFAULT-NEXT:    [[TMP32:%.*]] = extractelement <4 x i8> [[TMP26]], i32 2
88; DEFAULT-NEXT:    store i8 [[TMP32]], i8* [[TMP7]], align 1
89; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE10]]
90; DEFAULT:       pred.store.continue10:
91; DEFAULT-NEXT:    [[TMP33:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
92; DEFAULT-NEXT:    br i1 [[TMP33]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
93; DEFAULT:       pred.store.if11:
94; DEFAULT-NEXT:    [[TMP34:%.*]] = extractelement <4 x i8> [[TMP26]], i32 3
95; DEFAULT-NEXT:    store i8 [[TMP34]], i8* [[TMP8]], align 1
96; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE12]]
97; DEFAULT:       pred.store.continue12:
98; DEFAULT-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
99; DEFAULT-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
100; DEFAULT-NEXT:    [[TMP35:%.*]] = icmp eq i32 [[INDEX_NEXT]], 204
101; DEFAULT-NEXT:    br i1 [[TMP35]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
102; DEFAULT:       middle.block:
103; DEFAULT-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
104; DEFAULT:       scalar.ph:
105; DEFAULT-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 204, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
106; DEFAULT-NEXT:    br label [[FOR_BODY:%.*]]
107; DEFAULT:       for.body:
108; DEFAULT-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
109; DEFAULT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
110; DEFAULT-NEXT:    [[TMP36:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
111; DEFAULT-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP36]], 0
112; DEFAULT-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
113; DEFAULT-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
114; DEFAULT-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
115; DEFAULT-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], 202
116; DEFAULT-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
117; DEFAULT:       for.end:
118; DEFAULT-NEXT:    ret i32 0
119;
120entry:
121  br label %for.body
122
123for.body:                                         ; preds = %for.body, %entry
124  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
125  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
126  %0 = load i8, i8* %arrayidx, align 1
127  %cmp1 = icmp eq i8 %0, 0
128  %. = select i1 %cmp1, i8 2, i8 1
129  store i8 %., i8* %arrayidx, align 1
130  %inc = add nsw i32 %i.08, 1
131  %exitcond = icmp eq i32 %i.08, 202
132  br i1 %exitcond, label %for.end, label %for.body
133
134for.end:                                          ; preds = %for.body
135  ret i32 0
136}
137
138attributes #0 = { optsize }
139
140define i32 @foo_minsize() #1 {
141; DEFAULT-LABEL: @foo_minsize(
142; DEFAULT-NEXT:  entry:
143; DEFAULT-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
144; DEFAULT:       vector.ph:
145; DEFAULT-NEXT:    br label [[VECTOR_BODY:%.*]]
146; DEFAULT:       vector.body:
147; DEFAULT-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
148; DEFAULT-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
149; DEFAULT-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
150; DEFAULT-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 1
151; DEFAULT-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 2
152; DEFAULT-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 3
153; DEFAULT-NEXT:    [[TMP4:%.*]] = icmp ule <4 x i32> [[VEC_IND]], <i32 202, i32 202, i32 202, i32 202>
154; DEFAULT-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
155; DEFAULT-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
156; DEFAULT-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
157; DEFAULT-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
158; DEFAULT-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
159; DEFAULT-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
160; DEFAULT:       pred.load.if:
161; DEFAULT-NEXT:    [[TMP10:%.*]] = load i8, i8* [[TMP5]], align 1
162; DEFAULT-NEXT:    [[TMP11:%.*]] = insertelement <4 x i8> poison, i8 [[TMP10]], i32 0
163; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE]]
164; DEFAULT:       pred.load.continue:
165; DEFAULT-NEXT:    [[TMP12:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP11]], [[PRED_LOAD_IF]] ]
166; DEFAULT-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
167; DEFAULT-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
168; DEFAULT:       pred.load.if1:
169; DEFAULT-NEXT:    [[TMP14:%.*]] = load i8, i8* [[TMP6]], align 1
170; DEFAULT-NEXT:    [[TMP15:%.*]] = insertelement <4 x i8> [[TMP12]], i8 [[TMP14]], i32 1
171; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
172; DEFAULT:       pred.load.continue2:
173; DEFAULT-NEXT:    [[TMP16:%.*]] = phi <4 x i8> [ [[TMP12]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
174; DEFAULT-NEXT:    [[TMP17:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
175; DEFAULT-NEXT:    br i1 [[TMP17]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
176; DEFAULT:       pred.load.if3:
177; DEFAULT-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP7]], align 1
178; DEFAULT-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> [[TMP16]], i8 [[TMP18]], i32 2
179; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
180; DEFAULT:       pred.load.continue4:
181; DEFAULT-NEXT:    [[TMP20:%.*]] = phi <4 x i8> [ [[TMP16]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
182; DEFAULT-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
183; DEFAULT-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
184; DEFAULT:       pred.load.if5:
185; DEFAULT-NEXT:    [[TMP22:%.*]] = load i8, i8* [[TMP8]], align 1
186; DEFAULT-NEXT:    [[TMP23:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP22]], i32 3
187; DEFAULT-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
188; DEFAULT:       pred.load.continue6:
189; DEFAULT-NEXT:    [[TMP24:%.*]] = phi <4 x i8> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
190; DEFAULT-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i8> [[TMP24]], zeroinitializer
191; DEFAULT-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>
192; DEFAULT-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
193; DEFAULT-NEXT:    br i1 [[TMP27]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
194; DEFAULT:       pred.store.if:
195; DEFAULT-NEXT:    [[TMP28:%.*]] = extractelement <4 x i8> [[TMP26]], i32 0
196; DEFAULT-NEXT:    store i8 [[TMP28]], i8* [[TMP5]], align 1
197; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE]]
198; DEFAULT:       pred.store.continue:
199; DEFAULT-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
200; DEFAULT-NEXT:    br i1 [[TMP29]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
201; DEFAULT:       pred.store.if7:
202; DEFAULT-NEXT:    [[TMP30:%.*]] = extractelement <4 x i8> [[TMP26]], i32 1
203; DEFAULT-NEXT:    store i8 [[TMP30]], i8* [[TMP6]], align 1
204; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE8]]
205; DEFAULT:       pred.store.continue8:
206; DEFAULT-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
207; DEFAULT-NEXT:    br i1 [[TMP31]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
208; DEFAULT:       pred.store.if9:
209; DEFAULT-NEXT:    [[TMP32:%.*]] = extractelement <4 x i8> [[TMP26]], i32 2
210; DEFAULT-NEXT:    store i8 [[TMP32]], i8* [[TMP7]], align 1
211; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE10]]
212; DEFAULT:       pred.store.continue10:
213; DEFAULT-NEXT:    [[TMP33:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
214; DEFAULT-NEXT:    br i1 [[TMP33]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
215; DEFAULT:       pred.store.if11:
216; DEFAULT-NEXT:    [[TMP34:%.*]] = extractelement <4 x i8> [[TMP26]], i32 3
217; DEFAULT-NEXT:    store i8 [[TMP34]], i8* [[TMP8]], align 1
218; DEFAULT-NEXT:    br label [[PRED_STORE_CONTINUE12]]
219; DEFAULT:       pred.store.continue12:
220; DEFAULT-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
221; DEFAULT-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
222; DEFAULT-NEXT:    [[TMP35:%.*]] = icmp eq i32 [[INDEX_NEXT]], 204
223; DEFAULT-NEXT:    br i1 [[TMP35]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
224; DEFAULT:       middle.block:
225; DEFAULT-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
226; DEFAULT:       scalar.ph:
227; DEFAULT-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 204, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
228; DEFAULT-NEXT:    br label [[FOR_BODY:%.*]]
229; DEFAULT:       for.body:
230; DEFAULT-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
231; DEFAULT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
232; DEFAULT-NEXT:    [[TMP36:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
233; DEFAULT-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP36]], 0
234; DEFAULT-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
235; DEFAULT-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
236; DEFAULT-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
237; DEFAULT-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], 202
238; DEFAULT-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
239; DEFAULT:       for.end:
240; DEFAULT-NEXT:    ret i32 0
241;
242entry:
243  br label %for.body
244
245for.body:                                         ; preds = %for.body, %entry
246  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
247  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
248  %0 = load i8, i8* %arrayidx, align 1
249  %cmp1 = icmp eq i8 %0, 0
250  %. = select i1 %cmp1, i8 2, i8 1
251  store i8 %., i8* %arrayidx, align 1
252  %inc = add nsw i32 %i.08, 1
253  %exitcond = icmp eq i32 %i.08, 202
254  br i1 %exitcond, label %for.end, label %for.body
255
256for.end:                                          ; preds = %for.body
257  ret i32 0
258}
259
260attributes #1 = { minsize }
261
262define i32 @foo_pgso() !prof !14 {
263; PGSO-LABEL: @foo_pgso(
264; PGSO-NEXT:  entry:
265; PGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
266; PGSO:       vector.ph:
267; PGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
268; PGSO:       vector.body:
269; PGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
270; PGSO-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE12]] ]
271; PGSO-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
272; PGSO-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 1
273; PGSO-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 2
274; PGSO-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 3
275; PGSO-NEXT:    [[TMP4:%.*]] = icmp ule <4 x i32> [[VEC_IND]], <i32 202, i32 202, i32 202, i32 202>
276; PGSO-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
277; PGSO-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP1]]
278; PGSO-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP2]]
279; PGSO-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP3]]
280; PGSO-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
281; PGSO-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
282; PGSO:       pred.load.if:
283; PGSO-NEXT:    [[TMP10:%.*]] = load i8, i8* [[TMP5]], align 1
284; PGSO-NEXT:    [[TMP11:%.*]] = insertelement <4 x i8> poison, i8 [[TMP10]], i32 0
285; PGSO-NEXT:    br label [[PRED_LOAD_CONTINUE]]
286; PGSO:       pred.load.continue:
287; PGSO-NEXT:    [[TMP12:%.*]] = phi <4 x i8> [ poison, [[VECTOR_BODY]] ], [ [[TMP11]], [[PRED_LOAD_IF]] ]
288; PGSO-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
289; PGSO-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
290; PGSO:       pred.load.if1:
291; PGSO-NEXT:    [[TMP14:%.*]] = load i8, i8* [[TMP6]], align 1
292; PGSO-NEXT:    [[TMP15:%.*]] = insertelement <4 x i8> [[TMP12]], i8 [[TMP14]], i32 1
293; PGSO-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
294; PGSO:       pred.load.continue2:
295; PGSO-NEXT:    [[TMP16:%.*]] = phi <4 x i8> [ [[TMP12]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
296; PGSO-NEXT:    [[TMP17:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
297; PGSO-NEXT:    br i1 [[TMP17]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
298; PGSO:       pred.load.if3:
299; PGSO-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP7]], align 1
300; PGSO-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> [[TMP16]], i8 [[TMP18]], i32 2
301; PGSO-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
302; PGSO:       pred.load.continue4:
303; PGSO-NEXT:    [[TMP20:%.*]] = phi <4 x i8> [ [[TMP16]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
304; PGSO-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
305; PGSO-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
306; PGSO:       pred.load.if5:
307; PGSO-NEXT:    [[TMP22:%.*]] = load i8, i8* [[TMP8]], align 1
308; PGSO-NEXT:    [[TMP23:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP22]], i32 3
309; PGSO-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
310; PGSO:       pred.load.continue6:
311; PGSO-NEXT:    [[TMP24:%.*]] = phi <4 x i8> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
312; PGSO-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i8> [[TMP24]], zeroinitializer
313; PGSO-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>
314; PGSO-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP4]], i32 0
315; PGSO-NEXT:    br i1 [[TMP27]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
316; PGSO:       pred.store.if:
317; PGSO-NEXT:    [[TMP28:%.*]] = extractelement <4 x i8> [[TMP26]], i32 0
318; PGSO-NEXT:    store i8 [[TMP28]], i8* [[TMP5]], align 1
319; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE]]
320; PGSO:       pred.store.continue:
321; PGSO-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP4]], i32 1
322; PGSO-NEXT:    br i1 [[TMP29]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
323; PGSO:       pred.store.if7:
324; PGSO-NEXT:    [[TMP30:%.*]] = extractelement <4 x i8> [[TMP26]], i32 1
325; PGSO-NEXT:    store i8 [[TMP30]], i8* [[TMP6]], align 1
326; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE8]]
327; PGSO:       pred.store.continue8:
328; PGSO-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP4]], i32 2
329; PGSO-NEXT:    br i1 [[TMP31]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
330; PGSO:       pred.store.if9:
331; PGSO-NEXT:    [[TMP32:%.*]] = extractelement <4 x i8> [[TMP26]], i32 2
332; PGSO-NEXT:    store i8 [[TMP32]], i8* [[TMP7]], align 1
333; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE10]]
334; PGSO:       pred.store.continue10:
335; PGSO-NEXT:    [[TMP33:%.*]] = extractelement <4 x i1> [[TMP4]], i32 3
336; PGSO-NEXT:    br i1 [[TMP33]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
337; PGSO:       pred.store.if11:
338; PGSO-NEXT:    [[TMP34:%.*]] = extractelement <4 x i8> [[TMP26]], i32 3
339; PGSO-NEXT:    store i8 [[TMP34]], i8* [[TMP8]], align 1
340; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE12]]
341; PGSO:       pred.store.continue12:
342; PGSO-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
343; PGSO-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
344; PGSO-NEXT:    [[TMP35:%.*]] = icmp eq i32 [[INDEX_NEXT]], 204
345; PGSO-NEXT:    br i1 [[TMP35]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP21:![0-9]+]]
346; PGSO:       middle.block:
347; PGSO-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
348; PGSO:       scalar.ph:
349; PGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 204, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
350; PGSO-NEXT:    br label [[FOR_BODY:%.*]]
351; PGSO:       for.body:
352; PGSO-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
353; PGSO-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
354; PGSO-NEXT:    [[TMP36:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
355; PGSO-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP36]], 0
356; PGSO-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
357; PGSO-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
358; PGSO-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
359; PGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], 202
360; PGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
361; PGSO:       for.end:
362; PGSO-NEXT:    ret i32 0
363;
364; NPGSO-LABEL: @foo_pgso(
365; NPGSO-NEXT:  entry:
366; NPGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
367; NPGSO:       vector.ph:
368; NPGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
369; NPGSO:       vector.body:
370; NPGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
371; NPGSO-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
372; NPGSO-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[TMP0]]
373; NPGSO-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i32 0
374; NPGSO-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
375; NPGSO-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i8>, <4 x i8>* [[TMP3]], align 1
376; NPGSO-NEXT:    [[TMP4:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
377; NPGSO-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>
378; NPGSO-NEXT:    [[TMP6:%.*]] = bitcast i8* [[TMP2]] to <4 x i8>*
379; NPGSO-NEXT:    store <4 x i8> [[TMP5]], <4 x i8>* [[TMP6]], align 1
380; NPGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
381; NPGSO-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 200
382; NPGSO-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP21:![0-9]+]]
383; NPGSO:       middle.block:
384; NPGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 203, 200
385; NPGSO-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
386; NPGSO:       scalar.ph:
387; NPGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 200, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
388; NPGSO-NEXT:    br label [[FOR_BODY:%.*]]
389; NPGSO:       for.body:
390; NPGSO-NEXT:    [[I_08:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
391; NPGSO-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 [[I_08]]
392; NPGSO-NEXT:    [[TMP8:%.*]] = load i8, i8* [[ARRAYIDX]], align 1
393; NPGSO-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TMP8]], 0
394; NPGSO-NEXT:    [[DOT:%.*]] = select i1 [[CMP1]], i8 2, i8 1
395; NPGSO-NEXT:    store i8 [[DOT]], i8* [[ARRAYIDX]], align 1
396; NPGSO-NEXT:    [[INC]] = add nsw i32 [[I_08]], 1
397; NPGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[I_08]], 202
398; NPGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
399; NPGSO:       for.end:
400; NPGSO-NEXT:    ret i32 0
401;
402entry:
403  br label %for.body
404
405for.body:                                         ; preds = %for.body, %entry
406  %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
407  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08
408  %0 = load i8, i8* %arrayidx, align 1
409  %cmp1 = icmp eq i8 %0, 0
410  %. = select i1 %cmp1, i8 2, i8 1
411  store i8 %., i8* %arrayidx, align 1
412  %inc = add nsw i32 %i.08, 1
413  %exitcond = icmp eq i32 %i.08, 202
414  br i1 %exitcond, label %for.end, label %for.body
415
416for.end:                                          ; preds = %for.body
417  ret i32 0
418}
419
420; PR43371: don't run into an assert due to emitting SCEV runtime checks
421; with OptForSize.
422;
423@cm_array = external global [2592 x i16], align 1
424
425define void @pr43371() optsize {
426; DEFAULT-LABEL: @pr43371(
427; DEFAULT-NEXT:  entry:
428; DEFAULT-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
429; DEFAULT:       vector.ph:
430; DEFAULT-NEXT:    br label [[VECTOR_BODY:%.*]]
431; DEFAULT:       vector.body:
432; DEFAULT-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
433; DEFAULT-NEXT:    [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 0, i16 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
434; DEFAULT-NEXT:    [[TMP0:%.*]] = add <2 x i16> undef, [[VEC_IND]]
435; DEFAULT-NEXT:    [[TMP1:%.*]] = zext <2 x i16> [[TMP0]] to <2 x i32>
436; DEFAULT-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[TMP1]], i32 0
437; DEFAULT-NEXT:    [[TMP3:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[TMP2]]
438; DEFAULT-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[TMP1]], i32 1
439; DEFAULT-NEXT:    [[TMP5:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[TMP4]]
440; DEFAULT-NEXT:    store i16 0, i16* [[TMP3]], align 1
441; DEFAULT-NEXT:    store i16 0, i16* [[TMP5]], align 1
442; DEFAULT-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
443; DEFAULT-NEXT:    [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], <i16 2, i16 2>
444; DEFAULT-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 756
445; DEFAULT-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP23:![0-9]+]]
446; DEFAULT:       middle.block:
447; DEFAULT-NEXT:    [[CMP_N:%.*]] = icmp eq i32 756, 756
448; DEFAULT-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP28:%.*]], label [[SCALAR_PH]]
449; DEFAULT:       scalar.ph:
450; DEFAULT-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i16 [ 756, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
451; DEFAULT-NEXT:    br label [[FOR_BODY29:%.*]]
452; DEFAULT:       for.cond.cleanup28:
453; DEFAULT-NEXT:    unreachable
454; DEFAULT:       for.body29:
455; DEFAULT-NEXT:    [[I24_0170:%.*]] = phi i16 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC37:%.*]], [[FOR_BODY29]] ]
456; DEFAULT-NEXT:    [[ADD33:%.*]] = add i16 undef, [[I24_0170]]
457; DEFAULT-NEXT:    [[IDXPROM34:%.*]] = zext i16 [[ADD33]] to i32
458; DEFAULT-NEXT:    [[ARRAYIDX35:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[IDXPROM34]]
459; DEFAULT-NEXT:    store i16 0, i16* [[ARRAYIDX35]], align 1
460; DEFAULT-NEXT:    [[INC37]] = add i16 [[I24_0170]], 1
461; DEFAULT-NEXT:    [[CMP26:%.*]] = icmp ult i16 [[INC37]], 756
462; DEFAULT-NEXT:    br i1 [[CMP26]], label [[FOR_BODY29]], label [[FOR_COND_CLEANUP28]], !llvm.loop [[LOOP24:![0-9]+]]
463;
464entry:
465  br label %for.body29
466
467for.cond.cleanup28:
468  unreachable
469
470for.body29:
471  %i24.0170 = phi i16 [ 0, %entry], [ %inc37, %for.body29]
472  %add33 = add i16 undef, %i24.0170
473  %idxprom34 = zext i16 %add33 to i32
474  %arrayidx35 = getelementptr [2592 x i16], [2592 x i16] * @cm_array, i32 0, i32 %idxprom34
475  store i16 0, i16 * %arrayidx35, align 1
476  %inc37 = add i16 %i24.0170, 1
477  %cmp26 = icmp ult i16 %inc37, 756
478  br i1 %cmp26, label %for.body29, label %for.cond.cleanup28
479}
480
481define void @pr43371_pgso() !prof !14 {
482; PGSO-LABEL: @pr43371_pgso(
483; PGSO-NEXT:  entry:
484; PGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
485; PGSO:       vector.ph:
486; PGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
487; PGSO:       vector.body:
488; PGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
489; PGSO-NEXT:    [[VEC_IND:%.*]] = phi <2 x i16> [ <i16 0, i16 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
490; PGSO-NEXT:    [[TMP0:%.*]] = add <2 x i16> undef, [[VEC_IND]]
491; PGSO-NEXT:    [[TMP1:%.*]] = zext <2 x i16> [[TMP0]] to <2 x i32>
492; PGSO-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[TMP1]], i32 0
493; PGSO-NEXT:    [[TMP3:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[TMP2]]
494; PGSO-NEXT:    [[TMP4:%.*]] = extractelement <2 x i32> [[TMP1]], i32 1
495; PGSO-NEXT:    [[TMP5:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[TMP4]]
496; PGSO-NEXT:    store i16 0, i16* [[TMP3]], align 1
497; PGSO-NEXT:    store i16 0, i16* [[TMP5]], align 1
498; PGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
499; PGSO-NEXT:    [[VEC_IND_NEXT]] = add <2 x i16> [[VEC_IND]], <i16 2, i16 2>
500; PGSO-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 756
501; PGSO-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP25:![0-9]+]]
502; PGSO:       middle.block:
503; PGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 756, 756
504; PGSO-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP28:%.*]], label [[SCALAR_PH]]
505; PGSO:       scalar.ph:
506; PGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i16 [ 756, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
507; PGSO-NEXT:    br label [[FOR_BODY29:%.*]]
508; PGSO:       for.cond.cleanup28:
509; PGSO-NEXT:    unreachable
510; PGSO:       for.body29:
511; PGSO-NEXT:    [[I24_0170:%.*]] = phi i16 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC37:%.*]], [[FOR_BODY29]] ]
512; PGSO-NEXT:    [[ADD33:%.*]] = add i16 undef, [[I24_0170]]
513; PGSO-NEXT:    [[IDXPROM34:%.*]] = zext i16 [[ADD33]] to i32
514; PGSO-NEXT:    [[ARRAYIDX35:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[IDXPROM34]]
515; PGSO-NEXT:    store i16 0, i16* [[ARRAYIDX35]], align 1
516; PGSO-NEXT:    [[INC37]] = add i16 [[I24_0170]], 1
517; PGSO-NEXT:    [[CMP26:%.*]] = icmp ult i16 [[INC37]], 756
518; PGSO-NEXT:    br i1 [[CMP26]], label [[FOR_BODY29]], label [[FOR_COND_CLEANUP28]], !llvm.loop [[LOOP26:![0-9]+]]
519;
520; NPGSO-LABEL: @pr43371_pgso(
521; NPGSO-NEXT:  entry:
522; NPGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
523; NPGSO:       vector.scevcheck:
524; NPGSO-NEXT:    br i1 undef, label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
525; NPGSO:       vector.ph:
526; NPGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
527; NPGSO:       vector.body:
528; NPGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
529; NPGSO-NEXT:    [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i16
530; NPGSO-NEXT:    [[TMP0:%.*]] = add i16 [[OFFSET_IDX]], 0
531; NPGSO-NEXT:    [[TMP1:%.*]] = add i16 undef, [[TMP0]]
532; NPGSO-NEXT:    [[TMP2:%.*]] = zext i16 [[TMP1]] to i32
533; NPGSO-NEXT:    [[TMP3:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[TMP2]]
534; NPGSO-NEXT:    [[TMP4:%.*]] = getelementptr i16, i16* [[TMP3]], i32 0
535; NPGSO-NEXT:    [[TMP5:%.*]] = bitcast i16* [[TMP4]] to <2 x i16>*
536; NPGSO-NEXT:    store <2 x i16> zeroinitializer, <2 x i16>* [[TMP5]], align 1
537; NPGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
538; NPGSO-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 756
539; NPGSO-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP25:![0-9]+]]
540; NPGSO:       middle.block:
541; NPGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 756, 756
542; NPGSO-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP28:%.*]], label [[SCALAR_PH]]
543; NPGSO:       scalar.ph:
544; NPGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i16 [ 756, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
545; NPGSO-NEXT:    br label [[FOR_BODY29:%.*]]
546; NPGSO:       for.cond.cleanup28:
547; NPGSO-NEXT:    unreachable
548; NPGSO:       for.body29:
549; NPGSO-NEXT:    [[I24_0170:%.*]] = phi i16 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC37:%.*]], [[FOR_BODY29]] ]
550; NPGSO-NEXT:    [[ADD33:%.*]] = add i16 undef, [[I24_0170]]
551; NPGSO-NEXT:    [[IDXPROM34:%.*]] = zext i16 [[ADD33]] to i32
552; NPGSO-NEXT:    [[ARRAYIDX35:%.*]] = getelementptr [2592 x i16], [2592 x i16]* @cm_array, i32 0, i32 [[IDXPROM34]]
553; NPGSO-NEXT:    store i16 0, i16* [[ARRAYIDX35]], align 1
554; NPGSO-NEXT:    [[INC37]] = add i16 [[I24_0170]], 1
555; NPGSO-NEXT:    [[CMP26:%.*]] = icmp ult i16 [[INC37]], 756
556; NPGSO-NEXT:    br i1 [[CMP26]], label [[FOR_BODY29]], label [[FOR_COND_CLEANUP28]], !llvm.loop [[LOOP26:![0-9]+]]
557;
558entry:
559  br label %for.body29
560
561for.cond.cleanup28:
562  unreachable
563
564for.body29:
565  %i24.0170 = phi i16 [ 0, %entry], [ %inc37, %for.body29]
566  %add33 = add i16 undef, %i24.0170
567  %idxprom34 = zext i16 %add33 to i32
568  %arrayidx35 = getelementptr [2592 x i16], [2592 x i16] * @cm_array, i32 0, i32 %idxprom34
569  store i16 0, i16 * %arrayidx35, align 1
570  %inc37 = add i16 %i24.0170, 1
571  %cmp26 = icmp ult i16 %inc37, 756
572  br i1 %cmp26, label %for.body29, label %for.cond.cleanup28
573}
574
575; PR45526: don't vectorize with fold-tail if first-order-recurrence is live-out.
576;
577define i32 @pr45526() optsize {
578; DEFAULT-LABEL: @pr45526(
579; DEFAULT-NEXT:  entry:
580; DEFAULT-NEXT:    br label [[LOOP:%.*]]
581; DEFAULT:       loop:
582; DEFAULT-NEXT:    [[PIV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[PIVPLUS1:%.*]], [[LOOP]] ]
583; DEFAULT-NEXT:    [[FOR:%.*]] = phi i32 [ 5, [[ENTRY]] ], [ [[PIVPLUS1]], [[LOOP]] ]
584; DEFAULT-NEXT:    [[PIVPLUS1]] = add nuw nsw i32 [[PIV]], 1
585; DEFAULT-NEXT:    [[COND:%.*]] = icmp ult i32 [[PIV]], 510
586; DEFAULT-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
587; DEFAULT:       exit:
588; DEFAULT-NEXT:    [[FOR_LCSSA:%.*]] = phi i32 [ [[FOR]], [[LOOP]] ]
589; DEFAULT-NEXT:    ret i32 [[FOR_LCSSA]]
590;
591entry:
592  br label %loop
593
594loop:
595  %piv = phi i32 [ 0, %entry ], [ %pivPlus1, %loop ]
596  %for = phi i32 [ 5, %entry ], [ %pivPlus1, %loop ]
597  %pivPlus1 = add nuw nsw i32 %piv, 1
598  %cond = icmp ult i32 %piv, 510
599  br i1 %cond, label %loop, label %exit
600
601exit:
602  ret i32 %for
603}
604
605define i32 @pr45526_pgso() !prof !14 {
606; PGSO-LABEL: @pr45526_pgso(
607; PGSO-NEXT:  entry:
608; PGSO-NEXT:    br label [[LOOP:%.*]]
609; PGSO:       loop:
610; PGSO-NEXT:    [[PIV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[PIVPLUS1:%.*]], [[LOOP]] ]
611; PGSO-NEXT:    [[FOR:%.*]] = phi i32 [ 5, [[ENTRY]] ], [ [[PIVPLUS1]], [[LOOP]] ]
612; PGSO-NEXT:    [[PIVPLUS1]] = add nuw nsw i32 [[PIV]], 1
613; PGSO-NEXT:    [[COND:%.*]] = icmp ult i32 [[PIV]], 510
614; PGSO-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
615; PGSO:       exit:
616; PGSO-NEXT:    [[FOR_LCSSA:%.*]] = phi i32 [ [[FOR]], [[LOOP]] ]
617; PGSO-NEXT:    ret i32 [[FOR_LCSSA]]
618;
619; NPGSO-LABEL: @pr45526_pgso(
620; NPGSO-NEXT:  entry:
621; NPGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
622; NPGSO:       vector.ph:
623; NPGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
624; NPGSO:       vector.body:
625; NPGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
626; NPGSO-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
627; NPGSO-NEXT:    [[VECTOR_RECUR:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 5>, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
628; NPGSO-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
629; NPGSO-NEXT:    [[TMP1:%.*]] = add i32 [[INDEX]], 1
630; NPGSO-NEXT:    [[TMP2:%.*]] = add i32 [[INDEX]], 2
631; NPGSO-NEXT:    [[TMP3:%.*]] = add i32 [[INDEX]], 3
632; NPGSO-NEXT:    [[TMP4]] = add nuw nsw <4 x i32> [[VEC_IND]], <i32 1, i32 1, i32 1, i32 1>
633; NPGSO-NEXT:    [[TMP5:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR]], <4 x i32> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
634; NPGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
635; NPGSO-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
636; NPGSO-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 508
637; NPGSO-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]]
638; NPGSO:       middle.block:
639; NPGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 511, 508
640; NPGSO-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i32> [[TMP4]], i32 3
641; NPGSO-NEXT:    [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <4 x i32> [[TMP4]], i32 2
642; NPGSO-NEXT:    br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
643; NPGSO:       scalar.ph:
644; NPGSO-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i32 [ 5, [[ENTRY:%.*]] ], [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ]
645; NPGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 508, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
646; NPGSO-NEXT:    br label [[LOOP:%.*]]
647; NPGSO:       loop:
648; NPGSO-NEXT:    [[PIV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[PIVPLUS1:%.*]], [[LOOP]] ]
649; NPGSO-NEXT:    [[SCALAR_RECUR:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[PIVPLUS1]], [[LOOP]] ]
650; NPGSO-NEXT:    [[PIVPLUS1]] = add nuw nsw i32 [[PIV]], 1
651; NPGSO-NEXT:    [[COND:%.*]] = icmp ult i32 [[PIV]], 510
652; NPGSO-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP28:![0-9]+]]
653; NPGSO:       exit:
654; NPGSO-NEXT:    [[FOR_LCSSA:%.*]] = phi i32 [ [[SCALAR_RECUR]], [[LOOP]] ], [ [[VECTOR_RECUR_EXTRACT_FOR_PHI]], [[MIDDLE_BLOCK]] ]
655; NPGSO-NEXT:    ret i32 [[FOR_LCSSA]]
656;
657entry:
658  br label %loop
659
660loop:
661  %piv = phi i32 [ 0, %entry ], [ %pivPlus1, %loop ]
662  %for = phi i32 [ 5, %entry ], [ %pivPlus1, %loop ]
663  %pivPlus1 = add nuw nsw i32 %piv, 1
664  %cond = icmp ult i32 %piv, 510
665  br i1 %cond, label %loop, label %exit
666
667exit:
668  ret i32 %for
669}
670
671; PR46228: Vectorize w/o versioning for unit stride under optsize and enabled
672; vectorization.
673
674; NOTE: Some assertions have been autogenerated by utils/update_test_checks.py
675define void @stride1(i16* noalias %B, i32 %BStride) optsize {
676; PGSO-LABEL: @stride1(
677; PGSO-NEXT:  entry:
678; PGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
679; PGSO:       vector.ph:
680; PGSO-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[BSTRIDE:%.*]], i32 0
681; PGSO-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i32> [[BROADCAST_SPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
682; PGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
683; PGSO:       vector.body:
684; PGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
685; PGSO-NEXT:    [[VEC_IND:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE2]] ]
686; PGSO-NEXT:    [[TMP0:%.*]] = icmp ule <2 x i32> [[VEC_IND]], <i32 1024, i32 1024>
687; PGSO-NEXT:    [[TMP1:%.*]] = mul nsw <2 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
688; PGSO-NEXT:    [[TMP2:%.*]] = extractelement <2 x i1> [[TMP0]], i32 0
689; PGSO-NEXT:    br i1 [[TMP2]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
690; PGSO:       pred.store.if:
691; PGSO-NEXT:    [[TMP3:%.*]] = extractelement <2 x i32> [[TMP1]], i32 0
692; PGSO-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i16, i16* [[B:%.*]], i32 [[TMP3]]
693; PGSO-NEXT:    store i16 42, i16* [[TMP4]], align 4
694; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE]]
695; PGSO:       pred.store.continue:
696; PGSO-NEXT:    [[TMP5:%.*]] = extractelement <2 x i1> [[TMP0]], i32 1
697; PGSO-NEXT:    br i1 [[TMP5]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
698; PGSO:       pred.store.if1:
699; PGSO-NEXT:    [[TMP6:%.*]] = extractelement <2 x i32> [[TMP1]], i32 1
700; PGSO-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[TMP6]]
701; PGSO-NEXT:    store i16 42, i16* [[TMP7]], align 4
702; PGSO-NEXT:    br label [[PRED_STORE_CONTINUE2]]
703; PGSO:       pred.store.continue2:
704; PGSO-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 2
705; PGSO-NEXT:    [[VEC_IND_NEXT]] = add <2 x i32> [[VEC_IND]], <i32 2, i32 2>
706; PGSO-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1026
707; PGSO-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]]
708; PGSO:       middle.block:
709; PGSO-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
710; PGSO:       scalar.ph:
711; PGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1026, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
712; PGSO-NEXT:    br label [[FOR_BODY:%.*]]
713; PGSO:       for.body:
714; PGSO-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
715; PGSO-NEXT:    [[MULB:%.*]] = mul nsw i32 [[IV]], [[BSTRIDE]]
716; PGSO-NEXT:    [[GEPOFB:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[MULB]]
717; PGSO-NEXT:    store i16 42, i16* [[GEPOFB]], align 4
718; PGSO-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
719; PGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV_NEXT]], 1025
720; PGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]]
721; PGSO:       for.end:
722; PGSO-NEXT:    ret void
723;
724; NPGSO-LABEL: @stride1(
725; NPGSO-NEXT:  entry:
726; NPGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
727; NPGSO:       vector.ph:
728; NPGSO-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[BSTRIDE:%.*]], i32 0
729; NPGSO-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i32> [[BROADCAST_SPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
730; NPGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
731; NPGSO:       vector.body:
732; NPGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ]
733; NPGSO-NEXT:    [[VEC_IND:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE2]] ]
734; NPGSO-NEXT:    [[TMP0:%.*]] = icmp ule <2 x i32> [[VEC_IND]], <i32 1024, i32 1024>
735; NPGSO-NEXT:    [[TMP1:%.*]] = mul nsw <2 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]
736; NPGSO-NEXT:    [[TMP2:%.*]] = extractelement <2 x i1> [[TMP0]], i32 0
737; NPGSO-NEXT:    br i1 [[TMP2]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
738; NPGSO:       pred.store.if:
739; NPGSO-NEXT:    [[TMP3:%.*]] = extractelement <2 x i32> [[TMP1]], i32 0
740; NPGSO-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i16, i16* [[B:%.*]], i32 [[TMP3]]
741; NPGSO-NEXT:    store i16 42, i16* [[TMP4]], align 4
742; NPGSO-NEXT:    br label [[PRED_STORE_CONTINUE]]
743; NPGSO:       pred.store.continue:
744; NPGSO-NEXT:    [[TMP5:%.*]] = extractelement <2 x i1> [[TMP0]], i32 1
745; NPGSO-NEXT:    br i1 [[TMP5]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]]
746; NPGSO:       pred.store.if1:
747; NPGSO-NEXT:    [[TMP6:%.*]] = extractelement <2 x i32> [[TMP1]], i32 1
748; NPGSO-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[TMP6]]
749; NPGSO-NEXT:    store i16 42, i16* [[TMP7]], align 4
750; NPGSO-NEXT:    br label [[PRED_STORE_CONTINUE2]]
751; NPGSO:       pred.store.continue2:
752; NPGSO-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 2
753; NPGSO-NEXT:    [[VEC_IND_NEXT]] = add <2 x i32> [[VEC_IND]], <i32 2, i32 2>
754; NPGSO-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1026
755; NPGSO-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP29:![0-9]+]]
756; NPGSO:       middle.block:
757; NPGSO-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
758; NPGSO:       scalar.ph:
759; NPGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1026, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
760; NPGSO-NEXT:    br label [[FOR_BODY:%.*]]
761; NPGSO:       for.body:
762; NPGSO-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
763; NPGSO-NEXT:    [[MULB:%.*]] = mul nsw i32 [[IV]], [[BSTRIDE]]
764; NPGSO-NEXT:    [[GEPOFB:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[MULB]]
765; NPGSO-NEXT:    store i16 42, i16* [[GEPOFB]], align 4
766; NPGSO-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
767; NPGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV_NEXT]], 1025
768; NPGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]]
769; NPGSO:       for.end:
770; NPGSO-NEXT:    ret void
771;
772entry:
773  br label %for.body
774
775for.body:
776  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
777  %mulB = mul nsw i32 %iv, %BStride
778  %gepOfB = getelementptr inbounds i16, i16* %B, i32 %mulB
779  store i16 42, i16* %gepOfB, align 4
780  %iv.next = add nuw nsw i32 %iv, 1
781  %exitcond = icmp eq i32 %iv.next, 1025
782  br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !15
783
784for.end:
785  ret void
786}
787
788; Vectorize with versioning for unit stride for PGSO and enabled vectorization.
789;
790define void @stride1_pgso(i16* noalias %B, i32 %BStride) !prof !14 {
791; PGSO-LABEL: @stride1_pgso(
792; PGSO-NEXT:  entry:
793; PGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
794; PGSO:       vector.scevcheck:
795; PGSO-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[BSTRIDE:%.*]], 1
796; PGSO-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
797; PGSO:       vector.ph:
798; PGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
799; PGSO:       vector.body:
800; PGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
801; PGSO-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
802; PGSO-NEXT:    [[TMP1:%.*]] = mul nsw i32 [[TMP0]], [[BSTRIDE]]
803; PGSO-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i16, i16* [[B:%.*]], i32 [[TMP1]]
804; PGSO-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, i16* [[TMP2]], i32 0
805; PGSO-NEXT:    [[TMP4:%.*]] = bitcast i16* [[TMP3]] to <2 x i16>*
806; PGSO-NEXT:    store <2 x i16> <i16 42, i16 42>, <2 x i16>* [[TMP4]], align 4
807; PGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
808; PGSO-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1024
809; PGSO-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP29:![0-9]+]]
810; PGSO:       middle.block:
811; PGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 1025, 1024
812; PGSO-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
813; PGSO:       scalar.ph:
814; PGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
815; PGSO-NEXT:    br label [[FOR_BODY:%.*]]
816; PGSO:       for.body:
817; PGSO-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
818; PGSO-NEXT:    [[MULB:%.*]] = mul nsw i32 [[IV]], [[BSTRIDE]]
819; PGSO-NEXT:    [[GEPOFB:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[MULB]]
820; PGSO-NEXT:    store i16 42, i16* [[GEPOFB]], align 4
821; PGSO-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
822; PGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV_NEXT]], 1025
823; PGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]]
824; PGSO:       for.end:
825; PGSO-NEXT:    ret void
826;
827; NPGSO-LABEL: @stride1_pgso(
828; NPGSO-NEXT:  entry:
829; NPGSO-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
830; NPGSO:       vector.scevcheck:
831; NPGSO-NEXT:    [[IDENT_CHECK:%.*]] = icmp ne i32 [[BSTRIDE:%.*]], 1
832; NPGSO-NEXT:    br i1 [[IDENT_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
833; NPGSO:       vector.ph:
834; NPGSO-NEXT:    br label [[VECTOR_BODY:%.*]]
835; NPGSO:       vector.body:
836; NPGSO-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
837; NPGSO-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
838; NPGSO-NEXT:    [[TMP1:%.*]] = mul nsw i32 [[TMP0]], [[BSTRIDE]]
839; NPGSO-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i16, i16* [[B:%.*]], i32 [[TMP1]]
840; NPGSO-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, i16* [[TMP2]], i32 0
841; NPGSO-NEXT:    [[TMP4:%.*]] = bitcast i16* [[TMP3]] to <2 x i16>*
842; NPGSO-NEXT:    store <2 x i16> <i16 42, i16 42>, <2 x i16>* [[TMP4]], align 4
843; NPGSO-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
844; NPGSO-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1024
845; NPGSO-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP31:![0-9]+]]
846; NPGSO:       middle.block:
847; NPGSO-NEXT:    [[CMP_N:%.*]] = icmp eq i32 1025, 1024
848; NPGSO-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
849; NPGSO:       scalar.ph:
850; NPGSO-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
851; NPGSO-NEXT:    br label [[FOR_BODY:%.*]]
852; NPGSO:       for.body:
853; NPGSO-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
854; NPGSO-NEXT:    [[MULB:%.*]] = mul nsw i32 [[IV]], [[BSTRIDE]]
855; NPGSO-NEXT:    [[GEPOFB:%.*]] = getelementptr inbounds i16, i16* [[B]], i32 [[MULB]]
856; NPGSO-NEXT:    store i16 42, i16* [[GEPOFB]], align 4
857; NPGSO-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
858; NPGSO-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV_NEXT]], 1025
859; NPGSO-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]]
860; NPGSO:       for.end:
861; NPGSO-NEXT:    ret void
862;
863entry:
864  br label %for.body
865
866for.body:
867  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
868  %mulB = mul nsw i32 %iv, %BStride
869  %gepOfB = getelementptr inbounds i16, i16* %B, i32 %mulB
870  store i16 42, i16* %gepOfB, align 4
871  %iv.next = add nuw nsw i32 %iv, 1
872  %exitcond = icmp eq i32 %iv.next, 1025
873  br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !15
874
875for.end:
876  ret void
877}
878
879; PR46652: Check that the need for stride==1 check prevents vectorizing a loop
880; having tiny trip count, when compiling w/o -Os/-Oz.
881
882@g = external global [1 x i16], align 1
883
884define void @pr46652(i16 %stride) {
885; DEFAULT-LABEL: @pr46652(
886; DEFAULT-NEXT:  entry:
887; DEFAULT-NEXT:    br label [[FOR_BODY:%.*]]
888; DEFAULT:       for.body:
889; DEFAULT-NEXT:    [[L1_02:%.*]] = phi i16 [ 1, [[ENTRY:%.*]] ], [ [[INC9:%.*]], [[FOR_BODY]] ]
890; DEFAULT-NEXT:    [[MUL:%.*]] = mul nsw i16 [[L1_02]], [[STRIDE:%.*]]
891; DEFAULT-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [1 x i16], [1 x i16]* @g, i16 0, i16 [[MUL]]
892; DEFAULT-NEXT:    [[TMP0:%.*]] = load i16, i16* [[ARRAYIDX6]], align 1
893; DEFAULT-NEXT:    [[INC9]] = add nuw nsw i16 [[L1_02]], 1
894; DEFAULT-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i16 [[INC9]], 16
895; DEFAULT-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
896; DEFAULT:       for.end:
897; DEFAULT-NEXT:    ret void
898;
899entry:
900  br label %for.body
901
902for.body:                                        ; preds = %for.body, %entry
903  %l1.02 = phi i16 [ 1, %entry ], [ %inc9, %for.body ]
904  %mul = mul nsw i16 %l1.02, %stride
905  %arrayidx6 = getelementptr inbounds [1 x i16], [1 x i16]* @g, i16 0, i16 %mul
906  %0 = load i16, i16* %arrayidx6, align 1
907  %inc9 = add nuw nsw i16 %l1.02, 1
908  %exitcond.not = icmp eq i16 %inc9, 16
909  br i1 %exitcond.not, label %for.end, label %for.body
910
911for.end:                                        ; preds = %for.body
912  ret void
913}
914
915; Make sure we do not crash while building the VPlan for the loop with the
916; select below.
917define i32 @PR48142(i32* %ptr.start, i32* %ptr.end) optsize {
918; DEFAULT-LABEL: @PR48142(
919; DEFAULT-NEXT:  entry:
920; DEFAULT-NEXT:    br label [[FOR_BODY:%.*]]
921; DEFAULT:       for.body:
922; DEFAULT-NEXT:    [[I_014:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ [[COND:%.*]], [[FOR_BODY]] ]
923; DEFAULT-NEXT:    [[PTR_IV:%.*]] = phi i32* [ [[PTR_START:%.*]], [[ENTRY]] ], [ [[PTR_NEXT:%.*]], [[FOR_BODY]] ]
924; DEFAULT-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I_014]], 99
925; DEFAULT-NEXT:    [[COND]] = select i1 [[CMP4]], i32 99, i32 [[I_014]]
926; DEFAULT-NEXT:    store i32 0, i32* [[PTR_IV]], align 4
927; DEFAULT-NEXT:    [[PTR_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
928; DEFAULT-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32* [[PTR_NEXT]], [[PTR_END:%.*]]
929; DEFAULT-NEXT:    br i1 [[CMP_NOT]], label [[EXIT:%.*]], label [[FOR_BODY]]
930; DEFAULT:       exit:
931; DEFAULT-NEXT:    [[RES:%.*]] = phi i32 [ [[COND]], [[FOR_BODY]] ]
932; DEFAULT-NEXT:    ret i32 [[RES]]
933;
934entry:
935  br label %for.body
936
937for.body:
938  %i.014 = phi i32 [ 20, %entry ], [ %cond, %for.body ]
939  %ptr.iv = phi i32* [ %ptr.start, %entry ], [ %ptr.next, %for.body ]
940  %cmp4 = icmp slt i32 %i.014, 99
941  %cond = select i1 %cmp4, i32 99, i32 %i.014
942  store i32 0, i32* %ptr.iv
943  %ptr.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
944  %cmp.not = icmp eq i32* %ptr.next, %ptr.end
945  br i1 %cmp.not, label %exit, label %for.body
946
947exit:
948  %res = phi i32 [ %cond, %for.body ]
949  ret i32 %res
950}
951
952!llvm.module.flags = !{!0}
953!0 = !{i32 1, !"ProfileSummary", !1}
954!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
955!2 = !{!"ProfileFormat", !"InstrProf"}
956!3 = !{!"TotalCount", i64 10000}
957!4 = !{!"MaxCount", i64 10}
958!5 = !{!"MaxInternalCount", i64 1}
959!6 = !{!"MaxFunctionCount", i64 1000}
960!7 = !{!"NumCounts", i64 3}
961!8 = !{!"NumFunctions", i64 3}
962!9 = !{!"DetailedSummary", !10}
963!10 = !{!11, !12, !13}
964!11 = !{i32 10000, i64 100, i32 1}
965!12 = !{i32 999000, i64 100, i32 1}
966!13 = !{i32 999999, i64 1, i32 2}
967!14 = !{!"function_entry_count", i64 0}
968!15 = distinct !{!15, !16}
969!16 = !{!"llvm.loop.vectorize.enable", i1 true}
970