1*12fb133eSKerry McLaughlin; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -prefer-inloop-reductions -dce -instcombine -S | FileCheck %s
2*12fb133eSKerry McLaughlin
3*12fb133eSKerry McLaughlindefine float @cond_fadd(float* noalias nocapture readonly %a, float* noalias nocapture readonly %cond, i64 %N){
4*12fb133eSKerry McLaughlin; CHECK-LABEL: @cond_fadd(
5*12fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
6*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
7*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
8*12fb133eSKerry McLaughlin; CHECK:       vector.ph:
9*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
10*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
11*12fb133eSKerry McLaughlin; CHECK:       vector.body:
12*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
13*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]
14*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[COND:%.*]], i64 [[INDEX]]
15*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
16*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 4
17*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], <float 5.000000e+00, float 5.000000e+00, float 5.000000e+00, float 5.000000e+00>
18*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
19*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
20*12fb133eSKerry McLaughlin; CHECK:       pred.load.if:
21*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[INDEX]]
22*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load float, float* [[TMP4]], align 4
23*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x float> poison, float [[TMP5]], i64 0
24*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
25*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
26*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
27*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
28*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
29*12fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
30*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
31*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]]
32*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load float, float* [[TMP10]], align 4
33*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x float> [[TMP7]], float [[TMP11]], i64 1
34*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
35*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
36*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x float> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
37*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
38*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
39*12fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
40*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
41*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]]
42*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load float, float* [[TMP16]], align 4
43*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float> [[TMP13]], float [[TMP17]], i64 2
44*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
45*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
46*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x float> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
47*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
48*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
49*12fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
50*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
51*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP21]]
52*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load float, float* [[TMP22]], align 4
53*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP23]], i64 3
54*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
55*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
56*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
57*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select fast <4 x i1> [[TMP2]], <4 x float> [[TMP25]], <4 x float> zeroinitializer
58*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[VEC_PHI]], <4 x float> [[TMP26]])
59*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
60*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
61*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
62*12fb133eSKerry McLaughlin; CHECK:       middle.block:
63*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
64*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
65*12fb133eSKerry McLaughlin; CHECK:       scalar.ph:
66*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
67*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP27]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
68*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
69*12fb133eSKerry McLaughlin; CHECK:       for.body:
70*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
71*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
72*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[COND]], i64 [[IV]]
73*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = load float, float* [[ARRAYIDX]], align 4
74*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP29]], 5.000000e+00
75*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
76*12fb133eSKerry McLaughlin; CHECK:       if.then:
77*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[IV]]
78*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load float, float* [[ARRAYIDX2]], align 4
79*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[FADD:%.*]] = fadd fast float [[RDX]], [[TMP30]]
80*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
81*12fb133eSKerry McLaughlin; CHECK:       for.inc:
82*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FADD]], [[IF_THEN]] ]
83*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
84*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
85*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
86*12fb133eSKerry McLaughlin; CHECK:       for.end:
87*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP27]], [[MIDDLE_BLOCK]] ]
88*12fb133eSKerry McLaughlin; CHECK-NEXT:    ret float [[RES_LCSSA]]
89*12fb133eSKerry McLaughlin;
90*12fb133eSKerry McLaughlinentry:
91*12fb133eSKerry McLaughlin  br label %for.body
92*12fb133eSKerry McLaughlin
93*12fb133eSKerry McLaughlinfor.body:
94*12fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
95*12fb133eSKerry McLaughlin  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
96*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
97*12fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
98*12fb133eSKerry McLaughlin  %tobool = fcmp une float %0, 5.000000e+00
99*12fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
100*12fb133eSKerry McLaughlin
101*12fb133eSKerry McLaughlinif.then:
102*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
103*12fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
104*12fb133eSKerry McLaughlin  %fadd = fadd fast float %rdx, %1
105*12fb133eSKerry McLaughlin  br label %for.inc
106*12fb133eSKerry McLaughlin
107*12fb133eSKerry McLaughlinfor.inc:
108*12fb133eSKerry McLaughlin  %res = phi float [ %rdx, %for.body ], [ %fadd, %if.then ]
109*12fb133eSKerry McLaughlin  %iv.next = add i64 %iv, 1
110*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
111*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
112*12fb133eSKerry McLaughlin
113*12fb133eSKerry McLaughlinfor.end:
114*12fb133eSKerry McLaughlin  ret float %res
115*12fb133eSKerry McLaughlin}
116*12fb133eSKerry McLaughlin
117*12fb133eSKerry McLaughlindefine float @cond_cmp_sel(float* noalias %a, float* noalias %cond, i64 %N) {
118*12fb133eSKerry McLaughlin; CHECK-LABEL: @cond_cmp_sel(
119*12fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
120*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
121*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
122*12fb133eSKerry McLaughlin; CHECK:       vector.ph:
123*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
124*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
125*12fb133eSKerry McLaughlin; CHECK:       vector.body:
126*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
127*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE6]] ]
128*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[COND:%.*]], i64 [[INDEX]]
129*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
130*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 4
131*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00>
132*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
133*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
134*12fb133eSKerry McLaughlin; CHECK:       pred.load.if:
135*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[INDEX]]
136*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load float, float* [[TMP4]], align 4
137*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x float> poison, float [[TMP5]], i64 0
138*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
139*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
140*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
141*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
142*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
143*12fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
144*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
145*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]]
146*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load float, float* [[TMP10]], align 4
147*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x float> [[TMP7]], float [[TMP11]], i64 1
148*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
149*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
150*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x float> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
151*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
152*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
153*12fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
154*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
155*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]]
156*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load float, float* [[TMP16]], align 4
157*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float> [[TMP13]], float [[TMP17]], i64 2
158*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
159*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
160*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x float> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
161*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
162*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
163*12fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
164*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
165*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP21]]
166*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load float, float* [[TMP22]], align 4
167*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP23]], i64 3
168*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
169*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
170*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
171*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select fast <4 x i1> [[TMP2]], <4 x float> [[TMP25]], <4 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000, float 0xFFF0000000000000>
172*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[TMP26]])
173*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28]] = call fast float @llvm.minnum.f32(float [[TMP27]], float [[VEC_PHI]])
174*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
175*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
176*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
177*12fb133eSKerry McLaughlin; CHECK:       middle.block:
178*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
179*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
180*12fb133eSKerry McLaughlin; CHECK:       scalar.ph:
181*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
182*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP28]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
183*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
184*12fb133eSKerry McLaughlin; CHECK:       for.body:
185*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
186*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
187*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[COND]], i64 [[IV]]
188*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load float, float* [[ARRAYIDX]], align 4
189*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP30]], 3.000000e+00
190*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
191*12fb133eSKerry McLaughlin; CHECK:       if.then:
192*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[IV]]
193*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load float, float* [[ARRAYIDX2]], align 4
194*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP32:%.*]] = call fast float @llvm.minnum.f32(float [[RDX]], float [[TMP31]])
195*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
196*12fb133eSKerry McLaughlin; CHECK:       for.inc:
197*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[TMP32]], [[IF_THEN]] ]
198*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
199*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
200*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
201*12fb133eSKerry McLaughlin; CHECK:       for.end:
202*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP28]], [[MIDDLE_BLOCK]] ]
203*12fb133eSKerry McLaughlin; CHECK-NEXT:    ret float [[RES_LCSSA]]
204*12fb133eSKerry McLaughlin;
205*12fb133eSKerry McLaughlinentry:
206*12fb133eSKerry McLaughlin  br label %for.body
207*12fb133eSKerry McLaughlin
208*12fb133eSKerry McLaughlinfor.body:
209*12fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
210*12fb133eSKerry McLaughlin  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
211*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
212*12fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
213*12fb133eSKerry McLaughlin  %tobool = fcmp une float %0, 3.000000e+00
214*12fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
215*12fb133eSKerry McLaughlin
216*12fb133eSKerry McLaughlinif.then:
217*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
218*12fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
219*12fb133eSKerry McLaughlin  %fcmp = fcmp fast olt float %rdx, %1
220*12fb133eSKerry McLaughlin  %fsel = select fast i1 %fcmp, float %rdx, float %1
221*12fb133eSKerry McLaughlin  br label %for.inc
222*12fb133eSKerry McLaughlin
223*12fb133eSKerry McLaughlinfor.inc:
224*12fb133eSKerry McLaughlin  %res = phi float [ %rdx, %for.body ], [ %fsel, %if.then ]
225*12fb133eSKerry McLaughlin  %iv.next = add i64 %iv, 1
226*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
227*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
228*12fb133eSKerry McLaughlin
229*12fb133eSKerry McLaughlinfor.end:
230*12fb133eSKerry McLaughlin  ret float %res
231*12fb133eSKerry McLaughlin}
232*12fb133eSKerry McLaughlin
233*12fb133eSKerry McLaughlindefine i32 @conditional_and(i32* noalias %A, i32* noalias %B, i32 %cond, i64 noundef %N) #0 {
234*12fb133eSKerry McLaughlin; CHECK-LABEL: @conditional_and(
235*12fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
236*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
237*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
238*12fb133eSKerry McLaughlin; CHECK:       vector.ph:
239*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
240*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[COND:%.*]], i64 0
241*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
242*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
243*12fb133eSKerry McLaughlin; CHECK:       vector.body:
244*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
245*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 7, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE6]] ]
246*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDEX]]
247*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
248*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
249*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
250*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
251*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
252*12fb133eSKerry McLaughlin; CHECK:       pred.load.if:
253*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDEX]]
254*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
255*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x i32> poison, i32 [[TMP5]], i64 0
256*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
257*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
258*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
259*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
260*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
261*12fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
262*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
263*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP9]]
264*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load i32, i32* [[TMP10]], align 4
265*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x i32> [[TMP7]], i32 [[TMP11]], i64 1
266*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
267*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
268*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x i32> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
269*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
270*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
271*12fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
272*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
273*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP15]]
274*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 4
275*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x i32> [[TMP13]], i32 [[TMP17]], i64 2
276*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
277*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
278*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x i32> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
279*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
280*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
281*12fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
282*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
283*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP21]]
284*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4
285*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i32> [[TMP19]], i32 [[TMP23]], i64 3
286*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
287*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
288*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i32> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
289*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP25]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
290*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> [[TMP26]])
291*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28]] = and i32 [[TMP27]], [[VEC_PHI]]
292*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
293*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
294*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
295*12fb133eSKerry McLaughlin; CHECK:       middle.block:
296*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
297*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
298*12fb133eSKerry McLaughlin; CHECK:       scalar.ph:
299*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
300*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP28]], [[MIDDLE_BLOCK]] ], [ 7, [[ENTRY]] ]
301*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
302*12fb133eSKerry McLaughlin; CHECK:       for.body:
303*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
304*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
305*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[IV]]
306*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
307*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP30]], [[COND]]
308*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
309*12fb133eSKerry McLaughlin; CHECK:       if.then:
310*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[IV]]
311*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
312*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[AND:%.*]] = and i32 [[TMP31]], [[RDX]]
313*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
314*12fb133eSKerry McLaughlin; CHECK:       for.inc:
315*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi i32 [ [[AND]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
316*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
317*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
318*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
319*12fb133eSKerry McLaughlin; CHECK:       for.end:
320*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP28]], [[MIDDLE_BLOCK]] ]
321*12fb133eSKerry McLaughlin; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
322*12fb133eSKerry McLaughlin;
323*12fb133eSKerry McLaughlinentry:
324*12fb133eSKerry McLaughlin  br label %for.body
325*12fb133eSKerry McLaughlin
326*12fb133eSKerry McLaughlinfor.body:
327*12fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
328*12fb133eSKerry McLaughlin  %rdx = phi i32 [ 7, %entry ], [ %res, %for.inc ]
329*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %iv
330*12fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
331*12fb133eSKerry McLaughlin  %tobool = icmp eq i32 %0, %cond
332*12fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
333*12fb133eSKerry McLaughlin
334*12fb133eSKerry McLaughlinif.then:
335*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %iv
336*12fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx2
337*12fb133eSKerry McLaughlin  %and = and i32 %1, %rdx
338*12fb133eSKerry McLaughlin  br label %for.inc
339*12fb133eSKerry McLaughlin
340*12fb133eSKerry McLaughlinfor.inc:
341*12fb133eSKerry McLaughlin  %res = phi i32 [ %and, %if.then ], [ %rdx, %for.body ]
342*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
343*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
344*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
345*12fb133eSKerry McLaughlin
346*12fb133eSKerry McLaughlinfor.end:
347*12fb133eSKerry McLaughlin  ret i32 %res
348*12fb133eSKerry McLaughlin}
349*12fb133eSKerry McLaughlin
350*12fb133eSKerry McLaughlindefine i32 @simple_chained_rdx(i32* noalias %a, i32* noalias %b, i32* noalias %cond, i64 noundef %N) {
351*12fb133eSKerry McLaughlin; CHECK-LABEL: @simple_chained_rdx(
352*12fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
353*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
354*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
355*12fb133eSKerry McLaughlin; CHECK:       vector.ph:
356*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
357*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
358*12fb133eSKerry McLaughlin; CHECK:       vector.body:
359*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]
360*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 5, [[VECTOR_PH]] ], [ [[TMP51:%.*]], [[PRED_LOAD_CONTINUE14]] ]
361*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = or i64 [[INDEX]], 1
362*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[INDEX]], 2
363*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[INDEX]], 3
364*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, i32* [[COND:%.*]], i64 [[INDEX]]
365*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP3]] to <4 x i32>*
366*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP4]], align 4
367*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer
368*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0
369*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP6]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
370*12fb133eSKerry McLaughlin; CHECK:       pred.load.if:
371*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDEX]]
372*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
373*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <4 x i32> poison, i32 [[TMP8]], i64 0
374*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
375*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
376*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP9]], [[PRED_LOAD_IF]] ]
377*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1
378*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP11]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
379*12fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
380*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP0]]
381*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
382*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <4 x i32> [[TMP10]], i32 [[TMP13]], i64 1
383*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
384*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
385*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = phi <4 x i32> [ [[TMP10]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], [[PRED_LOAD_IF1]] ]
386*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2
387*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP16]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
388*12fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
389*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP1]]
390*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 4
391*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i32> [[TMP15]], i32 [[TMP18]], i64 2
392*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
393*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
394*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i32> [ [[TMP15]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
395*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3
396*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
397*12fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
398*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP2]]
399*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4
400*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP23]], i64 3
401*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
402*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
403*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
404*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP25]], <4 x i32> zeroinitializer
405*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP26]])
406*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28:%.*]] = add i32 [[TMP27]], [[VEC_PHI]]
407*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0
408*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]
409*12fb133eSKerry McLaughlin; CHECK:       pred.load.if7:
410*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDEX]]
411*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4
412*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP32:%.*]] = insertelement <4 x i32> poison, i32 [[TMP31]], i64 0
413*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE8]]
414*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue8:
415*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP33:%.*]] = phi <4 x i32> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP32]], [[PRED_LOAD_IF7]] ]
416*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1
417*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP34]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]
418*12fb133eSKerry McLaughlin; CHECK:       pred.load.if9:
419*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP35:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP0]]
420*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4
421*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP37:%.*]] = insertelement <4 x i32> [[TMP33]], i32 [[TMP36]], i64 1
422*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE10]]
423*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue10:
424*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP38:%.*]] = phi <4 x i32> [ [[TMP33]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP37]], [[PRED_LOAD_IF9]] ]
425*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP39:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2
426*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP39]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]
427*12fb133eSKerry McLaughlin; CHECK:       pred.load.if11:
428*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP1]]
429*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4
430*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP42:%.*]] = insertelement <4 x i32> [[TMP38]], i32 [[TMP41]], i64 2
431*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE12]]
432*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue12:
433*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP43:%.*]] = phi <4 x i32> [ [[TMP38]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP42]], [[PRED_LOAD_IF11]] ]
434*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3
435*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP44]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]
436*12fb133eSKerry McLaughlin; CHECK:       pred.load.if13:
437*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP45:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP2]]
438*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP46:%.*]] = load i32, i32* [[TMP45]], align 4
439*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP47:%.*]] = insertelement <4 x i32> [[TMP43]], i32 [[TMP46]], i64 3
440*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE14]]
441*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue14:
442*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP48:%.*]] = phi <4 x i32> [ [[TMP43]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP47]], [[PRED_LOAD_IF13]] ]
443*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP49:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP48]], <4 x i32> zeroinitializer
444*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP50:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP49]])
445*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP51]] = add i32 [[TMP50]], [[TMP28]]
446*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
447*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP52:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
448*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP52]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
449*12fb133eSKerry McLaughlin; CHECK:       middle.block:
450*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
451*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
452*12fb133eSKerry McLaughlin; CHECK:       scalar.ph:
453*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
454*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP51]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]
455*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
456*12fb133eSKerry McLaughlin; CHECK:       for.body:
457*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
458*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
459*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[COND]], i64 [[IV]]
460*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP53:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
461*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP53]], 0
462*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]
463*12fb133eSKerry McLaughlin; CHECK:       if.then:
464*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[IV]]
465*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP54:%.*]] = load i32, i32* [[ARRAYIDX1]], align 4
466*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP54]], [[RDX]]
467*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[IV]]
468*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP55:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
469*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[ADD]], [[TMP55]]
470*12fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
471*12fb133eSKerry McLaughlin; CHECK:       for.inc:
472*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi i32 [ [[ADD3]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
473*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
474*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
475*12fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
476*12fb133eSKerry McLaughlin; CHECK:       for.end:
477*12fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP51]], [[MIDDLE_BLOCK]] ]
478*12fb133eSKerry McLaughlin; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
479*12fb133eSKerry McLaughlin;
480*12fb133eSKerry McLaughlinentry:
481*12fb133eSKerry McLaughlin  br label %for.body
482*12fb133eSKerry McLaughlin
483*12fb133eSKerry McLaughlinfor.body:
484*12fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
485*12fb133eSKerry McLaughlin  %rdx = phi i32 [ %res, %for.inc ], [ 5, %entry ]
486*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %cond, i64 %iv
487*12fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
488*12fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %0, 0
489*12fb133eSKerry McLaughlin  br i1 %tobool.not, label %for.inc, label %if.then
490*12fb133eSKerry McLaughlin
491*12fb133eSKerry McLaughlinif.then:
492*12fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %a, i64 %iv
493*12fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
494*12fb133eSKerry McLaughlin  %add = add nsw i32 %1, %rdx
495*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %b, i64 %iv
496*12fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
497*12fb133eSKerry McLaughlin  %add3 = add nsw i32 %add, %2
498*12fb133eSKerry McLaughlin  br label %for.inc
499*12fb133eSKerry McLaughlin
500*12fb133eSKerry McLaughlinfor.inc:
501*12fb133eSKerry McLaughlin  %res = phi i32 [ %add3, %if.then ], [ %rdx, %for.body ]
502*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
503*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
504*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
505*12fb133eSKerry McLaughlin
506*12fb133eSKerry McLaughlinfor.end:
507*12fb133eSKerry McLaughlin  ret i32 %res
508*12fb133eSKerry McLaughlin}
509*12fb133eSKerry McLaughlin
510*12fb133eSKerry McLaughlin;
511*12fb133eSKerry McLaughlin; Negative Tests
512*12fb133eSKerry McLaughlin;
513*12fb133eSKerry McLaughlin
514*12fb133eSKerry McLaughlin;
515*12fb133eSKerry McLaughlin; Reduction not performed in loop as the phi has more than two incoming values
516*12fb133eSKerry McLaughlin;
517*12fb133eSKerry McLaughlindefine i64 @nested_cond_and(i64* noalias nocapture readonly %a, i64* noalias nocapture readonly %b, i64* noalias nocapture readonly %cond, i64 %N){
518*12fb133eSKerry McLaughlin; CHECK-LABEL: @nested_cond_and(
519*12fb133eSKerry McLaughlin; CHECK:       vector.body:
520*12fb133eSKerry McLaughlin; CHECK-NOT:     @llvm.vector.reduce.and
521*12fb133eSKerry McLaughlin; CHECK:       middle.block:
522*12fb133eSKerry McLaughlin; CHECK:         @llvm.vector.reduce.and
523*12fb133eSKerry McLaughlin; CHECK:       scalar.ph
524*12fb133eSKerry McLaughlinentry:
525*12fb133eSKerry McLaughlin  br label %for.body
526*12fb133eSKerry McLaughlin
527*12fb133eSKerry McLaughlinfor.body:
528*12fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
529*12fb133eSKerry McLaughlin  %rdx = phi i64 [ 5, %entry ], [ %res, %for.inc ]
530*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i64, i64* %cond, i64 %iv
531*12fb133eSKerry McLaughlin  %0 = load i64, i64* %arrayidx
532*12fb133eSKerry McLaughlin  %tobool = icmp eq i64 %0, 0
533*12fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
534*12fb133eSKerry McLaughlin
535*12fb133eSKerry McLaughlinif.then:
536*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i64, i64* %a, i64 %iv
537*12fb133eSKerry McLaughlin  %1 = load i64, i64* %arrayidx2
538*12fb133eSKerry McLaughlin  %and1 = and i64 %rdx, %1
539*12fb133eSKerry McLaughlin  %tobool2 = icmp eq i64 %1, 3
540*12fb133eSKerry McLaughlin  br i1 %tobool2, label %if.then.2, label %for.inc
541*12fb133eSKerry McLaughlin
542*12fb133eSKerry McLaughlinif.then.2:
543*12fb133eSKerry McLaughlin  %arrayidx3 = getelementptr inbounds i64, i64* %b, i64 %iv
544*12fb133eSKerry McLaughlin  %2 = load i64, i64* %arrayidx3
545*12fb133eSKerry McLaughlin  %and2 = and i64 %rdx, %2
546*12fb133eSKerry McLaughlin  br label %for.inc
547*12fb133eSKerry McLaughlin
548*12fb133eSKerry McLaughlinfor.inc:
549*12fb133eSKerry McLaughlin  %res = phi i64 [ %and2, %if.then.2 ], [ %and1, %if.then ], [ %rdx, %for.body ]
550*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
551*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
552*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
553*12fb133eSKerry McLaughlin
554*12fb133eSKerry McLaughlinfor.end:
555*12fb133eSKerry McLaughlin  ret i64 %res
556*12fb133eSKerry McLaughlin}
557*12fb133eSKerry McLaughlin
558*12fb133eSKerry McLaughlin; Chain of conditional & unconditional reductions. We currently only support conditional reductions
559*12fb133eSKerry McLaughlin; if they are the last in the chain, i.e. the loop exit instruction is a Phi node. Therefore we reject
560*12fb133eSKerry McLaughlin; the Phi (%rdx1) as it has more than one use.
561*12fb133eSKerry McLaughlin;
562*12fb133eSKerry McLaughlindefine i32 @cond-uncond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 noundef %n) #0 {
563*12fb133eSKerry McLaughlin; CHECK-LABEL: @cond-uncond(
564*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
565*12fb133eSKerry McLaughlin; CHECK-NOT:     @llvm.vector.reduce.add
566*12fb133eSKerry McLaughlin; CHECK:       middle.block:
567*12fb133eSKerry McLaughlin; CHECK:         @llvm.vector.reduce.add
568*12fb133eSKerry McLaughlin; CHECK:       scalar.ph
569*12fb133eSKerry McLaughlinentry:
570*12fb133eSKerry McLaughlin  br label %for.body
571*12fb133eSKerry McLaughlin
572*12fb133eSKerry McLaughlinfor.body:
573*12fb133eSKerry McLaughlin  %rdx1 = phi i32 [ %add2, %if.end ], [ 0, %entry ]
574*12fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry]
575*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %cond, i64 %iv
576*12fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
577*12fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %0, 0
578*12fb133eSKerry McLaughlin  br i1 %tobool.not, label %if.end, label %if.then
579*12fb133eSKerry McLaughlin
580*12fb133eSKerry McLaughlinif.then:
581*12fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %src2, i64 %iv
582*12fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
583*12fb133eSKerry McLaughlin  %add = add nsw i32 %1, %rdx1
584*12fb133eSKerry McLaughlin  br label %if.end
585*12fb133eSKerry McLaughlin
586*12fb133eSKerry McLaughlinif.end:
587*12fb133eSKerry McLaughlin  %res = phi i32 [ %add, %if.then ], [ %rdx1, %for.body ]
588*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src1, i64 %iv
589*12fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
590*12fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %res
591*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
592*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %n
593*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
594*12fb133eSKerry McLaughlin
595*12fb133eSKerry McLaughlinfor.end:
596*12fb133eSKerry McLaughlin  ret i32 %add2
597*12fb133eSKerry McLaughlin}
598*12fb133eSKerry McLaughlin
599*12fb133eSKerry McLaughlin;
600*12fb133eSKerry McLaughlin; Chain of two conditional reductions. We do not vectorise this with in-loop reductions as neither
601*12fb133eSKerry McLaughlin; of the incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx1).
602*12fb133eSKerry McLaughlin;
603*12fb133eSKerry McLaughlindefine float @cond_cond(float* noalias %src1, float* noalias %src2, float* noalias %cond, i64 %n) #0 {
604*12fb133eSKerry McLaughlin; CHECK-LABEL: @cond_cond(
605*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue14:
606*12fb133eSKerry McLaughlin; CHECK-NOT:     @llvm.vector.reduce.fadd
607*12fb133eSKerry McLaughlin; CHECK:       middle.block:
608*12fb133eSKerry McLaughlin; CHECK:         @llvm.vector.reduce.fadd
609*12fb133eSKerry McLaughlin; CHECK:       scalar.ph
610*12fb133eSKerry McLaughlinentry:
611*12fb133eSKerry McLaughlin  br label %for.body
612*12fb133eSKerry McLaughlin
613*12fb133eSKerry McLaughlinfor.body:
614*12fb133eSKerry McLaughlin  %rdx1 = phi float [ %res, %for.inc ], [ 2.000000e+00, %entry ]
615*12fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
616*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
617*12fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
618*12fb133eSKerry McLaughlin  %cmp1 = fcmp fast oeq float %0, 3.000000e+00
619*12fb133eSKerry McLaughlin  br i1 %cmp1, label %if.then, label %if.end
620*12fb133eSKerry McLaughlin
621*12fb133eSKerry McLaughlinif.then:
622*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %src1, i64 %iv
623*12fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
624*12fb133eSKerry McLaughlin  %add = fadd fast float %1, %rdx1
625*12fb133eSKerry McLaughlin  br label %if.end
626*12fb133eSKerry McLaughlin
627*12fb133eSKerry McLaughlinif.end:
628*12fb133eSKerry McLaughlin  %rdx2 = phi float [ %add, %if.then ], [ %rdx1, %for.body ]
629*12fb133eSKerry McLaughlin  %cmp5 = fcmp fast oeq float %0, 7.000000e+00
630*12fb133eSKerry McLaughlin  br i1 %cmp5, label %if.then6, label %for.inc
631*12fb133eSKerry McLaughlin
632*12fb133eSKerry McLaughlinif.then6:
633*12fb133eSKerry McLaughlin  %arrayidx7 = getelementptr inbounds float, float* %src2, i64 %iv
634*12fb133eSKerry McLaughlin  %2 = load float, float* %arrayidx7
635*12fb133eSKerry McLaughlin  %add2 = fadd fast float %2, %rdx2
636*12fb133eSKerry McLaughlin  br label %for.inc
637*12fb133eSKerry McLaughlin
638*12fb133eSKerry McLaughlinfor.inc:
639*12fb133eSKerry McLaughlin  %res = phi float [ %add2, %if.then6 ], [ %rdx2, %if.end ]
640*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
641*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %n
642*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
643*12fb133eSKerry McLaughlin
644*12fb133eSKerry McLaughlinfor.end:
645*12fb133eSKerry McLaughlin  ret float %res
646*12fb133eSKerry McLaughlin}
647*12fb133eSKerry McLaughlin
648*12fb133eSKerry McLaughlin;
649*12fb133eSKerry McLaughlin; Chain of an unconditional & a conditional reduction. We do not vectorise this in-loop as neither of the
650*12fb133eSKerry McLaughlin; incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx).
651*12fb133eSKerry McLaughlin;
652*12fb133eSKerry McLaughlindefine i32 @uncond_cond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 %N) #0 {
653*12fb133eSKerry McLaughlin; CHECK-LABEL: @uncond_cond(
654*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue7:
655*12fb133eSKerry McLaughlin; CHECK-NOT:     @llvm.vector.reduce.add
656*12fb133eSKerry McLaughlin; CHECK:       middle.block:
657*12fb133eSKerry McLaughlin; CHECK:         @llvm.vector.reduce.add
658*12fb133eSKerry McLaughlin; CHECK:       scalar.ph
659*12fb133eSKerry McLaughlinentry:
660*12fb133eSKerry McLaughlin  br label %for.body
661*12fb133eSKerry McLaughlin
662*12fb133eSKerry McLaughlinfor.body:
663*12fb133eSKerry McLaughlin  %rdx = phi i32 [ %res, %for.inc ], [ 0, %entry ]
664*12fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
665*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %src1, i64 %iv
666*12fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
667*12fb133eSKerry McLaughlin  %add1 = add nsw i32 %0, %rdx
668*12fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %cond, i64 %iv
669*12fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
670*12fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %1, 0
671*12fb133eSKerry McLaughlin  br i1 %tobool.not, label %for.inc, label %if.then
672*12fb133eSKerry McLaughlin
673*12fb133eSKerry McLaughlinif.then:
674*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src2, i64 %iv
675*12fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
676*12fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %add1
677*12fb133eSKerry McLaughlin  br label %for.inc
678*12fb133eSKerry McLaughlin
679*12fb133eSKerry McLaughlinfor.inc:
680*12fb133eSKerry McLaughlin  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
681*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
682*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
683*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
684*12fb133eSKerry McLaughlin
685*12fb133eSKerry McLaughlinfor.end:
686*12fb133eSKerry McLaughlin  ret i32 %res
687*12fb133eSKerry McLaughlin}
688*12fb133eSKerry McLaughlin
689*12fb133eSKerry McLaughlin;
690*12fb133eSKerry McLaughlin; Chain of multiple unconditional & conditional reductions. Does not vectorise in-loop as when we look back
691*12fb133eSKerry McLaughlin; through the chain and check the number of uses of %add1, we find more than the expected one use.
692*12fb133eSKerry McLaughlin;
693*12fb133eSKerry McLaughlindefine i32 @uncond_cond_uncond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 noundef %N) {
694*12fb133eSKerry McLaughlin; CHECK-LABEL: @uncond_cond_uncond(
695*12fb133eSKerry McLaughlin; CHECK:       pred.load.continue7:
696*12fb133eSKerry McLaughlin; CHECK-NOT:     @llvm.vector.reduce.add
697*12fb133eSKerry McLaughlin; CHECK:       middle.block:
698*12fb133eSKerry McLaughlin; CHECK:         @llvm.vector.reduce.add
699*12fb133eSKerry McLaughlin; CHECK:       scalar.ph
700*12fb133eSKerry McLaughlinentry:
701*12fb133eSKerry McLaughlin  br label %for.body
702*12fb133eSKerry McLaughlin
703*12fb133eSKerry McLaughlinfor.body:
704*12fb133eSKerry McLaughlin  %rdx = phi i32 [ %add3, %if.end ], [ 0, %entry ]
705*12fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry ]
706*12fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %src1, i64 %iv
707*12fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
708*12fb133eSKerry McLaughlin  %add1 = add nsw i32 %0, %rdx
709*12fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %cond, i64 %iv
710*12fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
711*12fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %1, 0
712*12fb133eSKerry McLaughlin  br i1 %tobool.not, label %if.end, label %if.then
713*12fb133eSKerry McLaughlin
714*12fb133eSKerry McLaughlinif.then:
715*12fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src2, i64 %iv
716*12fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
717*12fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %add1
718*12fb133eSKerry McLaughlin  br label %if.end
719*12fb133eSKerry McLaughlin
720*12fb133eSKerry McLaughlinif.end:
721*12fb133eSKerry McLaughlin  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
722*12fb133eSKerry McLaughlin  %add3 = add nsw i32 %res, %0
723*12fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
724*12fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
725*12fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
726*12fb133eSKerry McLaughlin
727*12fb133eSKerry McLaughlinfor.end:
728*12fb133eSKerry McLaughlin  ret i32 %add3
729*12fb133eSKerry McLaughlin}
730