1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s  -loop-vectorize -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx -S | FileCheck %s
3
4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
5target triple = "x86_64-apple-macosx10.8.0"
6
7@c = common global [2048 x i32] zeroinitializer, align 16
8@b = common global [2048 x i32] zeroinitializer, align 16
9@d = common global [2048 x i32] zeroinitializer, align 16
10@a = common global [2048 x i32] zeroinitializer, align 16
11
12; The program below gathers and scatters data. We better not vectorize it.
13define void @cost_model_1() nounwind uwtable noinline ssp {
14; CHECK-LABEL: @cost_model_1(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
17; CHECK:       for.body:
18; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
19; CHECK-NEXT:    [[TMP0:%.*]] = shl nsw i64 [[INDVARS_IV]], 1
20; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @c, i64 0, i64 [[TMP0]]
21; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 8
22; CHECK-NEXT:    [[IDXPROM1:%.*]] = sext i32 [[TMP1]] to i64
23; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @b, i64 0, i64 [[IDXPROM1]]
24; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
25; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @d, i64 0, i64 [[INDVARS_IV]]
26; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4
27; CHECK-NEXT:    [[IDXPROM5:%.*]] = sext i32 [[TMP3]] to i64
28; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [2048 x i32], [2048 x i32]* @a, i64 0, i64 [[IDXPROM5]]
29; CHECK-NEXT:    store i32 [[TMP2]], i32* [[ARRAYIDX6]], align 4
30; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
31; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
32; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], 256
33; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
34; CHECK:       for.end:
35; CHECK-NEXT:    ret void
36;
37entry:
38  br label %for.body
39
40for.body:                                         ; preds = %for.body, %entry
41  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
42  %0 = shl nsw i64 %indvars.iv, 1
43  %arrayidx = getelementptr inbounds [2048 x i32], [2048 x i32]* @c, i64 0, i64 %0
44  %1 = load i32, i32* %arrayidx, align 8
45  %idxprom1 = sext i32 %1 to i64
46  %arrayidx2 = getelementptr inbounds [2048 x i32], [2048 x i32]* @b, i64 0, i64 %idxprom1
47  %2 = load i32, i32* %arrayidx2, align 4
48  %arrayidx4 = getelementptr inbounds [2048 x i32], [2048 x i32]* @d, i64 0, i64 %indvars.iv
49  %3 = load i32, i32* %arrayidx4, align 4
50  %idxprom5 = sext i32 %3 to i64
51  %arrayidx6 = getelementptr inbounds [2048 x i32], [2048 x i32]* @a, i64 0, i64 %idxprom5
52  store i32 %2, i32* %arrayidx6, align 4
53  %indvars.iv.next = add i64 %indvars.iv, 1
54  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
55  %exitcond = icmp eq i32 %lftr.wideiv, 256
56  br i1 %exitcond, label %for.end, label %for.body
57
58for.end:                                          ; preds = %for.body
59  ret void
60}
61
62; This function uses a stride that is generally too big to benefit from vectorization without
63; really good support for a gather load. But if we don't vectorize the pointer induction,
64; then we don't need to extract the pointers out of vector of pointers,
65; and the vectorization becomes profitable.
66
67define float @PR27826(float* nocapture readonly %a, float* nocapture readonly %b, i32 %n) {
68; CHECK-LABEL: @PR27826(
69; CHECK-NEXT:  entry:
70; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], 0
71; CHECK-NEXT:    br i1 [[CMP]], label [[PREHEADER:%.*]], label [[FOR_END:%.*]]
72; CHECK:       preheader:
73; CHECK-NEXT:    [[T0:%.*]] = sext i32 [[N]] to i64
74; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i64 [[T0]], -1
75; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 5
76; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
77; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 16
78; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
79; CHECK:       vector.ph:
80; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 16
81; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
82; CHECK-NEXT:    [[IND_END:%.*]] = mul i64 [[N_VEC]], 32
83; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
84; CHECK:       vector.body:
85; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
86; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP119:%.*]], [[VECTOR_BODY]] ]
87; CHECK-NEXT:    [[VEC_PHI1:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP120:%.*]], [[VECTOR_BODY]] ]
88; CHECK-NEXT:    [[VEC_PHI2:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP121:%.*]], [[VECTOR_BODY]] ]
89; CHECK-NEXT:    [[VEC_PHI3:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP122:%.*]], [[VECTOR_BODY]] ]
90; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 32
91; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0
92; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 32
93; CHECK-NEXT:    [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], 64
94; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 96
95; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[OFFSET_IDX]], 128
96; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[OFFSET_IDX]], 160
97; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[OFFSET_IDX]], 192
98; CHECK-NEXT:    [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 224
99; CHECK-NEXT:    [[TMP11:%.*]] = add i64 [[OFFSET_IDX]], 256
100; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[OFFSET_IDX]], 288
101; CHECK-NEXT:    [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 320
102; CHECK-NEXT:    [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 352
103; CHECK-NEXT:    [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 384
104; CHECK-NEXT:    [[TMP16:%.*]] = add i64 [[OFFSET_IDX]], 416
105; CHECK-NEXT:    [[TMP17:%.*]] = add i64 [[OFFSET_IDX]], 448
106; CHECK-NEXT:    [[TMP18:%.*]] = add i64 [[OFFSET_IDX]], 480
107; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[TMP3]]
108; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP4]]
109; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP5]]
110; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP6]]
111; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP7]]
112; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP8]]
113; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]]
114; CHECK-NEXT:    [[TMP26:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP10]]
115; CHECK-NEXT:    [[TMP27:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP11]]
116; CHECK-NEXT:    [[TMP28:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP12]]
117; CHECK-NEXT:    [[TMP29:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP13]]
118; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP14]]
119; CHECK-NEXT:    [[TMP31:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]]
120; CHECK-NEXT:    [[TMP32:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP16]]
121; CHECK-NEXT:    [[TMP33:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP17]]
122; CHECK-NEXT:    [[TMP34:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP18]]
123; CHECK-NEXT:    [[TMP35:%.*]] = load float, float* [[TMP19]], align 4
124; CHECK-NEXT:    [[TMP36:%.*]] = load float, float* [[TMP20]], align 4
125; CHECK-NEXT:    [[TMP37:%.*]] = load float, float* [[TMP21]], align 4
126; CHECK-NEXT:    [[TMP38:%.*]] = load float, float* [[TMP22]], align 4
127; CHECK-NEXT:    [[TMP39:%.*]] = insertelement <4 x float> poison, float [[TMP35]], i32 0
128; CHECK-NEXT:    [[TMP40:%.*]] = insertelement <4 x float> [[TMP39]], float [[TMP36]], i32 1
129; CHECK-NEXT:    [[TMP41:%.*]] = insertelement <4 x float> [[TMP40]], float [[TMP37]], i32 2
130; CHECK-NEXT:    [[TMP42:%.*]] = insertelement <4 x float> [[TMP41]], float [[TMP38]], i32 3
131; CHECK-NEXT:    [[TMP43:%.*]] = load float, float* [[TMP23]], align 4
132; CHECK-NEXT:    [[TMP44:%.*]] = load float, float* [[TMP24]], align 4
133; CHECK-NEXT:    [[TMP45:%.*]] = load float, float* [[TMP25]], align 4
134; CHECK-NEXT:    [[TMP46:%.*]] = load float, float* [[TMP26]], align 4
135; CHECK-NEXT:    [[TMP47:%.*]] = insertelement <4 x float> poison, float [[TMP43]], i32 0
136; CHECK-NEXT:    [[TMP48:%.*]] = insertelement <4 x float> [[TMP47]], float [[TMP44]], i32 1
137; CHECK-NEXT:    [[TMP49:%.*]] = insertelement <4 x float> [[TMP48]], float [[TMP45]], i32 2
138; CHECK-NEXT:    [[TMP50:%.*]] = insertelement <4 x float> [[TMP49]], float [[TMP46]], i32 3
139; CHECK-NEXT:    [[TMP51:%.*]] = load float, float* [[TMP27]], align 4
140; CHECK-NEXT:    [[TMP52:%.*]] = load float, float* [[TMP28]], align 4
141; CHECK-NEXT:    [[TMP53:%.*]] = load float, float* [[TMP29]], align 4
142; CHECK-NEXT:    [[TMP54:%.*]] = load float, float* [[TMP30]], align 4
143; CHECK-NEXT:    [[TMP55:%.*]] = insertelement <4 x float> poison, float [[TMP51]], i32 0
144; CHECK-NEXT:    [[TMP56:%.*]] = insertelement <4 x float> [[TMP55]], float [[TMP52]], i32 1
145; CHECK-NEXT:    [[TMP57:%.*]] = insertelement <4 x float> [[TMP56]], float [[TMP53]], i32 2
146; CHECK-NEXT:    [[TMP58:%.*]] = insertelement <4 x float> [[TMP57]], float [[TMP54]], i32 3
147; CHECK-NEXT:    [[TMP59:%.*]] = load float, float* [[TMP31]], align 4
148; CHECK-NEXT:    [[TMP60:%.*]] = load float, float* [[TMP32]], align 4
149; CHECK-NEXT:    [[TMP61:%.*]] = load float, float* [[TMP33]], align 4
150; CHECK-NEXT:    [[TMP62:%.*]] = load float, float* [[TMP34]], align 4
151; CHECK-NEXT:    [[TMP63:%.*]] = insertelement <4 x float> poison, float [[TMP59]], i32 0
152; CHECK-NEXT:    [[TMP64:%.*]] = insertelement <4 x float> [[TMP63]], float [[TMP60]], i32 1
153; CHECK-NEXT:    [[TMP65:%.*]] = insertelement <4 x float> [[TMP64]], float [[TMP61]], i32 2
154; CHECK-NEXT:    [[TMP66:%.*]] = insertelement <4 x float> [[TMP65]], float [[TMP62]], i32 3
155; CHECK-NEXT:    [[TMP67:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 [[TMP3]]
156; CHECK-NEXT:    [[TMP68:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP4]]
157; CHECK-NEXT:    [[TMP69:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP5]]
158; CHECK-NEXT:    [[TMP70:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP6]]
159; CHECK-NEXT:    [[TMP71:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP7]]
160; CHECK-NEXT:    [[TMP72:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP8]]
161; CHECK-NEXT:    [[TMP73:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP9]]
162; CHECK-NEXT:    [[TMP74:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP10]]
163; CHECK-NEXT:    [[TMP75:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP11]]
164; CHECK-NEXT:    [[TMP76:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP12]]
165; CHECK-NEXT:    [[TMP77:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP13]]
166; CHECK-NEXT:    [[TMP78:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP14]]
167; CHECK-NEXT:    [[TMP79:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP15]]
168; CHECK-NEXT:    [[TMP80:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP16]]
169; CHECK-NEXT:    [[TMP81:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP17]]
170; CHECK-NEXT:    [[TMP82:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[TMP18]]
171; CHECK-NEXT:    [[TMP83:%.*]] = load float, float* [[TMP67]], align 4
172; CHECK-NEXT:    [[TMP84:%.*]] = load float, float* [[TMP68]], align 4
173; CHECK-NEXT:    [[TMP85:%.*]] = load float, float* [[TMP69]], align 4
174; CHECK-NEXT:    [[TMP86:%.*]] = load float, float* [[TMP70]], align 4
175; CHECK-NEXT:    [[TMP87:%.*]] = insertelement <4 x float> poison, float [[TMP83]], i32 0
176; CHECK-NEXT:    [[TMP88:%.*]] = insertelement <4 x float> [[TMP87]], float [[TMP84]], i32 1
177; CHECK-NEXT:    [[TMP89:%.*]] = insertelement <4 x float> [[TMP88]], float [[TMP85]], i32 2
178; CHECK-NEXT:    [[TMP90:%.*]] = insertelement <4 x float> [[TMP89]], float [[TMP86]], i32 3
179; CHECK-NEXT:    [[TMP91:%.*]] = load float, float* [[TMP71]], align 4
180; CHECK-NEXT:    [[TMP92:%.*]] = load float, float* [[TMP72]], align 4
181; CHECK-NEXT:    [[TMP93:%.*]] = load float, float* [[TMP73]], align 4
182; CHECK-NEXT:    [[TMP94:%.*]] = load float, float* [[TMP74]], align 4
183; CHECK-NEXT:    [[TMP95:%.*]] = insertelement <4 x float> poison, float [[TMP91]], i32 0
184; CHECK-NEXT:    [[TMP96:%.*]] = insertelement <4 x float> [[TMP95]], float [[TMP92]], i32 1
185; CHECK-NEXT:    [[TMP97:%.*]] = insertelement <4 x float> [[TMP96]], float [[TMP93]], i32 2
186; CHECK-NEXT:    [[TMP98:%.*]] = insertelement <4 x float> [[TMP97]], float [[TMP94]], i32 3
187; CHECK-NEXT:    [[TMP99:%.*]] = load float, float* [[TMP75]], align 4
188; CHECK-NEXT:    [[TMP100:%.*]] = load float, float* [[TMP76]], align 4
189; CHECK-NEXT:    [[TMP101:%.*]] = load float, float* [[TMP77]], align 4
190; CHECK-NEXT:    [[TMP102:%.*]] = load float, float* [[TMP78]], align 4
191; CHECK-NEXT:    [[TMP103:%.*]] = insertelement <4 x float> poison, float [[TMP99]], i32 0
192; CHECK-NEXT:    [[TMP104:%.*]] = insertelement <4 x float> [[TMP103]], float [[TMP100]], i32 1
193; CHECK-NEXT:    [[TMP105:%.*]] = insertelement <4 x float> [[TMP104]], float [[TMP101]], i32 2
194; CHECK-NEXT:    [[TMP106:%.*]] = insertelement <4 x float> [[TMP105]], float [[TMP102]], i32 3
195; CHECK-NEXT:    [[TMP107:%.*]] = load float, float* [[TMP79]], align 4
196; CHECK-NEXT:    [[TMP108:%.*]] = load float, float* [[TMP80]], align 4
197; CHECK-NEXT:    [[TMP109:%.*]] = load float, float* [[TMP81]], align 4
198; CHECK-NEXT:    [[TMP110:%.*]] = load float, float* [[TMP82]], align 4
199; CHECK-NEXT:    [[TMP111:%.*]] = insertelement <4 x float> poison, float [[TMP107]], i32 0
200; CHECK-NEXT:    [[TMP112:%.*]] = insertelement <4 x float> [[TMP111]], float [[TMP108]], i32 1
201; CHECK-NEXT:    [[TMP113:%.*]] = insertelement <4 x float> [[TMP112]], float [[TMP109]], i32 2
202; CHECK-NEXT:    [[TMP114:%.*]] = insertelement <4 x float> [[TMP113]], float [[TMP110]], i32 3
203; CHECK-NEXT:    [[TMP115:%.*]] = fadd fast <4 x float> [[TMP42]], [[VEC_PHI]]
204; CHECK-NEXT:    [[TMP116:%.*]] = fadd fast <4 x float> [[TMP50]], [[VEC_PHI1]]
205; CHECK-NEXT:    [[TMP117:%.*]] = fadd fast <4 x float> [[TMP58]], [[VEC_PHI2]]
206; CHECK-NEXT:    [[TMP118:%.*]] = fadd fast <4 x float> [[TMP66]], [[VEC_PHI3]]
207; CHECK-NEXT:    [[TMP119]] = fadd fast <4 x float> [[TMP115]], [[TMP90]]
208; CHECK-NEXT:    [[TMP120]] = fadd fast <4 x float> [[TMP116]], [[TMP98]]
209; CHECK-NEXT:    [[TMP121]] = fadd fast <4 x float> [[TMP117]], [[TMP106]]
210; CHECK-NEXT:    [[TMP122]] = fadd fast <4 x float> [[TMP118]], [[TMP114]]
211; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16
212; CHECK-NEXT:    [[TMP123:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
213; CHECK-NEXT:    br i1 [[TMP123]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
214; CHECK:       middle.block:
215; CHECK-NEXT:    [[BIN_RDX:%.*]] = fadd fast <4 x float> [[TMP120]], [[TMP119]]
216; CHECK-NEXT:    [[BIN_RDX4:%.*]] = fadd fast <4 x float> [[TMP121]], [[BIN_RDX]]
217; CHECK-NEXT:    [[BIN_RDX5:%.*]] = fadd fast <4 x float> [[TMP122]], [[BIN_RDX4]]
218; CHECK-NEXT:    [[TMP124:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> [[BIN_RDX5]])
219; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
220; CHECK-NEXT:    br i1 [[CMP_N]], label [[LOOPEXIT:%.*]], label [[SCALAR_PH]]
221; CHECK:       scalar.ph:
222; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[PREHEADER]] ]
223; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ 0.000000e+00, [[PREHEADER]] ], [ [[TMP124]], [[MIDDLE_BLOCK]] ]
224; CHECK-NEXT:    br label [[FOR:%.*]]
225; CHECK:       for:
226; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR]] ]
227; CHECK-NEXT:    [[S_02:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[ADD4:%.*]], [[FOR]] ]
228; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[INDVARS_IV]]
229; CHECK-NEXT:    [[T1:%.*]] = load float, float* [[ARRAYIDX]], align 4
230; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds float, float* [[B]], i64 [[INDVARS_IV]]
231; CHECK-NEXT:    [[T2:%.*]] = load float, float* [[ARRAYIDX3]], align 4
232; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[T1]], [[S_02]]
233; CHECK-NEXT:    [[ADD4]] = fadd fast float [[ADD]], [[T2]]
234; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 32
235; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[T0]]
236; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR]], label [[LOOPEXIT]], !llvm.loop [[LOOP2:![0-9]+]]
237; CHECK:       loopexit:
238; CHECK-NEXT:    [[ADD4_LCSSA:%.*]] = phi float [ [[ADD4]], [[FOR]] ], [ [[TMP124]], [[MIDDLE_BLOCK]] ]
239; CHECK-NEXT:    br label [[FOR_END]]
240; CHECK:       for.end:
241; CHECK-NEXT:    [[S_0_LCSSA:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[ADD4_LCSSA]], [[LOOPEXIT]] ]
242; CHECK-NEXT:    ret float [[S_0_LCSSA]]
243;
244entry:
245  %cmp = icmp sgt i32 %n, 0
246  br i1 %cmp, label %preheader, label %for.end
247
248preheader:
249  %t0 = sext i32 %n to i64
250  br label %for
251
252for:
253  %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %for ]
254  %s.02 = phi float [ 0.0, %preheader ], [ %add4, %for ]
255  %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv
256  %t1 = load float, float* %arrayidx, align 4
257  %arrayidx3 = getelementptr inbounds float, float* %b, i64 %indvars.iv
258  %t2 = load float, float* %arrayidx3, align 4
259  %add = fadd fast float %t1, %s.02
260  %add4 = fadd fast float %add, %t2
261  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 32
262  %cmp1 = icmp slt i64 %indvars.iv.next, %t0
263  br i1 %cmp1, label %for, label %loopexit
264
265loopexit:
266  %add4.lcssa = phi float [ %add4, %for ]
267  br label %for.end
268
269for.end:
270  %s.0.lcssa = phi float [ 0.0, %entry ], [ %add4.lcssa, %loopexit ]
271  ret float %s.0.lcssa
272}
273
274