diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-07-30 20:45:05 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-07-30 20:45:05 +0000 |
commit | f34dc428fa577d6d5d71ab3a1f9765b4e5da5a4f (patch) | |
tree | a86bb2efc2858086c526b79eb798b2de2a04d3cb /lib/IR/Instructions.cpp | |
parent | 80bec28b6645676a7cd9408d780b4c805774ef42 (diff) | |
download | llvm-f34dc428fa577d6d5d71ab3a1f9765b4e5da5a4f.tar.gz llvm-f34dc428fa577d6d5d71ab3a1f9765b4e5da5a4f.tar.bz2 llvm-f34dc428fa577d6d5d71ab3a1f9765b4e5da5a4f.tar.xz |
Change behavior of calling bitcasted alias functions.
It will now only convert the arguments / return value and call
the underlying function if the types are able to be bitcasted.
This avoids using fp<->int conversions that would occur before.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187444 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR/Instructions.cpp')
-rw-r--r-- | lib/IR/Instructions.cpp | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 5878f77dc1..665fe66ccc 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -2517,8 +2517,48 @@ bool CastInst::isCastable(Type *SrcTy, Type *DestTy) { } } -// Provide a way to get a "cast" where the cast opcode is inferred from the -// types and size of the operand. This, basically, is a parallel of the +bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) { + if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType()) + return false; + + if (SrcTy == DestTy) + return true; + + if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) { + if (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(); + } + } + } + + if (PointerType *DestPtrTy = dyn_cast<PointerType>(DestTy)) { + if (PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy)) { + return SrcPtrTy->getAddressSpace() == DestPtrTy->getAddressSpace(); + } + } + + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr + + // Could still have vectors of pointers if the number of elements doesn't + // match + if (SrcBits == 0 || DestBits == 0) + return false; + + if (SrcBits != DestBits) + return false; + + if (DestTy->isX86_MMXTy() || SrcTy->isX86_MMXTy()) + return false; + + return true; +} + +// Provide a way to get a "cast" where the cast opcode is inferred from the +// types and size of the operand. This, basically, is a parallel of the // logic in the castIsValid function below. This axiom should hold: // castIsValid( getCastOpcode(Val, Ty), Val, Ty) // should not assert in castIsValid. In other words, this produces a "correct" @@ -2535,6 +2575,7 @@ CastInst::getCastOpcode( if (SrcTy == DestTy) return BitCast; + // FIXME: Check address space sizes here if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { @@ -2601,6 +2642,7 @@ CastInst::getCastOpcode( return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { + // TODO: Address space pointer sizes may not match return BitCast; // ptr -> ptr } else if (SrcTy->isIntegerTy()) { return IntToPtr; // int -> ptr |