diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 601b37bb64e..8ae585d48b8 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -51,6 +51,9 @@ public: /// isNullValue - Return true if this is the value that would be returned by /// 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. diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 7a8c703040c..0eacaf80378 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -45,15 +45,9 @@ using namespace llvm; /// ConstantExpr if unfoldable. static Constant *FoldBitCast(Constant *C, Type *DestTy, const TargetData &TD) { - - ConstantVector *CV = dyn_cast(C); - IntegerType *IntVTy = dyn_cast(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()) return Constant::getNullValue(DestTy); + if (C->isAllOnesValue()) return Constant::getAllOnesValue(DestTy); // The code below only handles casts to vectors currently. VectorType *DestVTy = dyn_cast(DestTy); @@ -68,6 +62,7 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, } // If this is a bitcast from constant vector -> vector, fold it. + ConstantVector *CV = dyn_cast(C); if (CV == 0) return ConstantExpr::getBitCast(C, DestTy); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 2f22cda5ba4..8b41ab75e25 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -62,6 +62,21 @@ bool Constant::isNullValue() const { return isa(this) || isa(this); } +bool Constant::isAllOnesValue() const { + // Check for -1 integers + if (const ConstantInt *CI = dyn_cast(this)) + return CI->isAllOnesValue(); + + // +0.0 is null. + if (const ConstantFP *CFP = dyn_cast(this)) + return CFP->getValueAPF().bitcastToAPInt().isAllOnesValue(); + + // Check for constant vectors + if (const ConstantVector *CV = dyn_cast(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 Elts; VectorType *VTy = cast(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::get(Elts)); } @@ -1064,13 +1079,16 @@ bool ConstantVector::isAllOnesValue() const { // Check out first element. const Constant *Elt = getOperand(0); const ConstantInt *CI = dyn_cast(Elt); - if (!CI || !CI->isAllOnesValue()) return false; + const ConstantFP *CF = dyn_cast(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 b0630d27254..899cb4962a3 100644 --- a/test/Transforms/InstCombine/bitcast.ll +++ b/test/Transforms/InstCombine/bitcast.ll @@ -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> 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 i64 @All111(i32 %in) { + %out = and i32 %in, xor (i64 bitcast (<1 x float> bitcast (i32 -1 to <1 x float>) to i32), i32 -1) + ret i32 %out +; CHECK: @All11 +; CHECK: ret i32 0 +} +