xref: /llvm-project/llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 4
2; RUN: opt < %s -passes=loop-vectorize,dce,instcombine -force-vector-interleave=1 -force-vector-width=4 -prefer-inloop-reductions -S | FileCheck %s
3
4define float @cond_fadd(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %cond, i64 %N){
5; CHECK-LABEL: define float @cond_fadd(
6; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[COND:%.*]], i64 [[N:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
9; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
10; CHECK:       vector.ph:
11; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
12; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
13; CHECK:       vector.body:
14; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
15; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[PRED_LOAD_CONTINUE6]] ]
16; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]
17; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP0]], align 4
18; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], splat (float 5.000000e+00)
19; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0
20; CHECK-NEXT:    br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
21; CHECK:       pred.load.if:
22; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX]]
23; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[TMP3]], align 4
24; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x float> poison, float [[TMP4]], i64 0
25; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
26; CHECK:       pred.load.continue:
27; CHECK-NEXT:    [[TMP6:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]
28; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1
29; CHECK-NEXT:    br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
30; CHECK:       pred.load.if1:
31; CHECK-NEXT:    [[TMP8:%.*]] = or disjoint i64 [[INDEX]], 1
32; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP8]]
33; CHECK-NEXT:    [[TMP10:%.*]] = load float, ptr [[TMP9]], align 4
34; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x float> [[TMP6]], float [[TMP10]], i64 1
35; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
36; CHECK:       pred.load.continue2:
37; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x float> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]
38; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2
39; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
40; CHECK:       pred.load.if3:
41; CHECK-NEXT:    [[TMP14:%.*]] = or disjoint i64 [[INDEX]], 2
42; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP14]]
43; CHECK-NEXT:    [[TMP16:%.*]] = load float, ptr [[TMP15]], align 4
44; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x float> [[TMP12]], float [[TMP16]], i64 2
45; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
46; CHECK:       pred.load.continue4:
47; CHECK-NEXT:    [[TMP18:%.*]] = phi <4 x float> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]
48; CHECK-NEXT:    [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3
49; CHECK-NEXT:    br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
50; CHECK:       pred.load.if5:
51; CHECK-NEXT:    [[TMP20:%.*]] = or disjoint i64 [[INDEX]], 3
52; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP20]]
53; CHECK-NEXT:    [[TMP22:%.*]] = load float, ptr [[TMP21]], align 4
54; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x float> [[TMP18]], float [[TMP22]], i64 3
55; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
56; CHECK:       pred.load.continue6:
57; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x float> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
58; CHECK-NEXT:    [[TMP25:%.*]] = select fast <4 x i1> [[TMP1]], <4 x float> [[TMP24]], <4 x float> zeroinitializer
59; CHECK-NEXT:    [[TMP26]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[VEC_PHI]], <4 x float> [[TMP25]])
60; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
61; CHECK-NEXT:    [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
62; CHECK-NEXT:    br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
63; CHECK:       middle.block:
64; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
65; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
66; CHECK:       scalar.ph:
67; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
68; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP26]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
69; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
70; CHECK:       for.body:
71; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
72; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
73; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]
74; CHECK-NEXT:    [[TMP28:%.*]] = load float, ptr [[ARRAYIDX]], align 4
75; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP28]], 5.000000e+00
76; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
77; CHECK:       if.then:
78; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]
79; CHECK-NEXT:    [[TMP29:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
80; CHECK-NEXT:    [[FADD:%.*]] = fadd fast float [[RDX]], [[TMP29]]
81; CHECK-NEXT:    br label [[FOR_INC]]
82; CHECK:       for.inc:
83; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FADD]], [[IF_THEN]] ]
84; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
85; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
86; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
87; CHECK:       for.end:
88; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP26]], [[MIDDLE_BLOCK]] ]
89; CHECK-NEXT:    ret float [[RES_LCSSA]]
90;
91entry:
92  br label %for.body
93
94for.body:
95  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
96  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
97  %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv
98  %0 = load float, ptr %arrayidx
99  %tobool = fcmp une float %0, 5.000000e+00
100  br i1 %tobool, label %if.then, label %for.inc
101
102if.then:
103  %arrayidx2 = getelementptr inbounds float, ptr %a, i64 %iv
104  %1 = load float, ptr %arrayidx2
105  %fadd = fadd fast float %rdx, %1
106  br label %for.inc
107
108for.inc:
109  %res = phi float [ %rdx, %for.body ], [ %fadd, %if.then ]
110  %iv.next = add i64 %iv, 1
111  %exitcond.not = icmp eq i64 %iv.next, %N
112  br i1 %exitcond.not, label %for.end, label %for.body
113
114for.end:
115  ret float %res
116}
117
118define float @cond_cmp_sel(ptr noalias %a, ptr noalias %cond, i64 %N) {
119; CHECK-LABEL: define float @cond_cmp_sel(
120; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {
121; CHECK-NEXT:  entry:
122; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
123; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
124; CHECK:       vector.ph:
125; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
126; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
127; CHECK:       vector.body:
128; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
129; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[RDX_MINMAX_SELECT:%.*]], [[PRED_LOAD_CONTINUE6]] ]
130; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]
131; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP0]], align 4
132; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], splat (float 3.000000e+00)
133; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0
134; CHECK-NEXT:    br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
135; CHECK:       pred.load.if:
136; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX]]
137; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[TMP3]], align 4
138; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x float> poison, float [[TMP4]], i64 0
139; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
140; CHECK:       pred.load.continue:
141; CHECK-NEXT:    [[TMP6:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]
142; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1
143; CHECK-NEXT:    br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
144; CHECK:       pred.load.if1:
145; CHECK-NEXT:    [[TMP8:%.*]] = or disjoint i64 [[INDEX]], 1
146; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP8]]
147; CHECK-NEXT:    [[TMP10:%.*]] = load float, ptr [[TMP9]], align 4
148; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x float> [[TMP6]], float [[TMP10]], i64 1
149; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
150; CHECK:       pred.load.continue2:
151; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x float> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]
152; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2
153; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
154; CHECK:       pred.load.if3:
155; CHECK-NEXT:    [[TMP14:%.*]] = or disjoint i64 [[INDEX]], 2
156; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP14]]
157; CHECK-NEXT:    [[TMP16:%.*]] = load float, ptr [[TMP15]], align 4
158; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x float> [[TMP12]], float [[TMP16]], i64 2
159; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
160; CHECK:       pred.load.continue4:
161; CHECK-NEXT:    [[TMP18:%.*]] = phi <4 x float> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]
162; CHECK-NEXT:    [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3
163; CHECK-NEXT:    br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
164; CHECK:       pred.load.if5:
165; CHECK-NEXT:    [[TMP20:%.*]] = or disjoint i64 [[INDEX]], 3
166; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[TMP20]]
167; CHECK-NEXT:    [[TMP22:%.*]] = load float, ptr [[TMP21]], align 4
168; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x float> [[TMP18]], float [[TMP22]], i64 3
169; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
170; CHECK:       pred.load.continue6:
171; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x float> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
172; CHECK-NEXT:    [[TMP25:%.*]] = select fast <4 x i1> [[TMP1]], <4 x float> [[TMP24]], <4 x float> splat (float 0x47EFFFFFE0000000)
173; CHECK-NEXT:    [[TMP26:%.*]] = call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[TMP25]])
174; CHECK-NEXT:    [[RDX_MINMAX_SELECT]] = call fast float @llvm.minnum.f32(float [[TMP26]], float [[VEC_PHI]])
175; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
176; CHECK-NEXT:    [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
177; CHECK-NEXT:    br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
178; CHECK:       middle.block:
179; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
180; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
181; CHECK:       scalar.ph:
182; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
183; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[RDX_MINMAX_SELECT]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
184; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
185; CHECK:       for.body:
186; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
187; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
188; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]
189; CHECK-NEXT:    [[TMP28:%.*]] = load float, ptr [[ARRAYIDX]], align 4
190; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP28]], 3.000000e+00
191; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
192; CHECK:       if.then:
193; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]
194; CHECK-NEXT:    [[TMP29:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
195; CHECK-NEXT:    [[FSEL:%.*]] = call fast float @llvm.minnum.f32(float [[RDX]], float [[TMP29]])
196; CHECK-NEXT:    br label [[FOR_INC]]
197; CHECK:       for.inc:
198; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FSEL]], [[IF_THEN]] ]
199; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
200; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
201; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
202; CHECK:       for.end:
203; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[RDX_MINMAX_SELECT]], [[MIDDLE_BLOCK]] ]
204; CHECK-NEXT:    ret float [[RES_LCSSA]]
205;
206entry:
207  br label %for.body
208
209for.body:
210  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
211  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
212  %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv
213  %0 = load float, ptr %arrayidx
214  %tobool = fcmp une float %0, 3.000000e+00
215  br i1 %tobool, label %if.then, label %for.inc
216
217if.then:
218  %arrayidx2 = getelementptr inbounds float, ptr %a, i64 %iv
219  %1 = load float, ptr %arrayidx2
220  %fcmp = fcmp fast olt float %rdx, %1
221  %fsel = select fast i1 %fcmp, float %rdx, float %1
222  br label %for.inc
223
224for.inc:
225  %res = phi float [ %rdx, %for.body ], [ %fsel, %if.then ]
226  %iv.next = add i64 %iv, 1
227  %exitcond.not = icmp eq i64 %iv.next, %N
228  br i1 %exitcond.not, label %for.end, label %for.body
229
230for.end:
231  ret float %res
232}
233
234define i32 @conditional_and(ptr noalias %A, ptr noalias %B, i32 %cond, i64 noundef %N) #0 {
235; CHECK-LABEL: define i32 @conditional_and(
236; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i32 [[COND:%.*]], i64 noundef [[N:%.*]]) {
237; CHECK-NEXT:  entry:
238; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
239; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
240; CHECK:       vector.ph:
241; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
242; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[COND]], i64 0
243; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
244; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
245; CHECK:       vector.body:
246; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
247; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 7, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]
248; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
249; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
250; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
251; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0
252; CHECK-NEXT:    br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
253; CHECK:       pred.load.if:
254; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDEX]]
255; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
256; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0
257; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
258; CHECK:       pred.load.continue:
259; CHECK-NEXT:    [[TMP6:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]
260; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1
261; CHECK-NEXT:    br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
262; CHECK:       pred.load.if1:
263; CHECK-NEXT:    [[TMP8:%.*]] = or disjoint i64 [[INDEX]], 1
264; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP8]]
265; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4
266; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i32> [[TMP6]], i32 [[TMP10]], i64 1
267; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
268; CHECK:       pred.load.continue2:
269; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x i32> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]
270; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2
271; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
272; CHECK:       pred.load.if3:
273; CHECK-NEXT:    [[TMP14:%.*]] = or disjoint i64 [[INDEX]], 2
274; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP14]]
275; CHECK-NEXT:    [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4
276; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x i32> [[TMP12]], i32 [[TMP16]], i64 2
277; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
278; CHECK:       pred.load.continue4:
279; CHECK-NEXT:    [[TMP18:%.*]] = phi <4 x i32> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]
280; CHECK-NEXT:    [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3
281; CHECK-NEXT:    br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
282; CHECK:       pred.load.if5:
283; CHECK-NEXT:    [[TMP20:%.*]] = or disjoint i64 [[INDEX]], 3
284; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP20]]
285; CHECK-NEXT:    [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4
286; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x i32> [[TMP18]], i32 [[TMP22]], i64 3
287; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
288; CHECK:       pred.load.continue6:
289; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x i32> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
290; CHECK-NEXT:    [[TMP25:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP24]], <4 x i32> splat (i32 -1)
291; CHECK-NEXT:    [[TMP26:%.*]] = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> [[TMP25]])
292; CHECK-NEXT:    [[TMP27]] = and i32 [[TMP26]], [[VEC_PHI]]
293; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
294; CHECK-NEXT:    [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
295; CHECK-NEXT:    br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
296; CHECK:       middle.block:
297; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
298; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
299; CHECK:       scalar.ph:
300; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
301; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP27]], [[MIDDLE_BLOCK]] ], [ 7, [[ENTRY]] ]
302; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
303; CHECK:       for.body:
304; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
305; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
306; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]
307; CHECK-NEXT:    [[TMP29:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
308; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP29]], [[COND]]
309; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
310; CHECK:       if.then:
311; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
312; CHECK-NEXT:    [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
313; CHECK-NEXT:    [[AND:%.*]] = and i32 [[TMP30]], [[RDX]]
314; CHECK-NEXT:    br label [[FOR_INC]]
315; CHECK:       for.inc:
316; CHECK-NEXT:    [[RES]] = phi i32 [ [[AND]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
317; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
318; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
319; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
320; CHECK:       for.end:
321; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP27]], [[MIDDLE_BLOCK]] ]
322; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
323;
324entry:
325  br label %for.body
326
327for.body:
328  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
329  %rdx = phi i32 [ 7, %entry ], [ %res, %for.inc ]
330  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %iv
331  %0 = load i32, ptr %arrayidx
332  %tobool = icmp eq i32 %0, %cond
333  br i1 %tobool, label %if.then, label %for.inc
334
335if.then:
336  %arrayidx2 = getelementptr inbounds i32, ptr %B, i64 %iv
337  %1 = load i32, ptr %arrayidx2
338  %and = and i32 %1, %rdx
339  br label %for.inc
340
341for.inc:
342  %res = phi i32 [ %and, %if.then ], [ %rdx, %for.body ]
343  %iv.next = add nuw nsw i64 %iv, 1
344  %exitcond.not = icmp eq i64 %iv.next, %N
345  br i1 %exitcond.not, label %for.end, label %for.body
346
347for.end:
348  ret i32 %res
349}
350
351define i32 @simple_chained_rdx(ptr noalias %a, ptr noalias %b, ptr noalias %cond, i64 noundef %N) {
352; CHECK-LABEL: define i32 @simple_chained_rdx(
353; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {
354; CHECK-NEXT:  entry:
355; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
356; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
357; CHECK:       vector.ph:
358; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
359; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
360; CHECK:       vector.body:
361; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
362; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 5, [[VECTOR_PH]] ], [ [[TMP46:%.*]], [[PRED_LOAD_CONTINUE6]] ]
363; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
364; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
365; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer
366; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0
367; CHECK-NEXT:    br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
368; CHECK:       pred.load.if:
369; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
370; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
371; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0
372; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDEX]]
373; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4
374; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <4 x i32> poison, i32 [[TMP7]], i64 0
375; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
376; CHECK:       pred.load.continue:
377; CHECK-NEXT:    [[TMP9:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]
378; CHECK-NEXT:    [[TMP10:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]
379; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1
380; CHECK-NEXT:    br i1 [[TMP11]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
381; CHECK:       pred.load.if1:
382; CHECK-NEXT:    [[TMP12:%.*]] = or disjoint i64 [[INDEX]], 1
383; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP12]]
384; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4
385; CHECK-NEXT:    [[TMP15:%.*]] = insertelement <4 x i32> [[TMP9]], i32 [[TMP14]], i64 1
386; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP12]]
387; CHECK-NEXT:    [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4
388; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x i32> [[TMP10]], i32 [[TMP17]], i64 1
389; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
390; CHECK:       pred.load.continue2:
391; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x i32> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]
392; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i32> [ [[TMP10]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP18]], [[PRED_LOAD_IF1]] ]
393; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2
394; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
395; CHECK:       pred.load.if3:
396; CHECK-NEXT:    [[TMP22:%.*]] = or disjoint i64 [[INDEX]], 2
397; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP22]]
398; CHECK-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
399; CHECK-NEXT:    [[TMP25:%.*]] = insertelement <4 x i32> [[TMP19]], i32 [[TMP24]], i64 2
400; CHECK-NEXT:    [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP22]]
401; CHECK-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
402; CHECK-NEXT:    [[TMP28:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP27]], i64 2
403; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
404; CHECK:       pred.load.continue4:
405; CHECK-NEXT:    [[TMP29:%.*]] = phi <4 x i32> [ [[TMP19]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP25]], [[PRED_LOAD_IF3]] ]
406; CHECK-NEXT:    [[TMP30:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP28]], [[PRED_LOAD_IF3]] ]
407; CHECK-NEXT:    [[TMP31:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3
408; CHECK-NEXT:    br i1 [[TMP31]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
409; CHECK:       pred.load.if5:
410; CHECK-NEXT:    [[TMP32:%.*]] = or disjoint i64 [[INDEX]], 3
411; CHECK-NEXT:    [[TMP33:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP32]]
412; CHECK-NEXT:    [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4
413; CHECK-NEXT:    [[TMP35:%.*]] = insertelement <4 x i32> [[TMP29]], i32 [[TMP34]], i64 3
414; CHECK-NEXT:    [[TMP36:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP32]]
415; CHECK-NEXT:    [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4
416; CHECK-NEXT:    [[TMP38:%.*]] = insertelement <4 x i32> [[TMP30]], i32 [[TMP37]], i64 3
417; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
418; CHECK:       pred.load.continue6:
419; CHECK-NEXT:    [[TMP39:%.*]] = phi <4 x i32> [ [[TMP29]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP35]], [[PRED_LOAD_IF5]] ]
420; CHECK-NEXT:    [[TMP40:%.*]] = phi <4 x i32> [ [[TMP30]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP38]], [[PRED_LOAD_IF5]] ]
421; CHECK-NEXT:    [[TMP41:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP39]], <4 x i32> zeroinitializer
422; CHECK-NEXT:    [[TMP42:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP41]])
423; CHECK-NEXT:    [[TMP43:%.*]] = add i32 [[TMP42]], [[VEC_PHI]]
424; CHECK-NEXT:    [[TMP44:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP40]], <4 x i32> zeroinitializer
425; CHECK-NEXT:    [[TMP45:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP44]])
426; CHECK-NEXT:    [[TMP46]] = add i32 [[TMP45]], [[TMP43]]
427; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
428; CHECK-NEXT:    [[TMP47:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
429; CHECK-NEXT:    br i1 [[TMP47]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
430; CHECK:       middle.block:
431; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
432; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
433; CHECK:       scalar.ph:
434; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
435; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP46]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]
436; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
437; CHECK:       for.body:
438; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
439; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
440; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]
441; CHECK-NEXT:    [[TMP48:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
442; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP48]], 0
443; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]
444; CHECK:       if.then:
445; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]
446; CHECK-NEXT:    [[TMP49:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
447; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP49]], [[RDX]]
448; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
449; CHECK-NEXT:    [[TMP50:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
450; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[ADD]], [[TMP50]]
451; CHECK-NEXT:    br label [[FOR_INC]]
452; CHECK:       for.inc:
453; CHECK-NEXT:    [[RES]] = phi i32 [ [[ADD3]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
454; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
455; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
456; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
457; CHECK:       for.end:
458; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP46]], [[MIDDLE_BLOCK]] ]
459; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
460;
461entry:
462  br label %for.body
463
464for.body:
465  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
466  %rdx = phi i32 [ %res, %for.inc ], [ 5, %entry ]
467  %arrayidx = getelementptr inbounds i32, ptr %cond, i64 %iv
468  %0 = load i32, ptr %arrayidx
469  %tobool.not = icmp eq i32 %0, 0
470  br i1 %tobool.not, label %for.inc, label %if.then
471
472if.then:
473  %arrayidx1 = getelementptr inbounds i32, ptr %a, i64 %iv
474  %1 = load i32, ptr %arrayidx1
475  %add = add nsw i32 %1, %rdx
476  %arrayidx2 = getelementptr inbounds i32, ptr %b, i64 %iv
477  %2 = load i32, ptr %arrayidx2
478  %add3 = add nsw i32 %add, %2
479  br label %for.inc
480
481for.inc:
482  %res = phi i32 [ %add3, %if.then ], [ %rdx, %for.body ]
483  %iv.next = add nuw nsw i64 %iv, 1
484  %exitcond.not = icmp eq i64 %iv.next, %N
485  br i1 %exitcond.not, label %for.end, label %for.body
486
487for.end:
488  ret i32 %res
489}
490
491;
492; Negative Tests
493;
494
495;
496; Reduction not performed in loop as the phi has more than two incoming values
497;
498define i64 @nested_cond_and(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, ptr noalias nocapture readonly %cond, i64 %N){
499; CHECK-LABEL: define i64 @nested_cond_and(
500; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[B:%.*]], ptr noalias readonly captures(none) [[COND:%.*]], i64 [[N:%.*]]) {
501; CHECK-NEXT:  entry:
502; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
503; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
504; CHECK:       vector.ph:
505; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
506; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
507; CHECK:       vector.body:
508; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]
509; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i64> [ <i64 5, i64 -1, i64 -1, i64 -1>, [[VECTOR_PH]] ], [ [[PREDPHI15:%.*]], [[PRED_LOAD_CONTINUE14]] ]
510; CHECK-NEXT:    [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1
511; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i64 [[INDEX]], 2
512; CHECK-NEXT:    [[TMP2:%.*]] = or disjoint i64 [[INDEX]], 3
513; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[COND]], i64 [[INDEX]]
514; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 4
515; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <4 x i64> [[WIDE_LOAD]], zeroinitializer
516; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x i1> [[TMP4]], i64 0
517; CHECK-NEXT:    br i1 [[TMP5]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
518; CHECK:       pred.load.if:
519; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[INDEX]]
520; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP6]], align 4
521; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <4 x i64> poison, i64 [[TMP7]], i64 0
522; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
523; CHECK:       pred.load.continue:
524; CHECK-NEXT:    [[TMP9:%.*]] = phi <4 x i64> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]
525; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <4 x i1> [[TMP4]], i64 1
526; CHECK-NEXT:    br i1 [[TMP10]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
527; CHECK:       pred.load.if1:
528; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP0]]
529; CHECK-NEXT:    [[TMP12:%.*]] = load i64, ptr [[TMP11]], align 4
530; CHECK-NEXT:    [[TMP13:%.*]] = insertelement <4 x i64> [[TMP9]], i64 [[TMP12]], i64 1
531; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
532; CHECK:       pred.load.continue2:
533; CHECK-NEXT:    [[TMP14:%.*]] = phi <4 x i64> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF1]] ]
534; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <4 x i1> [[TMP4]], i64 2
535; CHECK-NEXT:    br i1 [[TMP15]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
536; CHECK:       pred.load.if3:
537; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP1]]
538; CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr [[TMP16]], align 4
539; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x i64> [[TMP14]], i64 [[TMP17]], i64 2
540; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
541; CHECK:       pred.load.continue4:
542; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x i64> [ [[TMP14]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
543; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP4]], i64 3
544; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
545; CHECK:       pred.load.if5:
546; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
547; CHECK-NEXT:    [[TMP22:%.*]] = load i64, ptr [[TMP21]], align 4
548; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x i64> [[TMP19]], i64 [[TMP22]], i64 3
549; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
550; CHECK:       pred.load.continue6:
551; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x i64> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
552; CHECK-NEXT:    [[TMP25:%.*]] = icmp eq <4 x i64> [[TMP24]], splat (i64 3)
553; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP4]], <4 x i1> [[TMP25]], <4 x i1> zeroinitializer
554; CHECK-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP26]], i64 0
555; CHECK-NEXT:    br i1 [[TMP27]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]
556; CHECK:       pred.load.if7:
557; CHECK-NEXT:    [[TMP28:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[INDEX]]
558; CHECK-NEXT:    [[TMP29:%.*]] = load i64, ptr [[TMP28]], align 4
559; CHECK-NEXT:    [[TMP30:%.*]] = insertelement <4 x i64> poison, i64 [[TMP29]], i64 0
560; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE8]]
561; CHECK:       pred.load.continue8:
562; CHECK-NEXT:    [[TMP31:%.*]] = phi <4 x i64> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP30]], [[PRED_LOAD_IF7]] ]
563; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i1> [[TMP26]], i64 1
564; CHECK-NEXT:    br i1 [[TMP32]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]
565; CHECK:       pred.load.if9:
566; CHECK-NEXT:    [[TMP33:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
567; CHECK-NEXT:    [[TMP34:%.*]] = load i64, ptr [[TMP33]], align 4
568; CHECK-NEXT:    [[TMP35:%.*]] = insertelement <4 x i64> [[TMP31]], i64 [[TMP34]], i64 1
569; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE10]]
570; CHECK:       pred.load.continue10:
571; CHECK-NEXT:    [[TMP36:%.*]] = phi <4 x i64> [ [[TMP31]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP35]], [[PRED_LOAD_IF9]] ]
572; CHECK-NEXT:    [[TMP37:%.*]] = extractelement <4 x i1> [[TMP26]], i64 2
573; CHECK-NEXT:    br i1 [[TMP37]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]
574; CHECK:       pred.load.if11:
575; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
576; CHECK-NEXT:    [[TMP39:%.*]] = load i64, ptr [[TMP38]], align 4
577; CHECK-NEXT:    [[TMP40:%.*]] = insertelement <4 x i64> [[TMP36]], i64 [[TMP39]], i64 2
578; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE12]]
579; CHECK:       pred.load.continue12:
580; CHECK-NEXT:    [[TMP41:%.*]] = phi <4 x i64> [ [[TMP36]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP40]], [[PRED_LOAD_IF11]] ]
581; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <4 x i1> [[TMP26]], i64 3
582; CHECK-NEXT:    br i1 [[TMP42]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]
583; CHECK:       pred.load.if13:
584; CHECK-NEXT:    [[TMP43:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
585; CHECK-NEXT:    [[TMP44:%.*]] = load i64, ptr [[TMP43]], align 4
586; CHECK-NEXT:    [[TMP45:%.*]] = insertelement <4 x i64> [[TMP41]], i64 [[TMP44]], i64 3
587; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE14]]
588; CHECK:       pred.load.continue14:
589; CHECK-NEXT:    [[TMP46:%.*]] = phi <4 x i64> [ [[TMP41]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP45]], [[PRED_LOAD_IF13]] ]
590; CHECK-NEXT:    [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP26]], <4 x i64> [[TMP46]], <4 x i64> [[TMP24]]
591; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x i64> [[PREDPHI_V]], <4 x i64> splat (i64 -1)
592; CHECK-NEXT:    [[PREDPHI15]] = and <4 x i64> [[VEC_PHI]], [[PREDPHI]]
593; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
594; CHECK-NEXT:    [[TMP49:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
595; CHECK-NEXT:    br i1 [[TMP49]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
596; CHECK:       middle.block:
597; CHECK-NEXT:    [[TMP50:%.*]] = call i64 @llvm.vector.reduce.and.v4i64(<4 x i64> [[PREDPHI15]])
598; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
599; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
600; CHECK:       scalar.ph:
601; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
602; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i64 [ [[TMP50]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]
603; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
604; CHECK:       for.body:
605; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
606; CHECK-NEXT:    [[RDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
607; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[COND]], i64 [[IV]]
608; CHECK-NEXT:    [[TMP51:%.*]] = load i64, ptr [[ARRAYIDX]], align 4
609; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[TMP51]], 0
610; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
611; CHECK:       if.then:
612; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
613; CHECK-NEXT:    [[TMP52:%.*]] = load i64, ptr [[ARRAYIDX2]], align 4
614; CHECK-NEXT:    [[AND1:%.*]] = and i64 [[RDX]], [[TMP52]]
615; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp eq i64 [[TMP52]], 3
616; CHECK-NEXT:    br i1 [[TOBOOL2]], label [[IF_THEN_2:%.*]], label [[FOR_INC]]
617; CHECK:       if.then.2:
618; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
619; CHECK-NEXT:    [[TMP53:%.*]] = load i64, ptr [[ARRAYIDX3]], align 4
620; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[RDX]], [[TMP53]]
621; CHECK-NEXT:    br label [[FOR_INC]]
622; CHECK:       for.inc:
623; CHECK-NEXT:    [[RES]] = phi i64 [ [[AND2]], [[IF_THEN_2]] ], [ [[AND1]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
624; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
625; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
626; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
627; CHECK:       for.end:
628; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i64 [ [[RES]], [[FOR_INC]] ], [ [[TMP50]], [[MIDDLE_BLOCK]] ]
629; CHECK-NEXT:    ret i64 [[RES_LCSSA]]
630;
631entry:
632  br label %for.body
633
634for.body:
635  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
636  %rdx = phi i64 [ 5, %entry ], [ %res, %for.inc ]
637  %arrayidx = getelementptr inbounds i64, ptr %cond, i64 %iv
638  %0 = load i64, ptr %arrayidx
639  %tobool = icmp eq i64 %0, 0
640  br i1 %tobool, label %if.then, label %for.inc
641
642if.then:
643  %arrayidx2 = getelementptr inbounds i64, ptr %a, i64 %iv
644  %1 = load i64, ptr %arrayidx2
645  %and1 = and i64 %rdx, %1
646  %tobool2 = icmp eq i64 %1, 3
647  br i1 %tobool2, label %if.then.2, label %for.inc
648
649if.then.2:
650  %arrayidx3 = getelementptr inbounds i64, ptr %b, i64 %iv
651  %2 = load i64, ptr %arrayidx3
652  %and2 = and i64 %rdx, %2
653  br label %for.inc
654
655for.inc:
656  %res = phi i64 [ %and2, %if.then.2 ], [ %and1, %if.then ], [ %rdx, %for.body ]
657  %iv.next = add nuw nsw i64 %iv, 1
658  %exitcond.not = icmp eq i64 %iv.next, %N
659  br i1 %exitcond.not, label %for.end, label %for.body
660
661for.end:
662  ret i64 %res
663}
664
665; Chain of conditional & unconditional reductions. We currently only support conditional reductions
666; if they are the last in the chain, i.e. the loop exit instruction is a Phi node. Therefore we reject
667; the Phi (%rdx1) as it has more than one use.
668;
669define i32 @cond-uncond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 noundef %n) #0 {
670; CHECK-LABEL: define i32 @cond-uncond(
671; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {
672; CHECK-NEXT:  entry:
673; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
674; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
675; CHECK:       vector.ph:
676; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
677; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
678; CHECK:       vector.body:
679; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
680; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]
681; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
682; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
683; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer
684; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0
685; CHECK-NEXT:    br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
686; CHECK:       pred.load.if:
687; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]
688; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
689; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0
690; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
691; CHECK:       pred.load.continue:
692; CHECK-NEXT:    [[TMP6:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]
693; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1
694; CHECK-NEXT:    br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
695; CHECK:       pred.load.if1:
696; CHECK-NEXT:    [[TMP8:%.*]] = or disjoint i64 [[INDEX]], 1
697; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP8]]
698; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4
699; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i32> [[TMP6]], i32 [[TMP10]], i64 1
700; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
701; CHECK:       pred.load.continue2:
702; CHECK-NEXT:    [[TMP12:%.*]] = phi <4 x i32> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]
703; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2
704; CHECK-NEXT:    br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
705; CHECK:       pred.load.if3:
706; CHECK-NEXT:    [[TMP14:%.*]] = or disjoint i64 [[INDEX]], 2
707; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP14]]
708; CHECK-NEXT:    [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4
709; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x i32> [[TMP12]], i32 [[TMP16]], i64 2
710; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
711; CHECK:       pred.load.continue4:
712; CHECK-NEXT:    [[TMP18:%.*]] = phi <4 x i32> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]
713; CHECK-NEXT:    [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3
714; CHECK-NEXT:    br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
715; CHECK:       pred.load.if5:
716; CHECK-NEXT:    [[TMP20:%.*]] = or disjoint i64 [[INDEX]], 3
717; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP20]]
718; CHECK-NEXT:    [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4
719; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x i32> [[TMP18]], i32 [[TMP22]], i64 3
720; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
721; CHECK:       pred.load.continue6:
722; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x i32> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
723; CHECK-NEXT:    [[TMP25:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP24]], <4 x i32> zeroinitializer
724; CHECK-NEXT:    [[PREDPHI:%.*]] = add <4 x i32> [[VEC_PHI]], [[TMP25]]
725; CHECK-NEXT:    [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]
726; CHECK-NEXT:    [[WIDE_LOAD7:%.*]] = load <4 x i32>, ptr [[TMP26]], align 4
727; CHECK-NEXT:    [[TMP27]] = add <4 x i32> [[WIDE_LOAD7]], [[PREDPHI]]
728; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
729; CHECK-NEXT:    [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
730; CHECK-NEXT:    br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
731; CHECK:       middle.block:
732; CHECK-NEXT:    [[TMP29:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP27]])
733; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
734; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
735; CHECK:       scalar.ph:
736; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP29]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
737; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
738; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
739; CHECK:       for.body:
740; CHECK-NEXT:    [[RDX1:%.*]] = phi i32 [ [[ADD2:%.*]], [[IF_END:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
741; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[IF_END]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
742; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]
743; CHECK-NEXT:    [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
744; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP30]], 0
745; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
746; CHECK:       if.then:
747; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]
748; CHECK-NEXT:    [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
749; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP31]], [[RDX1]]
750; CHECK-NEXT:    br label [[IF_END]]
751; CHECK:       if.end:
752; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ [[RDX1]], [[FOR_BODY]] ]
753; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]
754; CHECK-NEXT:    [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
755; CHECK-NEXT:    [[ADD2]] = add nsw i32 [[TMP32]], [[RES]]
756; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
757; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
758; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
759; CHECK:       for.end:
760; CHECK-NEXT:    [[ADD2_LCSSA:%.*]] = phi i32 [ [[ADD2]], [[IF_END]] ], [ [[TMP29]], [[MIDDLE_BLOCK]] ]
761; CHECK-NEXT:    ret i32 [[ADD2_LCSSA]]
762;
763entry:
764  br label %for.body
765
766for.body:
767  %rdx1 = phi i32 [ %add2, %if.end ], [ 0, %entry ]
768  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry]
769  %arrayidx = getelementptr inbounds i32, ptr %cond, i64 %iv
770  %0 = load i32, ptr %arrayidx
771  %tobool.not = icmp eq i32 %0, 0
772  br i1 %tobool.not, label %if.end, label %if.then
773
774if.then:
775  %arrayidx1 = getelementptr inbounds i32, ptr %src2, i64 %iv
776  %1 = load i32, ptr %arrayidx1
777  %add = add nsw i32 %1, %rdx1
778  br label %if.end
779
780if.end:
781  %res = phi i32 [ %add, %if.then ], [ %rdx1, %for.body ]
782  %arrayidx2 = getelementptr inbounds i32, ptr %src1, i64 %iv
783  %2 = load i32, ptr %arrayidx2
784  %add2 = add nsw i32 %2, %res
785  %iv.next = add nuw nsw i64 %iv, 1
786  %exitcond.not = icmp eq i64 %iv.next, %n
787  br i1 %exitcond.not, label %for.end, label %for.body
788
789for.end:
790  ret i32 %add2
791}
792
793;
794; Chain of two conditional reductions. We do not vectorise this with in-loop reductions as neither
795; of the incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx1).
796;
797define float @cond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 %n) #0 {
798; CHECK-LABEL: define float @cond_cond(
799; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {
800; CHECK-NEXT:  entry:
801; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
802; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
803; CHECK:       vector.ph:
804; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
805; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
806; CHECK:       vector.body:
807; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]
808; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x float> [ <float 2.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, [[VECTOR_PH]] ], [ [[PREDPHI15:%.*]], [[PRED_LOAD_CONTINUE14]] ]
809; CHECK-NEXT:    [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1
810; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i64 [[INDEX]], 2
811; CHECK-NEXT:    [[TMP2:%.*]] = or disjoint i64 [[INDEX]], 3
812; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]
813; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP3]], align 4
814; CHECK-NEXT:    [[TMP4:%.*]] = fcmp fast oeq <4 x float> [[WIDE_LOAD]], splat (float 3.000000e+00)
815; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x i1> [[TMP4]], i64 0
816; CHECK-NEXT:    br i1 [[TMP5]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
817; CHECK:       pred.load.if:
818; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[INDEX]]
819; CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr [[TMP6]], align 4
820; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <4 x float> poison, float [[TMP7]], i64 0
821; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
822; CHECK:       pred.load.continue:
823; CHECK-NEXT:    [[TMP9:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]
824; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <4 x i1> [[TMP4]], i64 1
825; CHECK-NEXT:    br i1 [[TMP10]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
826; CHECK:       pred.load.if1:
827; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP0]]
828; CHECK-NEXT:    [[TMP12:%.*]] = load float, ptr [[TMP11]], align 4
829; CHECK-NEXT:    [[TMP13:%.*]] = insertelement <4 x float> [[TMP9]], float [[TMP12]], i64 1
830; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
831; CHECK:       pred.load.continue2:
832; CHECK-NEXT:    [[TMP14:%.*]] = phi <4 x float> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF1]] ]
833; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <4 x i1> [[TMP4]], i64 2
834; CHECK-NEXT:    br i1 [[TMP15]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
835; CHECK:       pred.load.if3:
836; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP1]]
837; CHECK-NEXT:    [[TMP17:%.*]] = load float, ptr [[TMP16]], align 4
838; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float> [[TMP14]], float [[TMP17]], i64 2
839; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
840; CHECK:       pred.load.continue4:
841; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x float> [ [[TMP14]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
842; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP4]], i64 3
843; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
844; CHECK:       pred.load.if5:
845; CHECK-NEXT:    [[TMP21:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP2]]
846; CHECK-NEXT:    [[TMP22:%.*]] = load float, ptr [[TMP21]], align 4
847; CHECK-NEXT:    [[TMP23:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP22]], i64 3
848; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
849; CHECK:       pred.load.continue6:
850; CHECK-NEXT:    [[TMP24:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]
851; CHECK-NEXT:    [[TMP25:%.*]] = fadd fast <4 x float> [[TMP24]], [[VEC_PHI]]
852; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x float> [[TMP25]], <4 x float> [[VEC_PHI]]
853; CHECK-NEXT:    [[TMP26:%.*]] = fcmp fast oeq <4 x float> [[WIDE_LOAD]], splat (float 7.000000e+00)
854; CHECK-NEXT:    [[TMP27:%.*]] = extractelement <4 x i1> [[TMP26]], i64 0
855; CHECK-NEXT:    br i1 [[TMP27]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]
856; CHECK:       pred.load.if7:
857; CHECK-NEXT:    [[TMP28:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[INDEX]]
858; CHECK-NEXT:    [[TMP29:%.*]] = load float, ptr [[TMP28]], align 4
859; CHECK-NEXT:    [[TMP30:%.*]] = insertelement <4 x float> poison, float [[TMP29]], i64 0
860; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE8]]
861; CHECK:       pred.load.continue8:
862; CHECK-NEXT:    [[TMP31:%.*]] = phi <4 x float> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP30]], [[PRED_LOAD_IF7]] ]
863; CHECK-NEXT:    [[TMP32:%.*]] = extractelement <4 x i1> [[TMP26]], i64 1
864; CHECK-NEXT:    br i1 [[TMP32]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]
865; CHECK:       pred.load.if9:
866; CHECK-NEXT:    [[TMP33:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP0]]
867; CHECK-NEXT:    [[TMP34:%.*]] = load float, ptr [[TMP33]], align 4
868; CHECK-NEXT:    [[TMP35:%.*]] = insertelement <4 x float> [[TMP31]], float [[TMP34]], i64 1
869; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE10]]
870; CHECK:       pred.load.continue10:
871; CHECK-NEXT:    [[TMP36:%.*]] = phi <4 x float> [ [[TMP31]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP35]], [[PRED_LOAD_IF9]] ]
872; CHECK-NEXT:    [[TMP37:%.*]] = extractelement <4 x i1> [[TMP26]], i64 2
873; CHECK-NEXT:    br i1 [[TMP37]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]
874; CHECK:       pred.load.if11:
875; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP1]]
876; CHECK-NEXT:    [[TMP39:%.*]] = load float, ptr [[TMP38]], align 4
877; CHECK-NEXT:    [[TMP40:%.*]] = insertelement <4 x float> [[TMP36]], float [[TMP39]], i64 2
878; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE12]]
879; CHECK:       pred.load.continue12:
880; CHECK-NEXT:    [[TMP41:%.*]] = phi <4 x float> [ [[TMP36]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP40]], [[PRED_LOAD_IF11]] ]
881; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <4 x i1> [[TMP26]], i64 3
882; CHECK-NEXT:    br i1 [[TMP42]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]
883; CHECK:       pred.load.if13:
884; CHECK-NEXT:    [[TMP43:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP2]]
885; CHECK-NEXT:    [[TMP44:%.*]] = load float, ptr [[TMP43]], align 4
886; CHECK-NEXT:    [[TMP45:%.*]] = insertelement <4 x float> [[TMP41]], float [[TMP44]], i64 3
887; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE14]]
888; CHECK:       pred.load.continue14:
889; CHECK-NEXT:    [[TMP46:%.*]] = phi <4 x float> [ [[TMP41]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP45]], [[PRED_LOAD_IF13]] ]
890; CHECK-NEXT:    [[TMP47:%.*]] = fadd fast <4 x float> [[TMP46]], [[PREDPHI]]
891; CHECK-NEXT:    [[PREDPHI15]] = select <4 x i1> [[TMP26]], <4 x float> [[TMP47]], <4 x float> [[PREDPHI]]
892; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
893; CHECK-NEXT:    [[TMP48:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
894; CHECK-NEXT:    br i1 [[TMP48]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
895; CHECK:       middle.block:
896; CHECK-NEXT:    [[TMP49:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[PREDPHI15]])
897; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
898; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
899; CHECK:       scalar.ph:
900; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP49]], [[MIDDLE_BLOCK]] ], [ 2.000000e+00, [[ENTRY:%.*]] ]
901; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
902; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
903; CHECK:       for.body:
904; CHECK-NEXT:    [[RDX1:%.*]] = phi float [ [[RES:%.*]], [[FOR_INC:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
905; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
906; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]
907; CHECK-NEXT:    [[TMP50:%.*]] = load float, ptr [[ARRAYIDX]], align 4
908; CHECK-NEXT:    [[CMP1:%.*]] = fcmp fast oeq float [[TMP50]], 3.000000e+00
909; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
910; CHECK:       if.then:
911; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[IV]]
912; CHECK-NEXT:    [[TMP51:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
913; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[TMP51]], [[RDX1]]
914; CHECK-NEXT:    br label [[IF_END]]
915; CHECK:       if.end:
916; CHECK-NEXT:    [[RDX2:%.*]] = phi float [ [[ADD]], [[IF_THEN]] ], [ [[RDX1]], [[FOR_BODY]] ]
917; CHECK-NEXT:    [[CMP5:%.*]] = fcmp fast oeq float [[TMP50]], 7.000000e+00
918; CHECK-NEXT:    br i1 [[CMP5]], label [[IF_THEN6:%.*]], label [[FOR_INC]]
919; CHECK:       if.then6:
920; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[IV]]
921; CHECK-NEXT:    [[TMP52:%.*]] = load float, ptr [[ARRAYIDX7]], align 4
922; CHECK-NEXT:    [[ADD2:%.*]] = fadd fast float [[TMP52]], [[RDX2]]
923; CHECK-NEXT:    br label [[FOR_INC]]
924; CHECK:       for.inc:
925; CHECK-NEXT:    [[RES]] = phi float [ [[ADD2]], [[IF_THEN6]] ], [ [[RDX2]], [[IF_END]] ]
926; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
927; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
928; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP15:![0-9]+]]
929; CHECK:       for.end:
930; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP49]], [[MIDDLE_BLOCK]] ]
931; CHECK-NEXT:    ret float [[RES_LCSSA]]
932;
933entry:
934  br label %for.body
935
936for.body:
937  %rdx1 = phi float [ %res, %for.inc ], [ 2.000000e+00, %entry ]
938  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
939  %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv
940  %0 = load float, ptr %arrayidx
941  %cmp1 = fcmp fast oeq float %0, 3.000000e+00
942  br i1 %cmp1, label %if.then, label %if.end
943
944if.then:
945  %arrayidx2 = getelementptr inbounds float, ptr %src1, i64 %iv
946  %1 = load float, ptr %arrayidx2
947  %add = fadd fast float %1, %rdx1
948  br label %if.end
949
950if.end:
951  %rdx2 = phi float [ %add, %if.then ], [ %rdx1, %for.body ]
952  %cmp5 = fcmp fast oeq float %0, 7.000000e+00
953  br i1 %cmp5, label %if.then6, label %for.inc
954
955if.then6:
956  %arrayidx7 = getelementptr inbounds float, ptr %src2, i64 %iv
957  %2 = load float, ptr %arrayidx7
958  %add2 = fadd fast float %2, %rdx2
959  br label %for.inc
960
961for.inc:
962  %res = phi float [ %add2, %if.then6 ], [ %rdx2, %if.end ]
963  %iv.next = add nuw nsw i64 %iv, 1
964  %exitcond.not = icmp eq i64 %iv.next, %n
965  br i1 %exitcond.not, label %for.end, label %for.body
966
967for.end:
968  ret float %res
969}
970
971;
972; Chain of an unconditional & a conditional reduction. We do not vectorise this in-loop as neither of the
973; incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx).
974;
975define i32 @uncond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 %N) #0 {
976; CHECK-LABEL: define i32 @uncond_cond(
977; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {
978; CHECK-NEXT:  entry:
979; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
980; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
981; CHECK:       vector.ph:
982; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
983; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
984; CHECK:       vector.body:
985; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE7:%.*]] ]
986; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[PRED_LOAD_CONTINUE7]] ]
987; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]
988; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
989; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[WIDE_LOAD]], [[VEC_PHI]]
990; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
991; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4
992; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD1]], zeroinitializer
993; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <4 x i1> [[TMP3]], i64 0
994; CHECK-NEXT:    br i1 [[TMP4]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
995; CHECK:       pred.load.if:
996; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]
997; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4
998; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <4 x i32> poison, i32 [[TMP6]], i64 0
999; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
1000; CHECK:       pred.load.continue:
1001; CHECK-NEXT:    [[TMP8:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP7]], [[PRED_LOAD_IF]] ]
1002; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP3]], i64 1
1003; CHECK-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF2:%.*]], label [[PRED_LOAD_CONTINUE3:%.*]]
1004; CHECK:       pred.load.if2:
1005; CHECK-NEXT:    [[TMP10:%.*]] = or disjoint i64 [[INDEX]], 1
1006; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP10]]
1007; CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4
1008; CHECK-NEXT:    [[TMP13:%.*]] = insertelement <4 x i32> [[TMP8]], i32 [[TMP12]], i64 1
1009; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE3]]
1010; CHECK:       pred.load.continue3:
1011; CHECK-NEXT:    [[TMP14:%.*]] = phi <4 x i32> [ [[TMP8]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF2]] ]
1012; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <4 x i1> [[TMP3]], i64 2
1013; CHECK-NEXT:    br i1 [[TMP15]], label [[PRED_LOAD_IF4:%.*]], label [[PRED_LOAD_CONTINUE5:%.*]]
1014; CHECK:       pred.load.if4:
1015; CHECK-NEXT:    [[TMP16:%.*]] = or disjoint i64 [[INDEX]], 2
1016; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP16]]
1017; CHECK-NEXT:    [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4
1018; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i32> [[TMP14]], i32 [[TMP18]], i64 2
1019; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE5]]
1020; CHECK:       pred.load.continue5:
1021; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i32> [ [[TMP14]], [[PRED_LOAD_CONTINUE3]] ], [ [[TMP19]], [[PRED_LOAD_IF4]] ]
1022; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP3]], i64 3
1023; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF6:%.*]], label [[PRED_LOAD_CONTINUE7]]
1024; CHECK:       pred.load.if6:
1025; CHECK-NEXT:    [[TMP22:%.*]] = or disjoint i64 [[INDEX]], 3
1026; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP22]]
1027; CHECK-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1028; CHECK-NEXT:    [[TMP25:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP24]], i64 3
1029; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE7]]
1030; CHECK:       pred.load.continue7:
1031; CHECK-NEXT:    [[TMP26:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE5]] ], [ [[TMP25]], [[PRED_LOAD_IF6]] ]
1032; CHECK-NEXT:    [[TMP27:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP26]], <4 x i32> zeroinitializer
1033; CHECK-NEXT:    [[PREDPHI]] = add <4 x i32> [[TMP1]], [[TMP27]]
1034; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
1035; CHECK-NEXT:    [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
1036; CHECK-NEXT:    br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
1037; CHECK:       middle.block:
1038; CHECK-NEXT:    [[TMP29:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[PREDPHI]])
1039; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
1040; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
1041; CHECK:       scalar.ph:
1042; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP29]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1043; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
1044; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1045; CHECK:       for.body:
1046; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
1047; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
1048; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]
1049; CHECK-NEXT:    [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
1050; CHECK-NEXT:    [[ADD1:%.*]] = add nsw i32 [[TMP30]], [[RDX]]
1051; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]
1052; CHECK-NEXT:    [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
1053; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP31]], 0
1054; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]
1055; CHECK:       if.then:
1056; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]
1057; CHECK-NEXT:    [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
1058; CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP32]], [[ADD1]]
1059; CHECK-NEXT:    br label [[FOR_INC]]
1060; CHECK:       for.inc:
1061; CHECK-NEXT:    [[RES]] = phi i32 [ [[ADD2]], [[IF_THEN]] ], [ [[ADD1]], [[FOR_BODY]] ]
1062; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1063; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
1064; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]
1065; CHECK:       for.end:
1066; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP29]], [[MIDDLE_BLOCK]] ]
1067; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
1068;
1069entry:
1070  br label %for.body
1071
1072for.body:
1073  %rdx = phi i32 [ %res, %for.inc ], [ 0, %entry ]
1074  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
1075  %arrayidx = getelementptr inbounds i32, ptr %src1, i64 %iv
1076  %0 = load i32, ptr %arrayidx
1077  %add1 = add nsw i32 %0, %rdx
1078  %arrayidx1 = getelementptr inbounds i32, ptr %cond, i64 %iv
1079  %1 = load i32, ptr %arrayidx1
1080  %tobool.not = icmp eq i32 %1, 0
1081  br i1 %tobool.not, label %for.inc, label %if.then
1082
1083if.then:
1084  %arrayidx2 = getelementptr inbounds i32, ptr %src2, i64 %iv
1085  %2 = load i32, ptr %arrayidx2
1086  %add2 = add nsw i32 %2, %add1
1087  br label %for.inc
1088
1089for.inc:
1090  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
1091  %iv.next = add nuw nsw i64 %iv, 1
1092  %exitcond.not = icmp eq i64 %iv.next, %N
1093  br i1 %exitcond.not, label %for.end, label %for.body
1094
1095for.end:
1096  ret i32 %res
1097}
1098
1099;
1100; Chain of multiple unconditional & conditional reductions. Does not vectorise in-loop as when we look back
1101; through the chain and check the number of uses of %add1, we find more than the expected one use.
1102;
1103define i32 @uncond_cond_uncond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 noundef %N) {
1104; CHECK-LABEL: define i32 @uncond_cond_uncond(
1105; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {
1106; CHECK-NEXT:  entry:
1107; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
1108; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1109; CHECK:       vector.ph:
1110; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
1111; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1112; CHECK:       vector.body:
1113; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE7:%.*]] ]
1114; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE7]] ]
1115; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]
1116; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
1117; CHECK-NEXT:    [[TMP1:%.*]] = add <4 x i32> [[WIDE_LOAD]], [[VEC_PHI]]
1118; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]
1119; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4
1120; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD1]], zeroinitializer
1121; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <4 x i1> [[TMP3]], i64 0
1122; CHECK-NEXT:    br i1 [[TMP4]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
1123; CHECK:       pred.load.if:
1124; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]
1125; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4
1126; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <4 x i32> poison, i32 [[TMP6]], i64 0
1127; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
1128; CHECK:       pred.load.continue:
1129; CHECK-NEXT:    [[TMP8:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP7]], [[PRED_LOAD_IF]] ]
1130; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x i1> [[TMP3]], i64 1
1131; CHECK-NEXT:    br i1 [[TMP9]], label [[PRED_LOAD_IF2:%.*]], label [[PRED_LOAD_CONTINUE3:%.*]]
1132; CHECK:       pred.load.if2:
1133; CHECK-NEXT:    [[TMP10:%.*]] = or disjoint i64 [[INDEX]], 1
1134; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP10]]
1135; CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4
1136; CHECK-NEXT:    [[TMP13:%.*]] = insertelement <4 x i32> [[TMP8]], i32 [[TMP12]], i64 1
1137; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE3]]
1138; CHECK:       pred.load.continue3:
1139; CHECK-NEXT:    [[TMP14:%.*]] = phi <4 x i32> [ [[TMP8]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF2]] ]
1140; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <4 x i1> [[TMP3]], i64 2
1141; CHECK-NEXT:    br i1 [[TMP15]], label [[PRED_LOAD_IF4:%.*]], label [[PRED_LOAD_CONTINUE5:%.*]]
1142; CHECK:       pred.load.if4:
1143; CHECK-NEXT:    [[TMP16:%.*]] = or disjoint i64 [[INDEX]], 2
1144; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP16]]
1145; CHECK-NEXT:    [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4
1146; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i32> [[TMP14]], i32 [[TMP18]], i64 2
1147; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE5]]
1148; CHECK:       pred.load.continue5:
1149; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i32> [ [[TMP14]], [[PRED_LOAD_CONTINUE3]] ], [ [[TMP19]], [[PRED_LOAD_IF4]] ]
1150; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP3]], i64 3
1151; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF6:%.*]], label [[PRED_LOAD_CONTINUE7]]
1152; CHECK:       pred.load.if6:
1153; CHECK-NEXT:    [[TMP22:%.*]] = or disjoint i64 [[INDEX]], 3
1154; CHECK-NEXT:    [[TMP23:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[TMP22]]
1155; CHECK-NEXT:    [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1156; CHECK-NEXT:    [[TMP25:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP24]], i64 3
1157; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE7]]
1158; CHECK:       pred.load.continue7:
1159; CHECK-NEXT:    [[TMP26:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE5]] ], [ [[TMP25]], [[PRED_LOAD_IF6]] ]
1160; CHECK-NEXT:    [[TMP27:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP26]], <4 x i32> zeroinitializer
1161; CHECK-NEXT:    [[PREDPHI:%.*]] = add <4 x i32> [[TMP1]], [[TMP27]]
1162; CHECK-NEXT:    [[TMP28]] = add <4 x i32> [[PREDPHI]], [[WIDE_LOAD]]
1163; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
1164; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
1165; CHECK-NEXT:    br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
1166; CHECK:       middle.block:
1167; CHECK-NEXT:    [[TMP30:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP28]])
1168; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
1169; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
1170; CHECK:       scalar.ph:
1171; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP30]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1172; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
1173; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1174; CHECK:       for.body:
1175; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[ADD3:%.*]], [[IF_END:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
1176; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[IF_END]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
1177; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]
1178; CHECK-NEXT:    [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
1179; CHECK-NEXT:    [[ADD1:%.*]] = add nsw i32 [[TMP31]], [[RDX]]
1180; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]
1181; CHECK-NEXT:    [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
1182; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP32]], 0
1183; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]
1184; CHECK:       if.then:
1185; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]
1186; CHECK-NEXT:    [[TMP33:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
1187; CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP33]], [[ADD1]]
1188; CHECK-NEXT:    br label [[IF_END]]
1189; CHECK:       if.end:
1190; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[ADD2]], [[IF_THEN]] ], [ [[ADD1]], [[FOR_BODY]] ]
1191; CHECK-NEXT:    [[ADD3]] = add nsw i32 [[RES]], [[TMP31]]
1192; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1193; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
1194; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
1195; CHECK:       for.end:
1196; CHECK-NEXT:    [[ADD3_LCSSA:%.*]] = phi i32 [ [[ADD3]], [[IF_END]] ], [ [[TMP30]], [[MIDDLE_BLOCK]] ]
1197; CHECK-NEXT:    ret i32 [[ADD3_LCSSA]]
1198;
1199entry:
1200  br label %for.body
1201
1202for.body:
1203  %rdx = phi i32 [ %add3, %if.end ], [ 0, %entry ]
1204  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry ]
1205  %arrayidx = getelementptr inbounds i32, ptr %src1, i64 %iv
1206  %0 = load i32, ptr %arrayidx
1207  %add1 = add nsw i32 %0, %rdx
1208  %arrayidx1 = getelementptr inbounds i32, ptr %cond, i64 %iv
1209  %1 = load i32, ptr %arrayidx1
1210  %tobool.not = icmp eq i32 %1, 0
1211  br i1 %tobool.not, label %if.end, label %if.then
1212
1213if.then:
1214  %arrayidx2 = getelementptr inbounds i32, ptr %src2, i64 %iv
1215  %2 = load i32, ptr %arrayidx2
1216  %add2 = add nsw i32 %2, %add1
1217  br label %if.end
1218
1219if.end:
1220  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
1221  %add3 = add nsw i32 %res, %0
1222  %iv.next = add nuw nsw i64 %iv, 1
1223  %exitcond.not = icmp eq i64 %iv.next, %N
1224  br i1 %exitcond.not, label %for.end, label %for.body
1225
1226for.end:
1227  ret i32 %add3
1228}
1229