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 | cacbb2377aeb58c9a43b69f3bd01be4863bb5002 (patch) | |
| tree | 6dbb19cbc985e329c1fca1fa6feed88cdeb08f7f /llvm/lib | |
| parent | 8f69d7f0c0c6ff12fcc8818bc5b2c2ffb4e971f9 (diff) | |
| download | bcm5719-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.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 18 |
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 |

