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