summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-04-04 19:16:42 +0000
committerDale Johannesen <dalej@apple.com>2007-04-04 19:16:42 +0000
commit7c2001d01422a2fd2167e2948ddb5274c16a1dae (patch)
tree76a85b9bfe2e947bf5622ad55899bf7835986232 /llvm/lib/Transforms
parentedf61160b138a929b8b2039a6628edec7e654edc (diff)
downloadbcm5719-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.cpp35
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() &&
OpenPOWER on IntegriCloud