diff options
author | Chris Lattner <sabre@nondot.org> | 2012-01-27 01:44:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2012-01-27 01:44:03 +0000 |
commit | 111d6ee655738400fae3bcdbd5f4bb5192ef4f1c (patch) | |
tree | 26db268a05e54236af33351bf9fa214a846cfb6b /llvm/lib | |
parent | cf6e0c839dbdec83d3bc56634662f085cfc7b730 (diff) | |
download | bcm5719-llvm-111d6ee655738400fae3bcdbd5f4bb5192ef4f1c.tar.gz bcm5719-llvm-111d6ee655738400fae3bcdbd5f4bb5192ef4f1c.zip |
enhance constant folding to be able to constant fold bitcast of
ConstantVector's to integer type.
llvm-svn: 149110
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index fe28926f1b2..6fbb1fe94d0 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -52,6 +52,44 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy, if (C->isAllOnesValue() && !DestTy->isX86_MMXTy()) return Constant::getAllOnesValue(DestTy); + // Handle a vector->integer cast. + if (IntegerType *IT = dyn_cast<IntegerType>(DestTy)) { + // FIXME: Remove ConstantVector support. + if ((!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C)) || + // TODO: Handle big endian someday. + !TD.isLittleEndian()) + return ConstantExpr::getBitCast(C, DestTy); + + unsigned NumSrcElts = C->getType()->getVectorNumElements(); + + // If the vector is a vector of floating point, convert it to vector of int + // to simplify things. + if (C->getType()->getVectorElementType()->isFloatingPointTy()) { + unsigned FPWidth = + C->getType()->getVectorElementType()->getPrimitiveSizeInBits(); + Type *SrcIVTy = + VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts); + // Ask VMCore to do the conversion now that #elts line up. + C = ConstantExpr::getBitCast(C, SrcIVTy); + } + + // Now that we know that the input value is a vector of integers, just shift + // and insert them into our result. + unsigned BitShift = + TD.getTypeAllocSizeInBits(C->getType()->getVectorElementType()); + APInt Result(IT->getBitWidth(), 0); + for (unsigned i = 0; i != NumSrcElts; ++i) { + // FIXME: Rework when we have ConstantDataVector. + ConstantInt *Elt=dyn_cast_or_null<ConstantInt>(C->getAggregateElement(i)); + if (Elt == 0) // Elt must be a constant expr or something. + return ConstantExpr::getBitCast(C, DestTy); + + Result |= Elt->getValue().zext(IT->getBitWidth()) << i*BitShift; + } + + return ConstantInt::get(IT, Result); + } + // The code below only handles casts to vectors currently. VectorType *DestVTy = dyn_cast<VectorType>(DestTy); if (DestVTy == 0) |