112fb133eSKerry McLaughlin; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -prefer-inloop-reductions -dce -instcombine -S | FileCheck %s
212fb133eSKerry McLaughlin
312fb133eSKerry McLaughlindefine float @cond_fadd(float* noalias nocapture readonly %a, float* noalias nocapture readonly %cond, i64 %N){
412fb133eSKerry McLaughlin; CHECK-LABEL: @cond_fadd(
512fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
612fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
712fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
812fb133eSKerry McLaughlin; CHECK:       vector.ph:
912fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
1012fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1112fb133eSKerry McLaughlin; CHECK:       vector.body:
1212fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
1312fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]
1412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[COND:%.*]], i64 [[INDEX]]
1512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
1612fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 4
1712fb133eSKerry 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>
1812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
1912fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
2012fb133eSKerry McLaughlin; CHECK:       pred.load.if:
2112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[INDEX]]
2212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load float, float* [[TMP4]], align 4
2312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x float> poison, float [[TMP5]], i64 0
2412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
2512fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
2612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
2712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
2812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
2912fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
3012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
3112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]]
3212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load float, float* [[TMP10]], align 4
3312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x float> [[TMP7]], float [[TMP11]], i64 1
3412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
3512fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
3612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x float> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
3712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
3812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
3912fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
4012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
4112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]]
4212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load float, float* [[TMP16]], align 4
4312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float> [[TMP13]], float [[TMP17]], i64 2
4412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
4512fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
4612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x float> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
4712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
4812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
4912fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
5012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
5112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP21]]
5212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load float, float* [[TMP22]], align 4
5312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP23]], i64 3
5412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
5512fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
5612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
5712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select fast <4 x i1> [[TMP2]], <4 x float> [[TMP25]], <4 x float> zeroinitializer
5812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[VEC_PHI]], <4 x float> [[TMP26]])
5912fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
6012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
6112fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
6212fb133eSKerry McLaughlin; CHECK:       middle.block:
6312fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
6412fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
6512fb133eSKerry McLaughlin; CHECK:       scalar.ph:
6612fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
6712fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP27]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
6812fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
6912fb133eSKerry McLaughlin; CHECK:       for.body:
7012fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
7112fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
7212fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[COND]], i64 [[IV]]
7312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = load float, float* [[ARRAYIDX]], align 4
7412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP29]], 5.000000e+00
7512fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
7612fb133eSKerry McLaughlin; CHECK:       if.then:
7712fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[IV]]
7812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load float, float* [[ARRAYIDX2]], align 4
7912fb133eSKerry McLaughlin; CHECK-NEXT:    [[FADD:%.*]] = fadd fast float [[RDX]], [[TMP30]]
8012fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
8112fb133eSKerry McLaughlin; CHECK:       for.inc:
8212fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FADD]], [[IF_THEN]] ]
8312fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
8412fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
8512fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
8612fb133eSKerry McLaughlin; CHECK:       for.end:
8712fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP27]], [[MIDDLE_BLOCK]] ]
8812fb133eSKerry McLaughlin; CHECK-NEXT:    ret float [[RES_LCSSA]]
8912fb133eSKerry McLaughlin;
9012fb133eSKerry McLaughlinentry:
9112fb133eSKerry McLaughlin  br label %for.body
9212fb133eSKerry McLaughlin
9312fb133eSKerry McLaughlinfor.body:
9412fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
9512fb133eSKerry McLaughlin  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
9612fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
9712fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
9812fb133eSKerry McLaughlin  %tobool = fcmp une float %0, 5.000000e+00
9912fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
10012fb133eSKerry McLaughlin
10112fb133eSKerry McLaughlinif.then:
10212fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
10312fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
10412fb133eSKerry McLaughlin  %fadd = fadd fast float %rdx, %1
10512fb133eSKerry McLaughlin  br label %for.inc
10612fb133eSKerry McLaughlin
10712fb133eSKerry McLaughlinfor.inc:
10812fb133eSKerry McLaughlin  %res = phi float [ %rdx, %for.body ], [ %fadd, %if.then ]
10912fb133eSKerry McLaughlin  %iv.next = add i64 %iv, 1
11012fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
11112fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
11212fb133eSKerry McLaughlin
11312fb133eSKerry McLaughlinfor.end:
11412fb133eSKerry McLaughlin  ret float %res
11512fb133eSKerry McLaughlin}
11612fb133eSKerry McLaughlin
11712fb133eSKerry McLaughlindefine float @cond_cmp_sel(float* noalias %a, float* noalias %cond, i64 %N) {
11812fb133eSKerry McLaughlin; CHECK-LABEL: @cond_cmp_sel(
11912fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
12012fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
12112fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12212fb133eSKerry McLaughlin; CHECK:       vector.ph:
12312fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
12412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
12512fb133eSKerry McLaughlin; CHECK:       vector.body:
12612fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
12712fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE6]] ]
12812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[COND:%.*]], i64 [[INDEX]]
12912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
13012fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 4
13112fb133eSKerry 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>
13212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
13312fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
13412fb133eSKerry McLaughlin; CHECK:       pred.load.if:
13512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[INDEX]]
13612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load float, float* [[TMP4]], align 4
13712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x float> poison, float [[TMP5]], i64 0
13812fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
13912fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
14012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
14112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
14212fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
14312fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
14412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
14512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP9]]
14612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load float, float* [[TMP10]], align 4
14712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x float> [[TMP7]], float [[TMP11]], i64 1
14812fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
14912fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
15012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x float> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
15112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
15212fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
15312fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
15412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
15512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP15]]
15612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load float, float* [[TMP16]], align 4
15712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float> [[TMP13]], float [[TMP17]], i64 2
15812fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
15912fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
16012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x float> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
16112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
16212fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
16312fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
16412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
16512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[TMP21]]
16612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load float, float* [[TMP22]], align 4
16712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP23]], i64 3
16812fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
16912fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
17012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
17112fb133eSKerry 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>
17212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[TMP26]])
17312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28]] = call fast float @llvm.minnum.f32(float [[TMP27]], float [[VEC_PHI]])
17412fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
17512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
17612fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
17712fb133eSKerry McLaughlin; CHECK:       middle.block:
17812fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
17912fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
18012fb133eSKerry McLaughlin; CHECK:       scalar.ph:
18112fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
18212fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP28]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]
18312fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
18412fb133eSKerry McLaughlin; CHECK:       for.body:
18512fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
18612fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
18712fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[COND]], i64 [[IV]]
18812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load float, float* [[ARRAYIDX]], align 4
18912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = fcmp une float [[TMP30]], 3.000000e+00
19012fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
19112fb133eSKerry McLaughlin; CHECK:       if.then:
19212fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, float* [[A]], i64 [[IV]]
19312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load float, float* [[ARRAYIDX2]], align 4
19412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP32:%.*]] = call fast float @llvm.minnum.f32(float [[RDX]], float [[TMP31]])
19512fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
19612fb133eSKerry McLaughlin; CHECK:       for.inc:
19712fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[TMP32]], [[IF_THEN]] ]
19812fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
19912fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
20012fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
20112fb133eSKerry McLaughlin; CHECK:       for.end:
20212fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP28]], [[MIDDLE_BLOCK]] ]
20312fb133eSKerry McLaughlin; CHECK-NEXT:    ret float [[RES_LCSSA]]
20412fb133eSKerry McLaughlin;
20512fb133eSKerry McLaughlinentry:
20612fb133eSKerry McLaughlin  br label %for.body
20712fb133eSKerry McLaughlin
20812fb133eSKerry McLaughlinfor.body:
20912fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
21012fb133eSKerry McLaughlin  %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]
21112fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
21212fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
21312fb133eSKerry McLaughlin  %tobool = fcmp une float %0, 3.000000e+00
21412fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
21512fb133eSKerry McLaughlin
21612fb133eSKerry McLaughlinif.then:
21712fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
21812fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
21912fb133eSKerry McLaughlin  %fcmp = fcmp fast olt float %rdx, %1
22012fb133eSKerry McLaughlin  %fsel = select fast i1 %fcmp, float %rdx, float %1
22112fb133eSKerry McLaughlin  br label %for.inc
22212fb133eSKerry McLaughlin
22312fb133eSKerry McLaughlinfor.inc:
22412fb133eSKerry McLaughlin  %res = phi float [ %rdx, %for.body ], [ %fsel, %if.then ]
22512fb133eSKerry McLaughlin  %iv.next = add i64 %iv, 1
22612fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
22712fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
22812fb133eSKerry McLaughlin
22912fb133eSKerry McLaughlinfor.end:
23012fb133eSKerry McLaughlin  ret float %res
23112fb133eSKerry McLaughlin}
23212fb133eSKerry McLaughlin
23312fb133eSKerry McLaughlindefine i32 @conditional_and(i32* noalias %A, i32* noalias %B, i32 %cond, i64 noundef %N) #0 {
23412fb133eSKerry McLaughlin; CHECK-LABEL: @conditional_and(
23512fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
23612fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
23712fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
23812fb133eSKerry McLaughlin; CHECK:       vector.ph:
23912fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
24012fb133eSKerry McLaughlin; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[COND:%.*]], i64 0
24112fb133eSKerry McLaughlin; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
24212fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
24312fb133eSKerry McLaughlin; CHECK:       vector.body:
24412fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
24512fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 7, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE6]] ]
24612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDEX]]
24712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
24812fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
24912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
25012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i64 0
25112fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP3]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
25212fb133eSKerry McLaughlin; CHECK:       pred.load.if:
25312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDEX]]
25412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
25512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <4 x i32> poison, i32 [[TMP5]], i64 0
25612fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
25712fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
25812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP6]], [[PRED_LOAD_IF]] ]
25912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <4 x i1> [[TMP2]], i64 1
26012fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP8]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
26112fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
26212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[INDEX]], 1
26312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP9]]
26412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = load i32, i32* [[TMP10]], align 4
26512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = insertelement <4 x i32> [[TMP7]], i32 [[TMP11]], i64 1
26612fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
26712fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
26812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = phi <4 x i32> [ [[TMP7]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP12]], [[PRED_LOAD_IF1]] ]
26912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x i1> [[TMP2]], i64 2
27012fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP14]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
27112fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
27212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = or i64 [[INDEX]], 2
27312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP15]]
27412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 4
27512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x i32> [[TMP13]], i32 [[TMP17]], i64 2
27612fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
27712fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
27812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = phi <4 x i32> [ [[TMP13]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]
27912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = extractelement <4 x i1> [[TMP2]], i64 3
28012fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]
28112fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
28212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = or i64 [[INDEX]], 3
28312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP21]]
28412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4
28512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i32> [[TMP19]], i32 [[TMP23]], i64 3
28612fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
28712fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
28812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i32> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
28912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP25]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
29012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> [[TMP26]])
29112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28]] = and i32 [[TMP27]], [[VEC_PHI]]
29212fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
29312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
29412fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
29512fb133eSKerry McLaughlin; CHECK:       middle.block:
29612fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
29712fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
29812fb133eSKerry McLaughlin; CHECK:       scalar.ph:
29912fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
30012fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP28]], [[MIDDLE_BLOCK]] ], [ 7, [[ENTRY]] ]
30112fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
30212fb133eSKerry McLaughlin; CHECK:       for.body:
30312fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
30412fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]
30512fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[IV]]
30612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
30712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP30]], [[COND]]
30812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]
30912fb133eSKerry McLaughlin; CHECK:       if.then:
31012fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[IV]]
31112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
31212fb133eSKerry McLaughlin; CHECK-NEXT:    [[AND:%.*]] = and i32 [[TMP31]], [[RDX]]
31312fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
31412fb133eSKerry McLaughlin; CHECK:       for.inc:
31512fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi i32 [ [[AND]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
31612fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
31712fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
31812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
31912fb133eSKerry McLaughlin; CHECK:       for.end:
32012fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP28]], [[MIDDLE_BLOCK]] ]
32112fb133eSKerry McLaughlin; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
32212fb133eSKerry McLaughlin;
32312fb133eSKerry McLaughlinentry:
32412fb133eSKerry McLaughlin  br label %for.body
32512fb133eSKerry McLaughlin
32612fb133eSKerry McLaughlinfor.body:
32712fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
32812fb133eSKerry McLaughlin  %rdx = phi i32 [ 7, %entry ], [ %res, %for.inc ]
32912fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %iv
33012fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
33112fb133eSKerry McLaughlin  %tobool = icmp eq i32 %0, %cond
33212fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
33312fb133eSKerry McLaughlin
33412fb133eSKerry McLaughlinif.then:
33512fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %iv
33612fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx2
33712fb133eSKerry McLaughlin  %and = and i32 %1, %rdx
33812fb133eSKerry McLaughlin  br label %for.inc
33912fb133eSKerry McLaughlin
34012fb133eSKerry McLaughlinfor.inc:
34112fb133eSKerry McLaughlin  %res = phi i32 [ %and, %if.then ], [ %rdx, %for.body ]
34212fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
34312fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
34412fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
34512fb133eSKerry McLaughlin
34612fb133eSKerry McLaughlinfor.end:
34712fb133eSKerry McLaughlin  ret i32 %res
34812fb133eSKerry McLaughlin}
34912fb133eSKerry McLaughlin
35012fb133eSKerry McLaughlindefine i32 @simple_chained_rdx(i32* noalias %a, i32* noalias %b, i32* noalias %cond, i64 noundef %N) {
35112fb133eSKerry McLaughlin; CHECK-LABEL: @simple_chained_rdx(
35212fb133eSKerry McLaughlin; CHECK-NEXT:  entry:
35312fb133eSKerry McLaughlin; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
35412fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
35512fb133eSKerry McLaughlin; CHECK:       vector.ph:
35612fb133eSKerry McLaughlin; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -4
35712fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
35812fb133eSKerry McLaughlin; CHECK:       vector.body:
35912fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]
36012fb133eSKerry McLaughlin; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 5, [[VECTOR_PH]] ], [ [[TMP51:%.*]], [[PRED_LOAD_CONTINUE14]] ]
36112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP0:%.*]] = or i64 [[INDEX]], 1
36212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[INDEX]], 2
36312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[INDEX]], 3
36412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, i32* [[COND:%.*]], i64 [[INDEX]]
36512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP3]] to <4 x i32>*
36612fb133eSKerry McLaughlin; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP4]], align 4
36712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP5:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer
36812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0
36912fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP6]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]
37012fb133eSKerry McLaughlin; CHECK:       pred.load.if:
37112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDEX]]
37212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4
37312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <4 x i32> poison, i32 [[TMP8]], i64 0
37412fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE]]
37512fb133eSKerry McLaughlin; CHECK:       pred.load.continue:
37612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP10:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP9]], [[PRED_LOAD_IF]] ]
37712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1
37812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP11]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]
37912fb133eSKerry McLaughlin; CHECK:       pred.load.if1:
38012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP0]]
38112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
38212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <4 x i32> [[TMP10]], i32 [[TMP13]], i64 1
38312fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE2]]
38412fb133eSKerry McLaughlin; CHECK:       pred.load.continue2:
38512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP15:%.*]] = phi <4 x i32> [ [[TMP10]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], [[PRED_LOAD_IF1]] ]
38612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2
38712fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP16]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]
38812fb133eSKerry McLaughlin; CHECK:       pred.load.if3:
38912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP1]]
39012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 4
39112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i32> [[TMP15]], i32 [[TMP18]], i64 2
39212fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE4]]
39312fb133eSKerry McLaughlin; CHECK:       pred.load.continue4:
39412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP20:%.*]] = phi <4 x i32> [ [[TMP15]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP19]], [[PRED_LOAD_IF3]] ]
39512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP21:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3
39612fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP21]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]
39712fb133eSKerry McLaughlin; CHECK:       pred.load.if5:
39812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP2]]
39912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4
40012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP24:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP23]], i64 3
40112fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE6]]
40212fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
40312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP25:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP24]], [[PRED_LOAD_IF5]] ]
40412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP26:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP25]], <4 x i32> zeroinitializer
40512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP27:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP26]])
40612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP28:%.*]] = add i32 [[TMP27]], [[VEC_PHI]]
40712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP29:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0
40812fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP29]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]
40912fb133eSKerry McLaughlin; CHECK:       pred.load.if7:
41012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i64 [[INDEX]]
41112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4
41212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP32:%.*]] = insertelement <4 x i32> poison, i32 [[TMP31]], i64 0
41312fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE8]]
41412fb133eSKerry McLaughlin; CHECK:       pred.load.continue8:
41512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP33:%.*]] = phi <4 x i32> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP32]], [[PRED_LOAD_IF7]] ]
41612fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP34:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1
41712fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP34]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]
41812fb133eSKerry McLaughlin; CHECK:       pred.load.if9:
41912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP35:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP0]]
42012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4
42112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP37:%.*]] = insertelement <4 x i32> [[TMP33]], i32 [[TMP36]], i64 1
42212fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE10]]
42312fb133eSKerry McLaughlin; CHECK:       pred.load.continue10:
42412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP38:%.*]] = phi <4 x i32> [ [[TMP33]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP37]], [[PRED_LOAD_IF9]] ]
42512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP39:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2
42612fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP39]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]
42712fb133eSKerry McLaughlin; CHECK:       pred.load.if11:
42812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP40:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP1]]
42912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4
43012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP42:%.*]] = insertelement <4 x i32> [[TMP38]], i32 [[TMP41]], i64 2
43112fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE12]]
43212fb133eSKerry McLaughlin; CHECK:       pred.load.continue12:
43312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP43:%.*]] = phi <4 x i32> [ [[TMP38]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP42]], [[PRED_LOAD_IF11]] ]
43412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3
43512fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TMP44]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]
43612fb133eSKerry McLaughlin; CHECK:       pred.load.if13:
43712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP45:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP2]]
43812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP46:%.*]] = load i32, i32* [[TMP45]], align 4
43912fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP47:%.*]] = insertelement <4 x i32> [[TMP43]], i32 [[TMP46]], i64 3
44012fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[PRED_LOAD_CONTINUE14]]
44112fb133eSKerry McLaughlin; CHECK:       pred.load.continue14:
44212fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP48:%.*]] = phi <4 x i32> [ [[TMP43]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP47]], [[PRED_LOAD_IF13]] ]
44312fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP49:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP48]], <4 x i32> zeroinitializer
44412fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP50:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP49]])
44512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP51]] = add i32 [[TMP50]], [[TMP28]]
44612fb133eSKerry McLaughlin; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
44712fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP52:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
448*872f7000SDávid Bolvanský; CHECK-NEXT:    br i1 [[TMP52]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
44912fb133eSKerry McLaughlin; CHECK:       middle.block:
45012fb133eSKerry McLaughlin; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[N]]
45112fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
45212fb133eSKerry McLaughlin; CHECK:       scalar.ph:
45312fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
45412fb133eSKerry McLaughlin; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP51]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]
45512fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
45612fb133eSKerry McLaughlin; CHECK:       for.body:
45712fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
45812fb133eSKerry McLaughlin; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
45912fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[COND]], i64 [[IV]]
46012fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP53:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
46112fb133eSKerry McLaughlin; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP53]], 0
46212fb133eSKerry McLaughlin; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]
46312fb133eSKerry McLaughlin; CHECK:       if.then:
46412fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[IV]]
46512fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP54:%.*]] = load i32, i32* [[ARRAYIDX1]], align 4
46612fb133eSKerry McLaughlin; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP54]], [[RDX]]
46712fb133eSKerry McLaughlin; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[IV]]
46812fb133eSKerry McLaughlin; CHECK-NEXT:    [[TMP55:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4
46912fb133eSKerry McLaughlin; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[ADD]], [[TMP55]]
47012fb133eSKerry McLaughlin; CHECK-NEXT:    br label [[FOR_INC]]
47112fb133eSKerry McLaughlin; CHECK:       for.inc:
47212fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES]] = phi i32 [ [[ADD3]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]
47312fb133eSKerry McLaughlin; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
47412fb133eSKerry McLaughlin; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
475*872f7000SDávid Bolvanský; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
47612fb133eSKerry McLaughlin; CHECK:       for.end:
47712fb133eSKerry McLaughlin; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP51]], [[MIDDLE_BLOCK]] ]
47812fb133eSKerry McLaughlin; CHECK-NEXT:    ret i32 [[RES_LCSSA]]
47912fb133eSKerry McLaughlin;
48012fb133eSKerry McLaughlinentry:
48112fb133eSKerry McLaughlin  br label %for.body
48212fb133eSKerry McLaughlin
48312fb133eSKerry McLaughlinfor.body:
48412fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
48512fb133eSKerry McLaughlin  %rdx = phi i32 [ %res, %for.inc ], [ 5, %entry ]
48612fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %cond, i64 %iv
48712fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
48812fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %0, 0
48912fb133eSKerry McLaughlin  br i1 %tobool.not, label %for.inc, label %if.then
49012fb133eSKerry McLaughlin
49112fb133eSKerry McLaughlinif.then:
49212fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %a, i64 %iv
49312fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
49412fb133eSKerry McLaughlin  %add = add nsw i32 %1, %rdx
49512fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %b, i64 %iv
49612fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
49712fb133eSKerry McLaughlin  %add3 = add nsw i32 %add, %2
49812fb133eSKerry McLaughlin  br label %for.inc
49912fb133eSKerry McLaughlin
50012fb133eSKerry McLaughlinfor.inc:
50112fb133eSKerry McLaughlin  %res = phi i32 [ %add3, %if.then ], [ %rdx, %for.body ]
50212fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
50312fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
50412fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
50512fb133eSKerry McLaughlin
50612fb133eSKerry McLaughlinfor.end:
50712fb133eSKerry McLaughlin  ret i32 %res
50812fb133eSKerry McLaughlin}
50912fb133eSKerry McLaughlin
51012fb133eSKerry McLaughlin;
51112fb133eSKerry McLaughlin; Negative Tests
51212fb133eSKerry McLaughlin;
51312fb133eSKerry McLaughlin
51412fb133eSKerry McLaughlin;
51512fb133eSKerry McLaughlin; Reduction not performed in loop as the phi has more than two incoming values
51612fb133eSKerry McLaughlin;
51712fb133eSKerry McLaughlindefine i64 @nested_cond_and(i64* noalias nocapture readonly %a, i64* noalias nocapture readonly %b, i64* noalias nocapture readonly %cond, i64 %N){
51812fb133eSKerry McLaughlin; CHECK-LABEL: @nested_cond_and(
51912fb133eSKerry McLaughlin; CHECK:       vector.body:
520*872f7000SDávid Bolvanský; CHECK-NOT:     @llvm.vector.reduce.and
52112fb133eSKerry McLaughlin; CHECK:       middle.block:
522*872f7000SDávid Bolvanský; CHECK:         @llvm.vector.reduce.and
523*872f7000SDávid Bolvanský; CHECK:       scalar.ph
52412fb133eSKerry McLaughlinentry:
52512fb133eSKerry McLaughlin  br label %for.body
52612fb133eSKerry McLaughlin
52712fb133eSKerry McLaughlinfor.body:
52812fb133eSKerry McLaughlin  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
52912fb133eSKerry McLaughlin  %rdx = phi i64 [ 5, %entry ], [ %res, %for.inc ]
53012fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i64, i64* %cond, i64 %iv
53112fb133eSKerry McLaughlin  %0 = load i64, i64* %arrayidx
53212fb133eSKerry McLaughlin  %tobool = icmp eq i64 %0, 0
53312fb133eSKerry McLaughlin  br i1 %tobool, label %if.then, label %for.inc
53412fb133eSKerry McLaughlin
53512fb133eSKerry McLaughlinif.then:
53612fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i64, i64* %a, i64 %iv
53712fb133eSKerry McLaughlin  %1 = load i64, i64* %arrayidx2
53812fb133eSKerry McLaughlin  %and1 = and i64 %rdx, %1
53912fb133eSKerry McLaughlin  %tobool2 = icmp eq i64 %1, 3
54012fb133eSKerry McLaughlin  br i1 %tobool2, label %if.then.2, label %for.inc
54112fb133eSKerry McLaughlin
54212fb133eSKerry McLaughlinif.then.2:
54312fb133eSKerry McLaughlin  %arrayidx3 = getelementptr inbounds i64, i64* %b, i64 %iv
54412fb133eSKerry McLaughlin  %2 = load i64, i64* %arrayidx3
54512fb133eSKerry McLaughlin  %and2 = and i64 %rdx, %2
54612fb133eSKerry McLaughlin  br label %for.inc
54712fb133eSKerry McLaughlin
54812fb133eSKerry McLaughlinfor.inc:
54912fb133eSKerry McLaughlin  %res = phi i64 [ %and2, %if.then.2 ], [ %and1, %if.then ], [ %rdx, %for.body ]
55012fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
55112fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
55212fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
55312fb133eSKerry McLaughlin
55412fb133eSKerry McLaughlinfor.end:
55512fb133eSKerry McLaughlin  ret i64 %res
55612fb133eSKerry McLaughlin}
55712fb133eSKerry McLaughlin
55812fb133eSKerry McLaughlin; Chain of conditional & unconditional reductions. We currently only support conditional reductions
55912fb133eSKerry McLaughlin; if they are the last in the chain, i.e. the loop exit instruction is a Phi node. Therefore we reject
56012fb133eSKerry McLaughlin; the Phi (%rdx1) as it has more than one use.
56112fb133eSKerry McLaughlin;
56212fb133eSKerry McLaughlindefine i32 @cond-uncond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 noundef %n) #0 {
56312fb133eSKerry McLaughlin; CHECK-LABEL: @cond-uncond(
56412fb133eSKerry McLaughlin; CHECK:       pred.load.continue6:
565*872f7000SDávid Bolvanský; CHECK-NOT:     @llvm.vector.reduce.add
56612fb133eSKerry McLaughlin; CHECK:       middle.block:
567*872f7000SDávid Bolvanský; CHECK:         @llvm.vector.reduce.add
568*872f7000SDávid Bolvanský; CHECK:       scalar.ph
56912fb133eSKerry McLaughlinentry:
57012fb133eSKerry McLaughlin  br label %for.body
57112fb133eSKerry McLaughlin
57212fb133eSKerry McLaughlinfor.body:
57312fb133eSKerry McLaughlin  %rdx1 = phi i32 [ %add2, %if.end ], [ 0, %entry ]
57412fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry]
57512fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %cond, i64 %iv
57612fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
57712fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %0, 0
57812fb133eSKerry McLaughlin  br i1 %tobool.not, label %if.end, label %if.then
57912fb133eSKerry McLaughlin
58012fb133eSKerry McLaughlinif.then:
58112fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %src2, i64 %iv
58212fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
58312fb133eSKerry McLaughlin  %add = add nsw i32 %1, %rdx1
58412fb133eSKerry McLaughlin  br label %if.end
58512fb133eSKerry McLaughlin
58612fb133eSKerry McLaughlinif.end:
58712fb133eSKerry McLaughlin  %res = phi i32 [ %add, %if.then ], [ %rdx1, %for.body ]
58812fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src1, i64 %iv
58912fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
59012fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %res
59112fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
59212fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %n
59312fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
59412fb133eSKerry McLaughlin
59512fb133eSKerry McLaughlinfor.end:
59612fb133eSKerry McLaughlin  ret i32 %add2
59712fb133eSKerry McLaughlin}
59812fb133eSKerry McLaughlin
59912fb133eSKerry McLaughlin;
60012fb133eSKerry McLaughlin; Chain of two conditional reductions. We do not vectorise this with in-loop reductions as neither
60112fb133eSKerry McLaughlin; of the incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx1).
60212fb133eSKerry McLaughlin;
60312fb133eSKerry McLaughlindefine float @cond_cond(float* noalias %src1, float* noalias %src2, float* noalias %cond, i64 %n) #0 {
60412fb133eSKerry McLaughlin; CHECK-LABEL: @cond_cond(
60512fb133eSKerry McLaughlin; CHECK:       pred.load.continue14:
606*872f7000SDávid Bolvanský; CHECK-NOT:     @llvm.vector.reduce.fadd
60712fb133eSKerry McLaughlin; CHECK:       middle.block:
608*872f7000SDávid Bolvanský; CHECK:         @llvm.vector.reduce.fadd
609*872f7000SDávid Bolvanský; CHECK:       scalar.ph
61012fb133eSKerry McLaughlinentry:
61112fb133eSKerry McLaughlin  br label %for.body
61212fb133eSKerry McLaughlin
61312fb133eSKerry McLaughlinfor.body:
61412fb133eSKerry McLaughlin  %rdx1 = phi float [ %res, %for.inc ], [ 2.000000e+00, %entry ]
61512fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
61612fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds float, float* %cond, i64 %iv
61712fb133eSKerry McLaughlin  %0 = load float, float* %arrayidx
61812fb133eSKerry McLaughlin  %cmp1 = fcmp fast oeq float %0, 3.000000e+00
61912fb133eSKerry McLaughlin  br i1 %cmp1, label %if.then, label %if.end
62012fb133eSKerry McLaughlin
62112fb133eSKerry McLaughlinif.then:
62212fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds float, float* %src1, i64 %iv
62312fb133eSKerry McLaughlin  %1 = load float, float* %arrayidx2
62412fb133eSKerry McLaughlin  %add = fadd fast float %1, %rdx1
62512fb133eSKerry McLaughlin  br label %if.end
62612fb133eSKerry McLaughlin
62712fb133eSKerry McLaughlinif.end:
62812fb133eSKerry McLaughlin  %rdx2 = phi float [ %add, %if.then ], [ %rdx1, %for.body ]
62912fb133eSKerry McLaughlin  %cmp5 = fcmp fast oeq float %0, 7.000000e+00
63012fb133eSKerry McLaughlin  br i1 %cmp5, label %if.then6, label %for.inc
63112fb133eSKerry McLaughlin
63212fb133eSKerry McLaughlinif.then6:
63312fb133eSKerry McLaughlin  %arrayidx7 = getelementptr inbounds float, float* %src2, i64 %iv
63412fb133eSKerry McLaughlin  %2 = load float, float* %arrayidx7
63512fb133eSKerry McLaughlin  %add2 = fadd fast float %2, %rdx2
63612fb133eSKerry McLaughlin  br label %for.inc
63712fb133eSKerry McLaughlin
63812fb133eSKerry McLaughlinfor.inc:
63912fb133eSKerry McLaughlin  %res = phi float [ %add2, %if.then6 ], [ %rdx2, %if.end ]
64012fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
64112fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %n
64212fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
64312fb133eSKerry McLaughlin
64412fb133eSKerry McLaughlinfor.end:
64512fb133eSKerry McLaughlin  ret float %res
64612fb133eSKerry McLaughlin}
64712fb133eSKerry McLaughlin
64812fb133eSKerry McLaughlin;
64912fb133eSKerry McLaughlin; Chain of an unconditional & a conditional reduction. We do not vectorise this in-loop as neither of the
65012fb133eSKerry McLaughlin; incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx).
65112fb133eSKerry McLaughlin;
65212fb133eSKerry McLaughlindefine i32 @uncond_cond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 %N) #0 {
65312fb133eSKerry McLaughlin; CHECK-LABEL: @uncond_cond(
65412fb133eSKerry McLaughlin; CHECK:       pred.load.continue7:
655*872f7000SDávid Bolvanský; CHECK-NOT:     @llvm.vector.reduce.add
65612fb133eSKerry McLaughlin; CHECK:       middle.block:
657*872f7000SDávid Bolvanský; CHECK:         @llvm.vector.reduce.add
658*872f7000SDávid Bolvanský; CHECK:       scalar.ph
65912fb133eSKerry McLaughlinentry:
66012fb133eSKerry McLaughlin  br label %for.body
66112fb133eSKerry McLaughlin
66212fb133eSKerry McLaughlinfor.body:
66312fb133eSKerry McLaughlin  %rdx = phi i32 [ %res, %for.inc ], [ 0, %entry ]
66412fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]
66512fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %src1, i64 %iv
66612fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
66712fb133eSKerry McLaughlin  %add1 = add nsw i32 %0, %rdx
66812fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %cond, i64 %iv
66912fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
67012fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %1, 0
67112fb133eSKerry McLaughlin  br i1 %tobool.not, label %for.inc, label %if.then
67212fb133eSKerry McLaughlin
67312fb133eSKerry McLaughlinif.then:
67412fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src2, i64 %iv
67512fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
67612fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %add1
67712fb133eSKerry McLaughlin  br label %for.inc
67812fb133eSKerry McLaughlin
67912fb133eSKerry McLaughlinfor.inc:
68012fb133eSKerry McLaughlin  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
68112fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
68212fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
68312fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
68412fb133eSKerry McLaughlin
68512fb133eSKerry McLaughlinfor.end:
68612fb133eSKerry McLaughlin  ret i32 %res
68712fb133eSKerry McLaughlin}
68812fb133eSKerry McLaughlin
68912fb133eSKerry McLaughlin;
69012fb133eSKerry McLaughlin; Chain of multiple unconditional & conditional reductions. Does not vectorise in-loop as when we look back
69112fb133eSKerry McLaughlin; through the chain and check the number of uses of %add1, we find more than the expected one use.
69212fb133eSKerry McLaughlin;
69312fb133eSKerry McLaughlindefine i32 @uncond_cond_uncond(i32* noalias %src1, i32* noalias %src2, i32* noalias %cond, i64 noundef %N) {
69412fb133eSKerry McLaughlin; CHECK-LABEL: @uncond_cond_uncond(
69512fb133eSKerry McLaughlin; CHECK:       pred.load.continue7:
696*872f7000SDávid Bolvanský; CHECK-NOT:     @llvm.vector.reduce.add
69712fb133eSKerry McLaughlin; CHECK:       middle.block:
698*872f7000SDávid Bolvanský; CHECK:         @llvm.vector.reduce.add
699*872f7000SDávid Bolvanský; CHECK:       scalar.ph
70012fb133eSKerry McLaughlinentry:
70112fb133eSKerry McLaughlin  br label %for.body
70212fb133eSKerry McLaughlin
70312fb133eSKerry McLaughlinfor.body:
70412fb133eSKerry McLaughlin  %rdx = phi i32 [ %add3, %if.end ], [ 0, %entry ]
70512fb133eSKerry McLaughlin  %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry ]
70612fb133eSKerry McLaughlin  %arrayidx = getelementptr inbounds i32, i32* %src1, i64 %iv
70712fb133eSKerry McLaughlin  %0 = load i32, i32* %arrayidx
70812fb133eSKerry McLaughlin  %add1 = add nsw i32 %0, %rdx
70912fb133eSKerry McLaughlin  %arrayidx1 = getelementptr inbounds i32, i32* %cond, i64 %iv
71012fb133eSKerry McLaughlin  %1 = load i32, i32* %arrayidx1
71112fb133eSKerry McLaughlin  %tobool.not = icmp eq i32 %1, 0
71212fb133eSKerry McLaughlin  br i1 %tobool.not, label %if.end, label %if.then
71312fb133eSKerry McLaughlin
71412fb133eSKerry McLaughlinif.then:
71512fb133eSKerry McLaughlin  %arrayidx2 = getelementptr inbounds i32, i32* %src2, i64 %iv
71612fb133eSKerry McLaughlin  %2 = load i32, i32* %arrayidx2
71712fb133eSKerry McLaughlin  %add2 = add nsw i32 %2, %add1
71812fb133eSKerry McLaughlin  br label %if.end
71912fb133eSKerry McLaughlin
72012fb133eSKerry McLaughlinif.end:
72112fb133eSKerry McLaughlin  %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]
72212fb133eSKerry McLaughlin  %add3 = add nsw i32 %res, %0
72312fb133eSKerry McLaughlin  %iv.next = add nuw nsw i64 %iv, 1
72412fb133eSKerry McLaughlin  %exitcond.not = icmp eq i64 %iv.next, %N
72512fb133eSKerry McLaughlin  br i1 %exitcond.not, label %for.end, label %for.body
72612fb133eSKerry McLaughlin
72712fb133eSKerry McLaughlinfor.end:
72812fb133eSKerry McLaughlin  ret i32 %add3
72912fb133eSKerry McLaughlin}
730