summaryrefslogtreecommitdiff
path: root/lib/IR/Instructions.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2013-07-30 20:45:05 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2013-07-30 20:45:05 +0000
commitf34dc428fa577d6d5d71ab3a1f9765b4e5da5a4f (patch)
treea86bb2efc2858086c526b79eb798b2de2a04d3cb /lib/IR/Instructions.cpp
parent80bec28b6645676a7cd9408d780b4c805774ef42 (diff)
downloadllvm-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.cpp46
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