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