diff options
| author | Dale Johannesen <dalej@apple.com> | 2007-04-04 19:16:42 +0000 |
|---|---|---|
| committer | Dale Johannesen <dalej@apple.com> | 2007-04-04 19:16:42 +0000 |
| commit | 7c2001d01422a2fd2167e2948ddb5274c16a1dae (patch) | |
| tree | 76a85b9bfe2e947bf5622ad55899bf7835986232 /llvm/lib/Transforms | |
| parent | edf61160b138a929b8b2039a6628edec7e654edc (diff) | |
| download | bcm5719-llvm-7c2001d01422a2fd2167e2948ddb5274c16a1dae.tar.gz bcm5719-llvm-7c2001d01422a2fd2167e2948ddb5274c16a1dae.zip | |
Prevent transformConstExprCastCall from generating conversions that assert
elsewhere.
llvm-svn: 35668
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index d217fca8890..d9b15de1afb 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7469,6 +7469,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { const Type *ParamTy = FT->getParamType(i); const Type *ActTy = (*AI)->getType(); 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 bool isConvertible = ActTy == ParamTy || (isa<PointerType>(ParamTy) && isa<PointerType>(ActTy)) || @@ -7477,6 +7478,40 @@ 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() && |

