summaryrefslogtreecommitdiff
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2012-01-27 01:44:03 +0000
committerChris Lattner <sabre@nondot.org>2012-01-27 01:44:03 +0000
commitf983da030e8295ae0f9a74d1185f999485f792b3 (patch)
treec033072ddf8ee19c88d4a40ab993493c9a1f6436 /lib/Analysis/ConstantFolding.cpp
parentcb5dca38157a48c734660746e7f7340d5db7c2db (diff)
downloadllvm-f983da030e8295ae0f9a74d1185f999485f792b3.tar.gz
llvm-f983da030e8295ae0f9a74d1185f999485f792b3.tar.bz2
llvm-f983da030e8295ae0f9a74d1185f999485f792b3.tar.xz
enhance constant folding to be able to constant fold bitcast of
ConstantVector's to integer type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149110 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index fe28926f1b..6fbb1fe94d 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/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)