Index: include/llvm/Analysis/ConstantFolding.h =================================================================== --- include/llvm/Analysis/ConstantFolding.h +++ include/llvm/Analysis/ConstantFolding.h @@ -79,6 +79,12 @@ Constant *ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL); +/// \brief Attempt to constant fold a select instruction with the specified +/// operands. The constant result is returned if successful; if not, null is +/// returned. +Constant *ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, + Constant *V2); + /// \brief Attempt to constant fold a cast with the specified operand. If it /// fails, it returns a constant expression of the specified operand. Constant *ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3580,6 +3580,9 @@ // select true, X, Y -> X // select false, X, Y -> Y if (Constant *CB = dyn_cast(CondVal)) { + if (Constant *CT = dyn_cast(TrueVal)) + if (Constant *CF = dyn_cast(FalseVal)) + return ConstantFoldSelectInstruction(CB, CT, CF); if (CB->isAllOnesValue()) return TrueVal; if (CB->isNullValue()) Index: test/Transforms/InstSimplify/select.ll =================================================================== --- test/Transforms/InstSimplify/select.ll +++ test/Transforms/InstSimplify/select.ll @@ -17,6 +17,14 @@ ret <2 x i8> %s } +define <2 x i8> @vsel_mixedvec() { +; CHECK-LABEL: @vsel_mixedvec( +; CHECK-NEXT: ret <2 x i8> +; + %s = select <2 x i1>, <2 x i8> , <2 x i8> + ret <2 x i8> %s +} + define i32 @test1(i32 %x) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: ret i32 %x