diff options
author | grehan <grehan@FreeBSD.org> | 2011-06-28 06:26:03 +0000 |
---|---|---|
committer | grehan <grehan@FreeBSD.org> | 2011-06-28 06:26:03 +0000 |
commit | 2c6741be0f59191f2283eb268e4f7690399d578a (patch) | |
tree | b139c8c6dcca4fa284815daade405b75886ee360 /contrib/llvm/lib/VMCore/Instructions.cpp | |
parent | 3c35264f695e0a1f8a04dbcca1c93bb5159b2274 (diff) | |
parent | 19ae02bba572390c7299166228d31e54003e094a (diff) | |
download | FreeBSD-src-2c6741be0f59191f2283eb268e4f7690399d578a.zip FreeBSD-src-2c6741be0f59191f2283eb268e4f7690399d578a.tar.gz |
IFC @ r222830
Diffstat (limited to 'contrib/llvm/lib/VMCore/Instructions.cpp')
-rw-r--r-- | contrib/llvm/lib/VMCore/Instructions.cpp | 167 |
1 files changed, 79 insertions, 88 deletions
diff --git a/contrib/llvm/lib/VMCore/Instructions.cpp b/contrib/llvm/lib/VMCore/Instructions.cpp index 61da9b6..8f4eabe 100644 --- a/contrib/llvm/lib/VMCore/Instructions.cpp +++ b/contrib/llvm/lib/VMCore/Instructions.cpp @@ -2076,6 +2076,7 @@ unsigned CastInst::isEliminableCastPair( CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore) { + assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); @@ -2098,6 +2099,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { + assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); @@ -2254,60 +2256,56 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { if (SrcTy == DestTy) return true; + if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) + if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) + if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { + // An element by element cast. Valid if casting the elements is valid. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + // Get the bit sizes, we'll need these - unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr - unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr // Run through the possibilities ... - if (DestTy->isIntegerTy()) { // Casting to integral - if (SrcTy->isIntegerTy()) { // Casting from integral + if (DestTy->isIntegerTy()) { // Casting to integral + if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt + } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt return true; - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestBits == PTy->getBitWidth(); + } else if (SrcTy->isVectorTy()) { // Casting from vector + return DestBits == SrcBits; } else { // Casting from something else return SrcTy->isPointerTy(); } - } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt - if (SrcTy->isIntegerTy()) { // Casting from integral + } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt + if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt + } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt return true; - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestBits == PTy->getBitWidth(); + } else if (SrcTy->isVectorTy()) { // Casting from vector + return DestBits == SrcBits; } else { // Casting from something else return false; } - } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { - // Casting to vector - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - // Casting from vector - return DestPTy->getBitWidth() == SrcPTy->getBitWidth(); - } else if (DestPTy->getBitWidth() == SrcBits) { - return true; // float/int -> vector - } else if (SrcTy->isX86_MMXTy()) { - return DestPTy->getBitWidth() == 64; // MMX to 64-bit vector - } else { - return false; - } + } else if (DestTy->isVectorTy()) { // Casting to vector + return DestBits == SrcBits; } else if (DestTy->isPointerTy()) { // Casting to pointer - if (SrcTy->isPointerTy()) { // Casting from pointer + if (SrcTy->isPointerTy()) { // Casting from pointer return true; - } else if (SrcTy->isIntegerTy()) { // Casting from integral + } else if (SrcTy->isIntegerTy()) { // Casting from integral return true; - } else { // Casting from something else + } else { // Casting from something else return false; } } else if (DestTy->isX86_MMXTy()) { - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - return SrcPTy->getBitWidth() == 64; // 64-bit vector to MMX + if (SrcTy->isVectorTy()) { + return DestBits == SrcBits; // 64-bit vector to MMX } else { return false; } - } else { // Casting to something else + } else { // Casting to something else return false; } } @@ -2322,14 +2320,27 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) { Instruction::CastOps CastInst::getCastOpcode( const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) { - // Get the bit sizes, we'll need these const Type *SrcTy = Src->getType(); - unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr - unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() && "Only first class types are castable!"); + if (SrcTy == DestTy) + return BitCast; + + if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) + if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) + if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { + // An element by element cast. Find the appropriate opcode based on the + // element types. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + + // Get the bit sizes, we'll need these + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr + // Run through the possibilities ... if (DestTy->isIntegerTy()) { // Casting to integral if (SrcTy->isIntegerTy()) { // Casting from integral @@ -2348,10 +2359,9 @@ CastInst::getCastOpcode( return FPToSI; // FP -> sint else return FPToUI; // FP -> uint - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestBits == PTy->getBitWidth() && - "Casting vector to integer of different width"); - PTy = NULL; + } else if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && + "Casting vector to integer of different width"); return BitCast; // Same size, no-op cast } else { assert(SrcTy->isPointerTy() && @@ -2372,29 +2382,17 @@ CastInst::getCastOpcode( } else { return BitCast; // same size, no-op cast } - } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestBits == PTy->getBitWidth() && + } else if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && "Casting vector to floating point of different width"); - PTy = NULL; return BitCast; // same size, no-op cast } else { llvm_unreachable("Casting pointer or non-first class to float"); } - } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { - if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { - assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() && - "Casting vector to vector of different widths"); - SrcPTy = NULL; - return BitCast; // vector -> vector - } else if (DestPTy->getBitWidth() == SrcBits) { - return BitCast; // float/int -> vector - } else if (SrcTy->isX86_MMXTy()) { - assert(DestPTy->getBitWidth()==64 && - "Casting X86_MMX to vector of wrong width"); - return BitCast; // MMX to 64-bit vector - } else { - assert(!"Illegal cast to vector (wrong type or size)"); - } + } else if (DestTy->isVectorTy()) { + assert(DestBits == SrcBits && + "Illegal cast to vector (wrong type or size)"); + return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { return BitCast; // ptr -> ptr @@ -2404,9 +2402,8 @@ CastInst::getCastOpcode( assert(!"Casting pointer to other than pointer or int"); } } else if (DestTy->isX86_MMXTy()) { - if (isa<VectorType>(SrcTy)) { - assert(cast<VectorType>(SrcTy)->getBitWidth() == 64 && - "Casting vector of wrong width to X86_MMX"); + if (SrcTy->isVectorTy()) { + assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); return BitCast; // 64-bit vector to MMX } else { assert(!"Illegal cast to X86_MMX"); @@ -2442,46 +2439,40 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); unsigned DstBitSize = DstTy->getScalarSizeInBits(); + // If these are vector types, get the lengths of the vectors (using zero for + // scalar types means that checking that vector lengths match also checks that + // scalars are not being converted to vectors or vectors to scalars). + unsigned SrcLength = SrcTy->isVectorTy() ? + cast<VectorType>(SrcTy)->getNumElements() : 0; + unsigned DstLength = DstTy->isVectorTy() ? + cast<VectorType>(DstTy)->getNumElements() : 0; + // Switch on the opcode provided switch (op) { default: return false; // This is an input error case Instruction::Trunc: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::ZExt: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::SExt: - return SrcTy->isIntOrIntVectorTy() && - DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::FPTrunc: - return SrcTy->isFPOrFPVectorTy() && - DstTy->isFPOrFPVectorTy() && - SrcBitSize > DstBitSize; + return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::FPExt: - return SrcTy->isFPOrFPVectorTy() && - DstTy->isFPOrFPVectorTy() && - SrcBitSize < DstBitSize; + return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::UIToFP: case Instruction::SIToFP: - if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) { - if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { - return SVTy->getElementType()->isIntOrIntVectorTy() && - DVTy->getElementType()->isFPOrFPVectorTy() && - SVTy->getNumElements() == DVTy->getNumElements(); - } - } - return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy(); + return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() && + SrcLength == DstLength; case Instruction::FPToUI: case Instruction::FPToSI: - if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) { - if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) { - return SVTy->getElementType()->isFPOrFPVectorTy() && - DVTy->getElementType()->isIntOrIntVectorTy() && - SVTy->getNumElements() == DVTy->getNumElements(); - } - } - return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy(); + return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && + SrcLength == DstLength; case Instruction::PtrToInt: return SrcTy->isPointerTy() && DstTy->isIntegerTy(); case Instruction::IntToPtr: |