diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4014,6 +4014,34 @@ if (isa(FalseVal)) // select ?, X, undef -> X return TrueVal; + // Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC'' + Constant *TrueC, *FalseC; + if (TrueVal->getType()->isVectorTy() && match(TrueVal, m_Constant(TrueC)) && + match(FalseVal, m_Constant(FalseC))) { + unsigned NumElts = TrueC->getType()->getVectorNumElements(); + SmallVector NewC; + for (unsigned i = 0; i != NumElts; ++i) { + // Bail out on incomplete vector constants. + Constant *TEltC = TrueC->getAggregateElement(i); + Constant *FEltC = FalseC->getAggregateElement(i); + if (!TEltC || !FEltC) + break; + + // If the elements match (undef or not), that value is the result. If only + // one element is undef, choose the defined element as the safe result. + if (TEltC == FEltC) + NewC.push_back(TEltC); + else if (isa(TEltC)) + NewC.push_back(FEltC); + else if (isa(FEltC)) + NewC.push_back(TEltC); + else + break; + } + if (NewC.size() == NumElts) + return ConstantVector::get(NewC); + } + if (Value *V = simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse)) return V; diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll --- a/llvm/test/Transforms/InstSimplify/select.ll +++ b/llvm/test/Transforms/InstSimplify/select.ll @@ -59,8 +59,7 @@ define <2 x i32> @equal_arms_vec_undef(<2 x i1> %cond) { ; CHECK-LABEL: @equal_arms_vec_undef( -; CHECK-NEXT: [[V:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> , <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[V]] +; CHECK-NEXT: ret <2 x i32> ; %V = select <2 x i1> %cond, <2 x i32> , <2 x i32> ret <2 x i32> %V @@ -68,8 +67,7 @@ define <3 x float> @equal_arms_vec_less_undef(<3 x i1> %cond) { ; CHECK-LABEL: @equal_arms_vec_less_undef( -; CHECK-NEXT: [[V:%.*]] = select <3 x i1> [[COND:%.*]], <3 x float> , <3 x float> -; CHECK-NEXT: ret <3 x float> [[V]] +; CHECK-NEXT: ret <3 x float> ; %V = select <3 x i1> %cond, <3 x float> , <3 x float> ret <3 x float> %V @@ -77,8 +75,7 @@ define <3 x float> @equal_arms_vec_more_undef(<3 x i1> %cond) { ; CHECK-LABEL: @equal_arms_vec_more_undef( -; CHECK-NEXT: [[V:%.*]] = select <3 x i1> [[COND:%.*]], <3 x float> , <3 x float> -; CHECK-NEXT: ret <3 x float> [[V]] +; CHECK-NEXT: ret <3 x float> ; %V = select <3 x i1> %cond, <3 x float> , <3 x float> ret <3 x float> %V