From 4c7c0f23533565c7e2ddf71e01bf50f2aede5f1b Mon Sep 17 00:00:00 2001 From: Nadav Rotem <nadav.rotem@intel.com> Date: Wed, 24 Aug 2011 20:18:38 +0000 Subject: [PATCH] Implement Constant::isAllOnesValue(). Fix ConstantFolding to use the new api. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138469 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constant.h | 4 +++ include/llvm/Constants.h | 2 +- lib/Analysis/ConstantFolding.cpp | 17 ++++++------- lib/VMCore/Constants.cpp | 24 +++++++++++++++--- test/Transforms/InstCombine/bitcast.ll | 34 ++++++++++++++++++++++---- 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 601b37bb64e..ecc1fe70cc5 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -52,6 +52,10 @@ public: /// getNullValue. bool isNullValue() const; + /// isAllOnesValue - Return true if this is the value that would be returned by + /// getAllOnesValue. + bool isAllOnesValue() const; + /// isNegativeZeroValue - Return true if the value is what would be returned /// by getZeroValueForNegation. bool isNegativeZeroValue() const; diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 5785b8187d8..e168979beaa 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -170,7 +170,7 @@ public: /// to true. /// @returns true iff this constant's bits are all set to true. /// @brief Determine if the value is all ones. - bool isAllOnesValue() const { + bool isMinusOne() const { return Val.isAllOnesValue(); } diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 7a8c703040c..df79849c3cf 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -45,16 +45,12 @@ using namespace llvm; /// ConstantExpr if unfoldable. static Constant *FoldBitCast(Constant *C, Type *DestTy, const TargetData &TD) { - - ConstantVector *CV = dyn_cast<ConstantVector>(C); - IntegerType *IntVTy = dyn_cast<IntegerType>(DestTy); - // When casting vectors to scalar integers, catch the - // obvious splat cases. - if (IntVTy && CV) { - if (CV->isNullValue()) return ConstantInt::getNullValue(IntVTy); - if (CV->isAllOnesValue()) return ConstantInt::getAllOnesValue(IntVTy); - } - + // Catch the obvious splat cases. + if (C->isNullValue() && !DestTy->isX86_MMXTy()) + return Constant::getNullValue(DestTy); + if (C->isAllOnesValue() && !DestTy->isX86_MMXTy()) + return Constant::getAllOnesValue(DestTy); + // The code below only handles casts to vectors currently. VectorType *DestVTy = dyn_cast<VectorType>(DestTy); if (DestVTy == 0) @@ -68,6 +64,7 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, } // If this is a bitcast from constant vector -> vector, fold it. + ConstantVector *CV = dyn_cast<ConstantVector>(C); if (CV == 0) return ConstantExpr::getBitCast(C, DestTy); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 2f22cda5ba4..ba309d9ca07 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -62,6 +62,21 @@ bool Constant::isNullValue() const { return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this); } +bool Constant::isAllOnesValue() const { + // Check for -1 integers + if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) + return CI->isMinusOne(); + + // Check for FP which are bitcasted from -1 integers + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) + return CFP->getValueAPF().bitcastToAPInt().isAllOnesValue(); + + // Check for constant vectors + if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) + return CV->isAllOnesValue(); + + return false; +} // Constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(Type *Ty) { switch (Ty->getTypeID()) { @@ -126,7 +141,7 @@ Constant *Constant::getAllOnesValue(Type *Ty) { SmallVector<Constant*, 16> Elts; VectorType *VTy = cast<VectorType>(Ty); Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); - assert(Elts[0] && "Not a vector integer type!"); + assert(Elts[0] && "Invalid AllOnes value!"); return cast<ConstantVector>(ConstantVector::get(Elts)); } @@ -1064,13 +1079,16 @@ bool ConstantVector::isAllOnesValue() const { // Check out first element. const Constant *Elt = getOperand(0); const ConstantInt *CI = dyn_cast<ConstantInt>(Elt); - if (!CI || !CI->isAllOnesValue()) return false; + const ConstantFP *CF = dyn_cast<ConstantFP>(Elt); + // Then make sure all remaining elements point to the same value. for (unsigned I = 1, E = getNumOperands(); I < E; ++I) if (getOperand(I) != Elt) return false; - return true; + // First value is all-ones. + return (CI && CI->isAllOnesValue()) || + (CF && CF->isAllOnesValue()); } /// getSplatValue - If this is a splat constant, where all of the diff --git a/test/Transforms/InstCombine/bitcast.ll b/test/Transforms/InstCombine/bitcast.ll index 3458c7b95b4..8f6ae7d8352 100644 --- a/test/Transforms/InstCombine/bitcast.ll +++ b/test/Transforms/InstCombine/bitcast.ll @@ -11,7 +11,7 @@ define i32 @test1(i64 %a) { %t3 = xor <2 x i32> %t1, %t2 %t4 = extractelement <2 x i32> %t3, i32 0 ret i32 %t4 - + ; CHECK: @test1 ; CHECK: ret i32 0 } @@ -30,7 +30,7 @@ define float @test2(<2 x float> %A, <2 x i32> %B) { %add = fadd float %tmp24, %tmp4 ret float %add - + ; CHECK: @test2 ; CHECK-NEXT: %tmp24 = extractelement <2 x float> %A, i32 0 ; CHECK-NEXT: bitcast <2 x i32> %B to <2 x float> @@ -55,7 +55,7 @@ define float @test3(<2 x float> %A, <2 x i64> %B) { %add = fadd float %tmp24, %tmp4 ret float %add - + ; CHECK: @test3 ; CHECK-NEXT: %tmp24 = extractelement <2 x float> %A, i32 1 ; CHECK-NEXT: bitcast <2 x i64> %B to <4 x float> @@ -75,7 +75,7 @@ define <2 x i32> @test4(i32 %A, i32 %B){ ; CHECK: @test4 ; CHECK-NEXT: insertelement <2 x i32> undef, i32 %A, i32 0 ; CHECK-NEXT: insertelement <2 x i32> {{.*}}, i32 %B, i32 1 - ; CHECK-NEXT: ret <2 x i32> + ; CHECK-NEXT: ret <2 x i32> } @@ -92,7 +92,7 @@ define <2 x float> @test5(float %A, float %B) { ; CHECK: @test5 ; CHECK-NEXT: insertelement <2 x float> undef, float %A, i32 0 ; CHECK-NEXT: insertelement <2 x float> {{.*}}, float %B, i32 1 - ; CHECK-NEXT: ret <2 x float> + ; CHECK-NEXT: ret <2 x float> } define <2 x float> @test6(float %A){ @@ -113,3 +113,27 @@ define i64 @ISPC0(i64 %in) { ; CHECK: @ISPC0 ; CHECK: ret i64 0 } + + +define i64 @Vec2(i64 %in) { + %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 0> to i64), i64 0) + ret i64 %out +; CHECK: @Vec2 +; CHECK: ret i64 0 +} + +define i64 @All11(i64 %in) { + %out = and i64 %in, xor (i64 bitcast (<2 x float> bitcast (i64 -1 to <2 x float>) to i64), i64 -1) + ret i64 %out +; CHECK: @All11 +; CHECK: ret i64 0 +} + + +define i32 @All111(i32 %in) { + %out = and i32 %in, xor (i32 bitcast (<1 x float> bitcast (i32 -1 to <1 x float>) to i32), i32 -1) + ret i32 %out +; CHECK: @All111 +; CHECK: ret i32 0 +} + -- 2.34.1