From 093399cbf3bcdb31d04b3bf5c5691fc88c25da48 Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Thu, 17 Feb 2011 21:22:27 +0000 Subject: [PATCH] Enhance constant folding of bitcast operations on vectors of floats. Add getAllOnesValue of FP numbers to Constants and APFloat. Add more tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125776 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/APFloat.h | 7 ++++ lib/Support/APFloat.cpp | 6 +++ lib/VMCore/ConstantFold.cpp | 3 +- lib/VMCore/Constants.cpp | 8 +++- .../InstCombine/bitcast-vec-uniform.ll | 42 ++++++++++++++++++- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index dfe4e0f49ad..ca4138b825a 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -246,6 +246,13 @@ namespace llvm { static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative = false); + /// getAllOnesValue - Returns a float which is bitcasted from + /// an all one value int. + /// + /// \param BitWidth - Select float type + /// \param isIEEE - If 128 bit number, select between PPC and IEEE + static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); + /// Profile - Used to insert APFloat objects, or objects that contain /// APFloat objects, into FoldingSets. void Profile(FoldingSetNodeID& NID) const; diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 6d018afa3f6..e765ba0a27b 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -3197,6 +3197,12 @@ APFloat::initFromAPInt(const APInt& api, bool isIEEE) llvm_unreachable(0); } +APFloat +APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) +{ + return APFloat(APInt::getAllOnesValue(BitWidth), isIEEE); +} + APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { APFloat Val(Sem, fcNormal, Negative); diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index c8292c6d612..573efb7e573 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -43,8 +43,7 @@ using namespace llvm; static Constant *BitCastConstantVector(ConstantVector *CV, const VectorType *DstTy) { - if (CV->isAllOnesValue() && DstTy->getElementType()->isIntegerTy()) - return Constant::getAllOnesValue(DstTy); + if (CV->isAllOnesValue()) return Constant::getAllOnesValue(DstTy); if (CV->isNullValue()) return Constant::getNullValue(DstTy); // If this cast changes element count then we can't handle it here: diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index cac37cbcc38..a2ac768d221 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -93,7 +93,13 @@ Constant *Constant::getAllOnesValue(const Type *Ty) { if (const IntegerType *ITy = dyn_cast(Ty)) return ConstantInt::get(Ty->getContext(), APInt::getAllOnesValue(ITy->getBitWidth())); - + + if (Ty->isFloatingPointTy()) { + APFloat FL = APFloat::getAllOnesValue(Ty->getPrimitiveSizeInBits(), + !Ty->isPPC_FP128Ty()); + return ConstantFP::get(Ty->getContext(), FL); + } + SmallVector Elts; const VectorType *VTy = cast(Ty); Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); diff --git a/test/Transforms/InstCombine/bitcast-vec-uniform.ll b/test/Transforms/InstCombine/bitcast-vec-uniform.ll index a0d4678b0a0..5975f1ec396 100644 --- a/test/Transforms/InstCombine/bitcast-vec-uniform.ll +++ b/test/Transforms/InstCombine/bitcast-vec-uniform.ll @@ -18,7 +18,8 @@ define <4 x i32> @b(<1 x i64> %y) { } ; CHECK: @foo -; CHECK: bitcast +; CHECK-NOT: bitcast +; CHECK: ret ; from MultiSource/Benchmarks/Bullet define <2 x float> @foo() { @@ -27,4 +28,43 @@ define <2 x float> @foo() { } +; CHECK: @foo2 +; CHECK-NOT: bitcast +; CHECK: ret +define <2 x double> @foo2() { + %cast = bitcast i128 -1 to <2 x double> + ret <2 x double> %cast +} +; CHECK: @foo3 +; CHECK-NOT: bitcast +; CHECK: ret +define <1 x float> @foo3() { + %cast = bitcast i32 -1 to <1 x float> + ret <1 x float> %cast +} + +; CHECK: @foo4 +; CHECK-NOT: bitcast +; CHECK: ret +define float @foo4() { + %cast = bitcast <1 x i32 > to float + ret float %cast +} + +; CHECK: @foo5 +; CHECK-NOT: bitcast +; CHECK: ret +define double @foo5() { + %cast = bitcast <2 x i32 > to double + ret double %cast +} + + +; CHECK: @foo6 +; CHECK-NOT: bitcast +; CHECK: ret +define <2 x double> @foo6() { + %cast = bitcast <4 x i32> to <2 x double> + ret <2 x double> %cast +}