From 330e7e4d250653243afaaeef4c01a7c12c314b39 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 10 Jul 2008 00:08:17 +0000 Subject: [PATCH] elementwise comparison of vector constants was completely wrong. Fix it for PR2529 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53380 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/ConstantFold.cpp | 51 ++++++++++++------- .../ConstProp/2008-07-07-VectorCompare.ll | 10 +++- 2 files changed, 41 insertions(+), 20 deletions(-) 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 +} +