diff options
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineSelect.cpp | 11 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 23 | ||||
-rw-r--r-- | test/Transforms/InstCombine/vec_demanded_elts.ll | 19 |
3 files changed, 53 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index eb9945b681..bdd97a862b 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -899,5 +899,16 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return &SI; } + if (VectorType* VecTy = dyn_cast<VectorType>(SI.getType())) { + unsigned VWidth = VecTy->getNumElements(); + APInt UndefElts(VWidth, 0); + APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth)); + if (Value *V = SimplifyDemandedVectorElts(&SI, AllOnesEltMask, UndefElts)) { + if (V != &SI) + return ReplaceInstUsesWith(SI, V); + return &SI; + } + } + return 0; } diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 46ba83b651..54be8ed3fa 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -989,6 +989,29 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, } break; } + case Instruction::Select: { + APInt LeftDemanded(DemandedElts), RightDemanded(DemandedElts); + if (ConstantVector* CV = dyn_cast<ConstantVector>(I->getOperand(0))) { + for (unsigned i = 0; i < VWidth; i++) { + if (CV->getAggregateElement(i)->isNullValue()) + LeftDemanded.clearBit(i); + else + RightDemanded.clearBit(i); + } + } + + TmpV = SimplifyDemandedVectorElts(I->getOperand(1), LeftDemanded, + UndefElts, Depth+1); + if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; } + + TmpV = SimplifyDemandedVectorElts(I->getOperand(2), RightDemanded, + UndefElts2, Depth+1); + if (TmpV) { I->setOperand(2, TmpV); MadeChange = true; } + + // Output elements are undefined if both are undefined. + UndefElts &= UndefElts2; + break; + } case Instruction::BitCast: { // Vector->vector casts only. VectorType *VTy = dyn_cast<VectorType>(I->getOperand(0)->getType()); diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll index d904196d13..0019a57627 100644 --- a/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -190,4 +190,23 @@ define <2 x double> @test_fpext(float %f) { ret <2 x double> %ret } +define <4 x float> @test_select(float %f, float %g) { +; CHECK: @test_select +; CHECK: %a0 = insertelement <4 x float> undef, float %f, i32 0 +; CHECK-NOT: insertelement +; CHECK: %a3 = insertelement <4 x float> %a0, float 3.000000e+00, i32 3 +; CHECK-NOT: insertelement +; CHECK: %ret = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x float> %a3, <4 x float> <float undef, float 4.000000e+00, float 5.000000e+00, float undef> + %a0 = insertelement <4 x float> undef, float %f, i32 0 + %a1 = insertelement <4 x float> %a0, float 1.000000e+00, i32 1 + %a2 = insertelement <4 x float> %a1, float 2.000000e+00, i32 2 + %a3 = insertelement <4 x float> %a2, float 3.000000e+00, i32 3 + %b0 = insertelement <4 x float> undef, float %g, i32 0 + %b1 = insertelement <4 x float> %b0, float 4.000000e+00, i32 1 + %b2 = insertelement <4 x float> %b1, float 5.000000e+00, i32 2 + %b3 = insertelement <4 x float> %b2, float 6.000000e+00, i32 3 + %ret = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x float> %a3, <4 x float> %b3 + ret <4 x float> %ret +} + |