summaryrefslogtreecommitdiffstats
path: root/llvm/lib
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
commitcacbb2377aeb58c9a43b69f3bd01be4863bb5002 (patch)
tree6dbb19cbc985e329c1fca1fa6feed88cdeb08f7f /llvm/lib
parent8f69d7f0c0c6ff12fcc8818bc5b2c2ffb4e971f9 (diff)
downloadbcm5719-llvm-cacbb2377aeb58c9a43b69f3bd01be4863bb5002.tar.gz
bcm5719-llvm-cacbb2377aeb58c9a43b69f3bd01be4863bb5002.zip
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. llvm-svn: 187444
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Instructions.cpp46
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp18
2 files changed, 53 insertions, 11 deletions
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 5878f77dc17..665fe66ccc3 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/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
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 815db335ea4..9f74fd6b8d0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1010,7 +1010,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (!Caller->use_empty() &&
// void -> non-void is handled specially
- !NewRetTy->isVoidTy() && !CastInst::isCastable(NewRetTy, OldRetTy))
+ !NewRetTy->isVoidTy() &&
+ !CastInst::isBitCastable(NewRetTy, OldRetTy))
return false; // Cannot transform this return value.
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
@@ -1044,8 +1045,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
Type *ParamTy = FT->getParamType(i);
Type *ActTy = (*AI)->getType();
- if (!CastInst::isCastable(ActTy, ParamTy))
+ if (!CastInst::isBitCastable(ActTy, ParamTy)) {
return false; // Cannot transform this parameter value.
+ }
if (AttrBuilder(CallerPAL.getParamAttributes(i + 1), i + 1).
hasAttributes(AttributeFuncs::
@@ -1074,7 +1076,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
ParamTy == TD->getIntPtrType(Caller->getContext())) &&
(ActTy->isPointerTy() ||
ActTy == TD->getIntPtrType(Caller->getContext()))));
- if (Callee->isDeclaration() && !isConvertible) return false;
+ if (Callee->isDeclaration() && !isConvertible)
+ return false;
}
if (Callee->isDeclaration()) {
@@ -1141,12 +1144,11 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
AI = CS.arg_begin();
for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
Type *ParamTy = FT->getParamType(i);
+
if ((*AI)->getType() == ParamTy) {
Args.push_back(*AI);
} else {
- Instruction::CastOps opcode = CastInst::getCastOpcode(*AI,
- false, ParamTy, false);
- Args.push_back(Builder->CreateCast(opcode, *AI, ParamTy));
+ Args.push_back(Builder->CreateBitCast(*AI, ParamTy));
}
// Add any parameter attributes.
@@ -1217,9 +1219,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
Value *NV = NC;
if (OldRetTy != NV->getType() && !Caller->use_empty()) {
if (!NV->getType()->isVoidTy()) {
- Instruction::CastOps opcode =
- CastInst::getCastOpcode(NC, false, OldRetTy, false);
- NV = NC = CastInst::Create(opcode, NC, OldRetTy);
+ NV = NC = CastInst::Create(CastInst::BitCast, NC, OldRetTy);
NC->setDebugLoc(Caller->getDebugLoc());
// If this is an invoke instruction, we should insert it after the first
OpenPOWER on IntegriCloud