Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4014,6 +4014,39 @@ if (isa(FalseVal)) // select ?, X, undef -> X return TrueVal; + // Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC'' + Constant *TrueC, *FalseC; + if (match(TrueVal, m_Constant(TrueC)) && + match(FalseVal, m_Constant(FalseC)) && + TrueC->isElementWiseEqual(FalseC)) { + assert(TrueC->getType()->isVectorTy() && FalseC->getType()->isVectorTy() && + "Expected vector constants"); + + 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)) { + assert(!isa(FEltC) && "Expected non-undef constant"); + NewC.push_back(FEltC); + } else { + assert(!isa(TEltC) && "Expected non-undef constant"); + NewC.push_back(TEltC); + } + } + if (NewC.size() == NumElts) + return ConstantVector::get(NewC); + } + if (Value *V = simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse)) return V; Index: llvm/test/Transforms/InstSimplify/select.ll =================================================================== --- llvm/test/Transforms/InstSimplify/select.ll +++ 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