diff options
author | Duncan Sands <baldrick@free.fr> | 2008-01-06 10:12:28 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-01-06 10:12:28 +0000 |
commit | a9d0c9dc58855a5f01dcc5c85c89fd3fc737d3e8 (patch) | |
tree | c8b6cf3406bdd858d159a99b39e5f498cd4cd9e7 /lib/Transforms | |
parent | 2e48a70b35635165703838fc8d3796b664207aa1 (diff) | |
download | llvm-a9d0c9dc58855a5f01dcc5c85c89fd3fc737d3e8.tar.gz llvm-a9d0c9dc58855a5f01dcc5c85c89fd3fc737d3e8.tar.bz2 llvm-a9d0c9dc58855a5f01dcc5c85c89fd3fc737d3e8.tar.xz |
When transforming a call to a bitcast function into
a direct call with cast parameters and cast return
value (if any), instcombine was prepared to cast any
non-void return value into any other, whether castable
or not. Add a new predicate for testing whether casting
is valid, and check it both for the return value and
(as a cleanup) for the parameters.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 61 |
1 files changed, 16 insertions, 45 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 1e12c79e68..4fcd47a870 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -8082,11 +8082,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { const FunctionType *FT = Callee->getFunctionType(); const Type *OldRetTy = Caller->getType(); - const ParamAttrsList* CallerPAL = 0; - if (CallInst *CallerCI = dyn_cast<CallInst>(Caller)) - CallerPAL = CallerCI->getParamAttrs(); - else if (InvokeInst *CallerII = dyn_cast<InvokeInst>(Caller)) - CallerPAL = CallerII->getParamAttrs(); + const ParamAttrsList* CallerPAL = CS.getParamAttrs(); // If the parameter attributes are not compatible, don't do the xform. We // don't want to lose an sret attribute or something. @@ -8101,6 +8097,12 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { TD->getIntPtrType() == OldRetTy)) return false; // Cannot transform this return value. + if (!Caller->use_empty() && + !CastInst::isCastable(FT->getReturnType(), OldRetTy) && + // void -> non-void is handled specially + FT->getReturnType() != Type::VoidTy) + return false; // Cannot transform this return value. + // If the callsite is an invoke instruction, and the return value is used by // a PHI node in a successor, we cannot change the return type of the call // because there is no place to put the cast instruction (without breaking @@ -8122,9 +8124,13 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { for (unsigned i = 0, e = NumCommonArgs; i != e; ++i, ++AI) { const Type *ParamTy = FT->getParamType(i); const Type *ActTy = (*AI)->getType(); + + if (!CastInst::isCastable(ActTy, ParamTy)) + return false; + ConstantInt *c = dyn_cast<ConstantInt>(*AI); - //Some conversions are safe even if we do not have a body. - //Either we can cast directly, or we can upconvert the argument + // Some conversions are safe even if we do not have a body. + // Either we can cast directly, or we can upconvert the argument bool isConvertible = ActTy == ParamTy || (isa<PointerType>(ParamTy) && isa<PointerType>(ActTy)) || (ParamTy->isInteger() && ActTy->isInteger() && @@ -8132,40 +8138,6 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { (c && ParamTy->getPrimitiveSizeInBits() >= ActTy->getPrimitiveSizeInBits() && c->getValue().isStrictlyPositive()); if (Callee->isDeclaration() && !isConvertible) return false; - - // Most other conversions can be done if we have a body, even if these - // lose information, e.g. int->short. - // Some conversions cannot be done at all, e.g. float to pointer. - // Logic here parallels CastInst::getCastOpcode (the design there - // requires legality checks like this be done before calling it). - if (ParamTy->isInteger()) { - if (const VectorType *VActTy = dyn_cast<VectorType>(ActTy)) { - if (VActTy->getBitWidth() != ParamTy->getPrimitiveSizeInBits()) - return false; - } - if (!ActTy->isInteger() && !ActTy->isFloatingPoint() && - !isa<PointerType>(ActTy)) - return false; - } else if (ParamTy->isFloatingPoint()) { - if (const VectorType *VActTy = dyn_cast<VectorType>(ActTy)) { - if (VActTy->getBitWidth() != ParamTy->getPrimitiveSizeInBits()) - return false; - } - if (!ActTy->isInteger() && !ActTy->isFloatingPoint()) - return false; - } else if (const VectorType *VParamTy = dyn_cast<VectorType>(ParamTy)) { - if (const VectorType *VActTy = dyn_cast<VectorType>(ActTy)) { - if (VActTy->getBitWidth() != VParamTy->getBitWidth()) - return false; - } - if (VParamTy->getBitWidth() != ActTy->getPrimitiveSizeInBits()) - return false; - } else if (isa<PointerType>(ParamTy)) { - if (!ActTy->isInteger() && !isa<PointerType>(ActTy)) - return false; - } else { - return false; - } } if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() && @@ -8238,12 +8210,11 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { // Insert a cast of the return type as necessary. Value *NV = NC; - if (Caller->getType() != NV->getType() && !Caller->use_empty()) { + if (OldRetTy != NV->getType() && !Caller->use_empty()) { if (NV->getType() != Type::VoidTy) { - const Type *CallerTy = Caller->getType(); Instruction::CastOps opcode = CastInst::getCastOpcode(NC, false, - CallerTy, false); - NV = NC = CastInst::create(opcode, NC, CallerTy, "tmp"); + OldRetTy, false); + NV = NC = CastInst::create(opcode, NC, OldRetTy, "tmp"); // If this is an invoke instruction, we should insert it after the first // non-phi, instruction in the normal successor block. |