Index: lib/Transforms/InstCombine/InstCombineVectorOps.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -365,6 +365,21 @@ Worklist.AddValue(EE); return CastInst::Create(CI->getOpcode(), EE, EI.getType()); } + } else if (CmpInst *CI = dyn_cast(I)) { + if (CI->hasOneUse() && + cheapToScalarize(CI, isa(EI.getOperand(1)))) { + Value *newEI0 = + Builder.CreateExtractElement(CI->getOperand(0), EI.getOperand(1), + EI.getName()+".lhs"); + Value *newEI1 = + Builder.CreateExtractElement(CI->getOperand(1), EI.getOperand(1), + EI.getName()+".rhs"); + + return CmpInst::Create( + CI->getOpcode(), + CI->getPredicate(), + newEI0, newEI1, CI->getName()); + } } } return nullptr; Index: test/Transforms/InstCombine/scalarization.ll =================================================================== --- test/Transforms/InstCombine/scalarization.ll +++ test/Transforms/InstCombine/scalarization.ll @@ -84,3 +84,46 @@ ret float %r } +define i1 @extractelt_vector_icmp_constrhs(<2 x i32> %arg) { +; CHECK-LABEL: @extractelt_vector_icmp_constrhs( +; CHECK-NEXT: [[EXT_LHS:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i32 0 +; CHECK-NEXT: [[EXT:%.*]] = icmp eq i32 [[EXT_LHS]], 0 +; CHECK-NEXT: ret i1 [[EXT]] +; + %cmp = icmp eq <2 x i32> %arg, zeroinitializer + %ext = extractelement <2 x i1> %cmp, i32 0 + ret i1 %ext +} + +define i1 @extractelt_vector_fcmp_constrhs(<2 x float> %arg) { +; CHECK-LABEL: @extractelt_vector_fcmp_constrhs( +; CHECK-NEXT: [[EXT_LHS:%.*]] = extractelement <2 x float> [[ARG:%.*]], i32 0 +; CHECK-NEXT: [[EXT:%.*]] = fcmp oeq float [[EXT_LHS]], 0.000000e+00 +; CHECK-NEXT: ret i1 [[EXT]] +; + %cmp = fcmp oeq <2 x float> %arg, zeroinitializer + %ext = extractelement <2 x i1> %cmp, i32 0 + ret i1 %ext +} + +define i1 @extractelt_vector_icmp_constrhs_dynidx(<2 x i32> %arg, i32 %idx) { +; CHECK-LABEL: @extractelt_vector_icmp_constrhs_dynidx( +; CHECK-NEXT: [[EXT_LHS:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i32 [[IDX:%.*]] +; CHECK-NEXT: [[EXT:%.*]] = icmp eq i32 [[EXT_LHS]], 0 +; CHECK-NEXT: ret i1 [[EXT]] +; + %cmp = icmp eq <2 x i32> %arg, zeroinitializer + %ext = extractelement <2 x i1> %cmp, i32 %idx + ret i1 %ext +} + +define i1 @extractelt_vector_fcmp_constrhs_dynidx(<2 x float> %arg, i32 %idx) { +; CHECK-LABEL: @extractelt_vector_fcmp_constrhs_dynidx( +; CHECK-NEXT: [[EXT_LHS:%.*]] = extractelement <2 x float> [[ARG:%.*]], i32 [[IDX:%.*]] +; CHECK-NEXT: [[EXT:%.*]] = fcmp oeq float [[EXT_LHS]], 0.000000e+00 +; CHECK-NEXT: ret i1 [[EXT]] +; + %cmp = fcmp oeq <2 x float> %arg, zeroinitializer + %ext = extractelement <2 x i1> %cmp, i32 %idx + ret i1 %ext +}