diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index c7accb36862..57b6a4e05d1 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -1350,27 +1350,40 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, } } else if (const ConstantVector *CP1 = dyn_cast(C1)) { if (const ConstantVector *CP2 = dyn_cast(C2)) { - if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) { - for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { - Constant *C = ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, - CP1->getOperand(i), - CP2->getOperand(i)); - if (ConstantInt *CB = dyn_cast(C)) - return CB; + // If we can constant fold the comparison of each element, constant fold + // the whole vector comparison. + SmallVector Elts; + const Type *InEltTy = CP1->getOperand(0)->getType(); + bool isFP = InEltTy->isFloatingPoint(); + const Type *ResEltTy = InEltTy; + if (isFP) + ResEltTy = IntegerType::get(InEltTy->getPrimitiveSizeInBits()); + + for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { + // Compare the elements, producing an i1 result or constant expr. + Constant *C; + if (isFP) + C = ConstantExpr::getFCmp(pred, CP1->getOperand(i), + CP2->getOperand(i)); + else + C = ConstantExpr::getICmp(pred, CP1->getOperand(i), + CP2->getOperand(i)); + + // If it is a bool or undef result, convert to the dest type. + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->isZero()) + Elts.push_back(Constant::getNullValue(ResEltTy)); + else + Elts.push_back(Constant::getAllOnesValue(ResEltTy)); + } else if (isa(C)) { + Elts.push_back(UndefValue::get(ResEltTy)); + } else { + break; } - // Otherwise, could not decide from any element pairs. - return 0; - } else if (pred == ICmpInst::ICMP_EQ) { - for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { - Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ, - CP1->getOperand(i), - CP2->getOperand(i)); - if (ConstantInt *CB = dyn_cast(C)) - return CB; - } - // Otherwise, could not decide from any element pairs. - return 0; } + + if (Elts.size() == CP1->getNumOperands()) + return ConstantVector::get(&Elts[0], Elts.size()); } } diff --git a/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll b/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll index 35f034a9095..b42b0248496 100644 --- a/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll +++ b/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll @@ -6,9 +6,17 @@ entry: ret <4 x i32> %foo } -define <4 x i32> @main(i32 %argc, i8** %argv) { +define <4 x i32> @test2(i32 %argc, i8** %argv) { entry: %foo = vicmp slt <4 x i32> , ret <4 x i32> %foo } + + +define <4 x i32> @test3() { + %foo = vfcmp ueq <4 x float> , + ret <4 x i32> %foo +} +