aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-01-27 23:33:07 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-01-27 23:33:07 +0000
commit04594aeffa3360882eb09a888a0970321b987b16 (patch)
treeeff7f045ec9900682ce59a374960799be389313c /lib
parent0c6e1778817ac97b42af1375ec6bfae8b65e9d76 (diff)
downloadexternal_llvm-04594aeffa3360882eb09a888a0970321b987b16.zip
external_llvm-04594aeffa3360882eb09a888a0970321b987b16.tar.gz
external_llvm-04594aeffa3360882eb09a888a0970321b987b16.tar.bz2
Add r149110 back with a fix for when the vector and the int have the same
width. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149151 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ConstantFolding.cpp38
-rw-r--r--lib/Support/APInt.cpp12
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index fe28926..121e334 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().zextOrSelf(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)
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index b5411be..c580dd3 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -1123,6 +1123,18 @@ APInt APInt::sextOrTrunc(unsigned width) const {
return *this;
}
+APInt APInt::zextOrSelf(unsigned width) const {
+ if (BitWidth < width)
+ return zext(width);
+ return *this;
+}
+
+APInt APInt::sextOrSelf(unsigned width) const {
+ if (BitWidth < width)
+ return sext(width);
+ return *this;
+}
+
/// Arithmetic right-shift this APInt by shiftAmt.
/// @brief Arithmetic right-shift function.
APInt APInt::ashr(const APInt &shiftAmt) const {