1*2e14900dSBjorn Pettersson; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK-VF4IC1 --check-prefix=CHECK 2*2e14900dSBjorn Pettersson; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK-VF4IC4 --check-prefix=CHECK 3*2e14900dSBjorn Pettersson; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=1 -S < %s | FileCheck %s --check-prefix=CHECK-VF1IC4 --check-prefix=CHECK 426b7d9d6SDavid Sherwood 526b7d9d6SDavid Sherwooddefine i32 @select_const_i32_from_icmp(i32* nocapture readonly %v, i64 %n) { 626b7d9d6SDavid Sherwood; CHECK-LABEL: @select_const_i32_from_icmp 726b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 826b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 926b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 1026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 1126b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 1226b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 1326b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 3, i32 3, i32 3, i32 3> 1426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 1526b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 1626b7d9d6SDavid Sherwood 1726b7d9d6SDavid Sherwood; CHECK-VF4IC4: vector.body: 1826b7d9d6SDavid Sherwood; CHECK-VF4IC4: [[VEC_PHI1:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL1:%.*]], %vector.body ] 1926b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_PHI2:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL2:%.*]], %vector.body ] 2026b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_PHI3:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL3:%.*]], %vector.body ] 2126b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_PHI4:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL4:%.*]], %vector.body ] 2226b7d9d6SDavid Sherwood; CHECK-VF4IC4: [[VEC_ICMP1:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 2326b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP2:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 2426b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP3:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 2526b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp eq <4 x i32> {{.*}}, <i32 3, i32 3, i32 3, i32 3> 2626b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL1:%.*]] = select <4 x i1> [[VEC_ICMP1]], <4 x i32> [[VEC_PHI1]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 2726b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL2:%.*]] = select <4 x i1> [[VEC_ICMP2]], <4 x i32> [[VEC_PHI2]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 2826b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL3:%.*]] = select <4 x i1> [[VEC_ICMP3]], <4 x i32> [[VEC_PHI3]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 2926b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL4:%.*]] = select <4 x i1> [[VEC_ICMP4]], <4 x i32> [[VEC_PHI4]], <4 x i32> <i32 7, i32 7, i32 7, i32 7> 3026b7d9d6SDavid Sherwood; CHECK-VF4IC4: middle.block: 3126b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP5:%.*]] = icmp ne <4 x i32> [[VEC_SEL1]], <i32 3, i32 3, i32 3, i32 3> 3226b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL5:%.*]] = select <4 x i1> [[VEC_ICMP5]], <4 x i32> [[VEC_SEL1]], <4 x i32> [[VEC_SEL2]] 3326b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP6:%.*]] = icmp ne <4 x i32> [[VEC_SEL5]], <i32 3, i32 3, i32 3, i32 3> 3426b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL6:%.*]] = select <4 x i1> [[VEC_ICMP6]], <4 x i32> [[VEC_SEL5]], <4 x i32> [[VEC_SEL3]] 3526b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_ICMP7:%.*]] = icmp ne <4 x i32> [[VEC_SEL6]], <i32 3, i32 3, i32 3, i32 3> 3626b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[VEC_SEL_FIN:%.*]] = select <4 x i1> [[VEC_ICMP7]], <4 x i32> [[VEC_SEL6]], <4 x i32> [[VEC_SEL4]] 3726b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL_FIN]], <i32 3, i32 3, i32 3, i32 3> 3826b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 3926b7d9d6SDavid Sherwood; CHECK-VF4IC4-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 4026b7d9d6SDavid Sherwood 4126b7d9d6SDavid Sherwood 4226b7d9d6SDavid Sherwood; CHECK-VF1IC4: vector.body: 4326b7d9d6SDavid Sherwood; CHECK-VF1IC4: [[VEC_PHI1:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL1:%.*]], %vector.body ] 4426b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_PHI2:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL2:%.*]], %vector.body ] 4526b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_PHI3:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL3:%.*]], %vector.body ] 4626b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_PHI4:%.*]] = phi i32 [ 3, %vector.ph ], [ [[VEC_SEL4:%.*]], %vector.body ] 4726b7d9d6SDavid Sherwood; CHECK-VF1IC4: [[VEC_LOAD1:%.*]] = load i32 4826b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_LOAD2:%.*]] = load i32 4926b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_LOAD3:%.*]] = load i32 5026b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_LOAD4:%.*]] = load i32 5126b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP1:%.*]] = icmp eq i32 [[VEC_LOAD1]], 3 5226b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP2:%.*]] = icmp eq i32 [[VEC_LOAD2]], 3 5326b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP3:%.*]] = icmp eq i32 [[VEC_LOAD3]], 3 5426b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp eq i32 [[VEC_LOAD4]], 3 5526b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL1]] = select i1 [[VEC_ICMP1]], i32 [[VEC_PHI1]], i32 7 5626b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL2]] = select i1 [[VEC_ICMP2]], i32 [[VEC_PHI2]], i32 7 5726b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL3]] = select i1 [[VEC_ICMP3]], i32 [[VEC_PHI3]], i32 7 5826b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL4]] = select i1 [[VEC_ICMP4]], i32 [[VEC_PHI4]], i32 7 5926b7d9d6SDavid Sherwood; CHECK-VF1IC4: middle.block: 6026b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP4:%.*]] = icmp ne i32 [[VEC_SEL1]], 3 6126b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL5:%.*]] = select i1 [[VEC_ICMP4]], i32 [[VEC_SEL1]], i32 [[VEC_SEL2]] 6226b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP5:%.*]] = icmp ne i32 [[VEC_SEL5]], 3 6326b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_SEL6:%.*]] = select i1 [[VEC_ICMP5]], i32 [[VEC_SEL5]], i32 [[VEC_SEL3]] 6426b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: [[VEC_ICMP6:%.*]] = icmp ne i32 [[VEC_SEL6]], 3 6526b7d9d6SDavid Sherwood; CHECK-VF1IC4-NEXT: {{.*}} = select i1 [[VEC_ICMP6]], i32 [[VEC_SEL6]], i32 [[VEC_SEL4]] 6626b7d9d6SDavid Sherwood 6726b7d9d6SDavid Sherwoodentry: 6826b7d9d6SDavid Sherwood br label %for.body 6926b7d9d6SDavid Sherwood 7026b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 7126b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 7226b7d9d6SDavid Sherwood %1 = phi i32 [ 3, %entry ], [ %5, %for.body ] 7326b7d9d6SDavid Sherwood %2 = getelementptr inbounds i32, i32* %v, i64 %0 7426b7d9d6SDavid Sherwood %3 = load i32, i32* %2, align 4 7526b7d9d6SDavid Sherwood %4 = icmp eq i32 %3, 3 7626b7d9d6SDavid Sherwood %5 = select i1 %4, i32 %1, i32 7 7726b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 7826b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 7926b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 8026b7d9d6SDavid Sherwood 8126b7d9d6SDavid Sherwoodexit: ; preds = %for.body 8226b7d9d6SDavid Sherwood ret i32 %5 8326b7d9d6SDavid Sherwood} 8426b7d9d6SDavid Sherwood 8526b7d9d6SDavid Sherwood 8626b7d9d6SDavid Sherwooddefine i32 @select_const_i32_from_icmp2(i32* nocapture readonly %v, i64 %n) { 8726b7d9d6SDavid Sherwood; CHECK-LABEL: @select_const_i32_from_icmp2 8826b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 8926b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 3, i32 3, i32 3, i32 3>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 9026b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 9126b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 9226b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> <i32 7, i32 7, i32 7, i32 7>, <4 x i32> [[VEC_PHI]] 9326b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 9426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 3, i32 3, i32 3, i32 3> 9526b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 9626b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3 9726b7d9d6SDavid Sherwood 9826b7d9d6SDavid Sherwoodentry: 9926b7d9d6SDavid Sherwood br label %for.body 10026b7d9d6SDavid Sherwood 10126b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 10226b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 10326b7d9d6SDavid Sherwood %1 = phi i32 [ 3, %entry ], [ %5, %for.body ] 10426b7d9d6SDavid Sherwood %2 = getelementptr inbounds i32, i32* %v, i64 %0 10526b7d9d6SDavid Sherwood %3 = load i32, i32* %2, align 4 10626b7d9d6SDavid Sherwood %4 = icmp eq i32 %3, 3 10726b7d9d6SDavid Sherwood %5 = select i1 %4, i32 7, i32 %1 10826b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 10926b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 11026b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 11126b7d9d6SDavid Sherwood 11226b7d9d6SDavid Sherwoodexit: ; preds = %for.body 11326b7d9d6SDavid Sherwood ret i32 %5 11426b7d9d6SDavid Sherwood} 11526b7d9d6SDavid Sherwood 11626b7d9d6SDavid Sherwood 11726b7d9d6SDavid Sherwooddefine i32 @select_i32_from_icmp(i32* nocapture readonly %v, i32 %a, i32 %b, i64 %n) { 11826b7d9d6SDavid Sherwood; CHECK-LABEL: @select_i32_from_icmp 11926b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.ph: 12026b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 12126b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[SPLAT_OF_A:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer 12226b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 12326b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[SPLAT_OF_B:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <4 x i32> zeroinitializer 12426b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 12526b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[SPLAT_OF_A]], %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 12626b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x i32> 12726b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_LOAD]], <i32 3, i32 3, i32 3, i32 3> 12826b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> [[SPLAT_OF_B]] 12926b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 13026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_INS:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 13126b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_SPLAT:%.*]] = shufflevector <4 x i32> [[FIN_INS]], <4 x i32> poison, <4 x i32> zeroinitializer 13226b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_CMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], [[FIN_SPLAT]] 13326b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_CMP]]) 13426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 %b, i32 %a 13526b7d9d6SDavid Sherwoodentry: 13626b7d9d6SDavid Sherwood br label %for.body 13726b7d9d6SDavid Sherwood 13826b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 13926b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 14026b7d9d6SDavid Sherwood %1 = phi i32 [ %a, %entry ], [ %5, %for.body ] 14126b7d9d6SDavid Sherwood %2 = getelementptr inbounds i32, i32* %v, i64 %0 14226b7d9d6SDavid Sherwood %3 = load i32, i32* %2, align 4 14326b7d9d6SDavid Sherwood %4 = icmp eq i32 %3, 3 14426b7d9d6SDavid Sherwood %5 = select i1 %4, i32 %1, i32 %b 14526b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 14626b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 14726b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 14826b7d9d6SDavid Sherwood 14926b7d9d6SDavid Sherwoodexit: ; preds = %for.body 15026b7d9d6SDavid Sherwood ret i32 %5 15126b7d9d6SDavid Sherwood} 15226b7d9d6SDavid Sherwood 15326b7d9d6SDavid Sherwood 15426b7d9d6SDavid Sherwooddefine i32 @select_const_i32_from_fcmp_fast(float* nocapture readonly %v, i64 %n) { 15526b7d9d6SDavid Sherwood; CHECK-LABEL: @select_const_i32_from_fcmp_fast 15626b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 15726b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 2, i32 2, i32 2, i32 2>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 15826b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x float> 15926b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_FCMP:%.*]] = fcmp fast ueq <4 x float> [[VEC_LOAD]], <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> 16026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_FCMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> 16126b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 16226b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 2, i32 2, i32 2, i32 2> 16326b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 16426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 1, i32 2 16526b7d9d6SDavid Sherwoodentry: 16626b7d9d6SDavid Sherwood br label %for.body 16726b7d9d6SDavid Sherwood 16826b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 16926b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 17026b7d9d6SDavid Sherwood %1 = phi i32 [ 2, %entry ], [ %5, %for.body ] 17126b7d9d6SDavid Sherwood %2 = getelementptr inbounds float, float* %v, i64 %0 17226b7d9d6SDavid Sherwood %3 = load float, float* %2, align 4 17326b7d9d6SDavid Sherwood %4 = fcmp fast ueq float %3, 3.0 17426b7d9d6SDavid Sherwood %5 = select i1 %4, i32 %1, i32 1 17526b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 17626b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 17726b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 17826b7d9d6SDavid Sherwood 17926b7d9d6SDavid Sherwoodexit: ; preds = %for.body 18026b7d9d6SDavid Sherwood ret i32 %5 18126b7d9d6SDavid Sherwood} 18226b7d9d6SDavid Sherwood 18326b7d9d6SDavid Sherwood 18426b7d9d6SDavid Sherwooddefine i32 @select_const_i32_from_fcmp(float* nocapture readonly %v, i64 %n) { 18526b7d9d6SDavid Sherwood; CHECK-LABEL: @select_const_i32_from_fcmp 18626b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 18726b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 2, i32 2, i32 2, i32 2>, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 18826b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <4 x float> 18926b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_FCMP:%.*]] = fcmp ueq <4 x float> [[VEC_LOAD]], <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> 19026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_FCMP]], <4 x i32> [[VEC_PHI]], <4 x i32> <i32 1, i32 1, i32 1, i32 1> 19126b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 19226b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], <i32 2, i32 2, i32 2, i32 2> 19326b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_ICMP]]) 19426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 1, i32 2 19526b7d9d6SDavid Sherwoodentry: 19626b7d9d6SDavid Sherwood br label %for.body 19726b7d9d6SDavid Sherwood 19826b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 19926b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 20026b7d9d6SDavid Sherwood %1 = phi i32 [ 2, %entry ], [ %5, %for.body ] 20126b7d9d6SDavid Sherwood %2 = getelementptr inbounds float, float* %v, i64 %0 20226b7d9d6SDavid Sherwood %3 = load float, float* %2, align 4 20326b7d9d6SDavid Sherwood %4 = fcmp ueq float %3, 3.0 20426b7d9d6SDavid Sherwood %5 = select i1 %4, i32 %1, i32 1 20526b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 20626b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 20726b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 20826b7d9d6SDavid Sherwood 20926b7d9d6SDavid Sherwoodexit: ; preds = %for.body 21026b7d9d6SDavid Sherwood ret i32 %5 21126b7d9d6SDavid Sherwood} 21226b7d9d6SDavid Sherwood 21326b7d9d6SDavid Sherwood 21426b7d9d6SDavid Sherwooddefine i32 @select_i32_from_icmp_same_inputs(i32 %a, i32 %b, i64 %n) { 21526b7d9d6SDavid Sherwood; CHECK-LABEL: @select_i32_from_icmp_same_inputs 21626b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.ph: 21726b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 21826b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[SPLAT_OF_A:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer 21926b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> poison, i32 %b, i32 0 22026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[SPLAT_OF_B:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <4 x i32> zeroinitializer 22126b7d9d6SDavid Sherwood; CHECK-VF4IC1: vector.body: 22226b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[SPLAT_OF_A]], %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ] 22326b7d9d6SDavid Sherwood; CHECK-VF4IC1: [[VEC_ICMP:%.*]] = icmp eq <4 x i32> [[VEC_PHI]], <i32 3, i32 3, i32 3, i32 3> 22426b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <4 x i1> [[VEC_ICMP]], <4 x i32> [[VEC_PHI]], <4 x i32> [[SPLAT_OF_B]] 22526b7d9d6SDavid Sherwood; CHECK-VF4IC1: middle.block: 22626b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_INS:%.*]] = insertelement <4 x i32> poison, i32 %a, i32 0 22726b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_SPLAT:%.*]] = shufflevector <4 x i32> [[FIN_INS]], <4 x i32> poison, <4 x i32> zeroinitializer 22826b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[FIN_CMP:%.*]] = icmp ne <4 x i32> [[VEC_SEL]], [[FIN_SPLAT]] 22926b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FIN_CMP]]) 23026b7d9d6SDavid Sherwood; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 %b, i32 %a 23126b7d9d6SDavid Sherwoodentry: 23226b7d9d6SDavid Sherwood br label %for.body 23326b7d9d6SDavid Sherwood 23426b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 23526b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %4, %for.body ] 23626b7d9d6SDavid Sherwood %1 = phi i32 [ %a, %entry ], [ %3, %for.body ] 23726b7d9d6SDavid Sherwood %2 = icmp eq i32 %1, 3 23826b7d9d6SDavid Sherwood %3 = select i1 %2, i32 %1, i32 %b 23926b7d9d6SDavid Sherwood %4 = add nuw nsw i64 %0, 1 24026b7d9d6SDavid Sherwood %5 = icmp eq i64 %4, %n 24126b7d9d6SDavid Sherwood br i1 %5, label %exit, label %for.body 24226b7d9d6SDavid Sherwood 24326b7d9d6SDavid Sherwoodexit: ; preds = %for.body 24426b7d9d6SDavid Sherwood ret i32 %3 24526b7d9d6SDavid Sherwood} 24626b7d9d6SDavid Sherwood 24726b7d9d6SDavid Sherwood 24826b7d9d6SDavid Sherwood; Negative tests 24926b7d9d6SDavid Sherwood 25026b7d9d6SDavid Sherwood; We don't support FP reduction variables at the moment. 25126b7d9d6SDavid Sherwooddefine float @select_const_f32_from_icmp(i32* nocapture readonly %v, i64 %n) { 25226b7d9d6SDavid Sherwood; CHECK: @select_const_f32_from_icmp 25326b7d9d6SDavid Sherwood; CHECK-NOT: vector.body 25426b7d9d6SDavid Sherwoodentry: 25526b7d9d6SDavid Sherwood br label %for.body 25626b7d9d6SDavid Sherwood 25726b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 25826b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %6, %for.body ] 25926b7d9d6SDavid Sherwood %1 = phi fast float [ 3.0, %entry ], [ %5, %for.body ] 26026b7d9d6SDavid Sherwood %2 = getelementptr inbounds i32, i32* %v, i64 %0 26126b7d9d6SDavid Sherwood %3 = load i32, i32* %2, align 4 26226b7d9d6SDavid Sherwood %4 = icmp eq i32 %3, 3 26326b7d9d6SDavid Sherwood %5 = select fast i1 %4, float %1, float 7.0 26426b7d9d6SDavid Sherwood %6 = add nuw nsw i64 %0, 1 26526b7d9d6SDavid Sherwood %7 = icmp eq i64 %6, %n 26626b7d9d6SDavid Sherwood br i1 %7, label %exit, label %for.body 26726b7d9d6SDavid Sherwood 26826b7d9d6SDavid Sherwoodexit: ; preds = %for.body 26926b7d9d6SDavid Sherwood ret float %5 27026b7d9d6SDavid Sherwood} 27126b7d9d6SDavid Sherwood 27226b7d9d6SDavid Sherwood 27326b7d9d6SDavid Sherwood; We don't support select/cmp reduction patterns where there is more than one 27426b7d9d6SDavid Sherwood; use of the icmp/fcmp. 27526b7d9d6SDavid Sherwooddefine i32 @select_const_i32_from_icmp_mul_use(i32* nocapture readonly %v1, i32* %v2, i64 %n) { 27626b7d9d6SDavid Sherwood; CHECK-LABEL: @select_const_i32_from_icmp_mul_use 27726b7d9d6SDavid Sherwood; CHECK-NOT: vector.body 27826b7d9d6SDavid Sherwoodentry: 27926b7d9d6SDavid Sherwood br label %for.body 28026b7d9d6SDavid Sherwood 28126b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 28226b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %8, %for.body ] 28326b7d9d6SDavid Sherwood %1 = phi i32 [ 3, %entry ], [ %6, %for.body ] 28426b7d9d6SDavid Sherwood %2 = phi i32 [ 0, %entry ], [ %7, %for.body ] 28526b7d9d6SDavid Sherwood %3 = getelementptr inbounds i32, i32* %v1, i64 %0 28626b7d9d6SDavid Sherwood %4 = load i32, i32* %3, align 4 28726b7d9d6SDavid Sherwood %5 = icmp eq i32 %4, 3 28826b7d9d6SDavid Sherwood %6 = select i1 %5, i32 %1, i32 7 28926b7d9d6SDavid Sherwood %7 = zext i1 %5 to i32 29026b7d9d6SDavid Sherwood %8 = add nuw nsw i64 %0, 1 29126b7d9d6SDavid Sherwood %9 = icmp eq i64 %8, %n 29226b7d9d6SDavid Sherwood br i1 %9, label %exit, label %for.body 29326b7d9d6SDavid Sherwood 29426b7d9d6SDavid Sherwoodexit: ; preds = %for.body 29526b7d9d6SDavid Sherwood store i32 %7, i32* %v2, align 4 29626b7d9d6SDavid Sherwood ret i32 %6 29726b7d9d6SDavid Sherwood} 29826b7d9d6SDavid Sherwood 29926b7d9d6SDavid Sherwood 30026b7d9d6SDavid Sherwood; We don't support selecting loop-variant values. 30126b7d9d6SDavid Sherwooddefine i32 @select_variant_i32_from_icmp(i32* nocapture readonly %v1, i32* nocapture readonly %v2, i64 %n) { 30226b7d9d6SDavid Sherwood; CHECK-LABEL: @select_variant_i32_from_icmp 30326b7d9d6SDavid Sherwood; CHECK-NOT: vector.body 30426b7d9d6SDavid Sherwoodentry: 30526b7d9d6SDavid Sherwood br label %for.body 30626b7d9d6SDavid Sherwood 30726b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 30826b7d9d6SDavid Sherwood %0 = phi i64 [ 0, %entry ], [ %8, %for.body ] 30926b7d9d6SDavid Sherwood %1 = phi i32 [ 3, %entry ], [ %7, %for.body ] 31026b7d9d6SDavid Sherwood %2 = getelementptr inbounds i32, i32* %v1, i64 %0 31126b7d9d6SDavid Sherwood %3 = load i32, i32* %2, align 4 31226b7d9d6SDavid Sherwood %4 = getelementptr inbounds i32, i32* %v2, i64 %0 31326b7d9d6SDavid Sherwood %5 = load i32, i32* %4, align 4 31426b7d9d6SDavid Sherwood %6 = icmp eq i32 %3, 3 31526b7d9d6SDavid Sherwood %7 = select i1 %6, i32 %1, i32 %5 31626b7d9d6SDavid Sherwood %8 = add nuw nsw i64 %0, 1 31726b7d9d6SDavid Sherwood %9 = icmp eq i64 %8, %n 31826b7d9d6SDavid Sherwood br i1 %9, label %exit, label %for.body 31926b7d9d6SDavid Sherwood 32026b7d9d6SDavid Sherwoodexit: ; preds = %for.body 32126b7d9d6SDavid Sherwood ret i32 %7 32226b7d9d6SDavid Sherwood} 32326b7d9d6SDavid Sherwood 32426b7d9d6SDavid Sherwood 32526b7d9d6SDavid Sherwood; We only support selects where the input comes from the same PHI as the 32626b7d9d6SDavid Sherwood; reduction PHI. In the example below, the select uses the induction 32726b7d9d6SDavid Sherwood; variable input and the icmp uses the reduction PHI. 32826b7d9d6SDavid Sherwooddefine i32 @select_i32_from_icmp_non_redux_phi(i32 %a, i32 %b, i32 %n) { 32926b7d9d6SDavid Sherwood; CHECK-LABEL: @select_i32_from_icmp_non_redux_phi 33026b7d9d6SDavid Sherwood; CHECK-NOT: vector.body 33126b7d9d6SDavid Sherwoodentry: 33226b7d9d6SDavid Sherwood br label %for.body 33326b7d9d6SDavid Sherwood 33426b7d9d6SDavid Sherwoodfor.body: ; preds = %entry, %for.body 33526b7d9d6SDavid Sherwood %0 = phi i32 [ 0, %entry ], [ %4, %for.body ] 33626b7d9d6SDavid Sherwood %1 = phi i32 [ %a, %entry ], [ %3, %for.body ] 33726b7d9d6SDavid Sherwood %2 = icmp eq i32 %1, 3 33826b7d9d6SDavid Sherwood %3 = select i1 %2, i32 %0, i32 %b 33926b7d9d6SDavid Sherwood %4 = add nuw nsw i32 %0, 1 34026b7d9d6SDavid Sherwood %5 = icmp eq i32 %4, %n 34126b7d9d6SDavid Sherwood br i1 %5, label %exit, label %for.body 34226b7d9d6SDavid Sherwood 34326b7d9d6SDavid Sherwoodexit: ; preds = %for.body 34426b7d9d6SDavid Sherwood ret i32 %3 34526b7d9d6SDavid Sherwood} 346