aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore/ConstantFold.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-12-11 18:30:27 +0000
committerChris Lattner <sabre@nondot.org>2006-12-11 18:30:27 +0000
commit14f440aae76e5bae91e6775ddfbb9473bf0b8144 (patch)
tree72f0a4cb6ae427f58092b24324f77bd484fab2f8 /lib/VMCore/ConstantFold.cpp
parent4ed4ac34c3fb132f3b8c9fb77aa6f7afe8ce16a7 (diff)
Implement correct constant folding of bitcast. This implements
Transforms/ConstProp/bitcast.ll and fixes SingleSource/Regression/C/2003-10-12-GlobalVarInitializers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32438 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/ConstantFold.cpp')
-rw-r--r--lib/VMCore/ConstantFold.cpp48
1 files changed, 33 insertions, 15 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index b8001506f3..7eb7d4d8f8 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -828,10 +828,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
const Type *DestTy) {
const Type *SrcTy = V->getType();
- // Handle some simple cases
- if (SrcTy == DestTy)
- return (Constant*)V; // no-op cast
-
if (isa<UndefValue>(V))
return UndefValue::get(DestTy);
@@ -901,6 +897,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
return ConstantIntegral::get(DestTy, CI->getZExtValue());
return 0;
case Instruction::BitCast:
+ if (SrcTy == DestTy) return (Constant*)V; // no-op cast
+
// Check to see if we are casting a pointer to an aggregate to a pointer to
// the first element. If so, return the appropriate GEP instruction.
if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
@@ -960,18 +958,38 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
}
}
- // Handle sign conversion for integer no-op casts. We need to cast the
- // value to the correct signedness before we try to cast it to the
- // destination type. Be careful to do this only for integer types.
- if (isa<ConstantIntegral>(V) && SrcTy->isInteger()) {
- if (SrcTy->isSigned())
- V = ConstantInt::get(SrcTy->getUnsignedVersion(),
- cast<ConstantIntegral>(V)->getZExtValue());
- else
- V = ConstantInt::get(SrcTy->getSignedVersion(),
- cast<ConstantIntegral>(V)->getSExtValue());
+ // Finally, implement bitcast folding now. The code below doesn't handle
+ // bitcast right.
+ if (isa<ConstantPointerNull>(V)) // ptr->ptr cast.
+ return ConstantPointerNull::get(cast<PointerType>(DestTy));
+
+ // Handle integral constant input.
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ // Integral -> Integral, must be changing sign.
+ if (DestTy->isIntegral())
+ return ConstantInt::get(DestTy, CI->getZExtValue());
+
+ if (DestTy->isFloatingPoint()) {
+ if (DestTy == Type::FloatTy)
+ return ConstantFP::get(DestTy, BitsToFloat(CI->getZExtValue()));
+ assert(DestTy == Type::DoubleTy && "Unknown FP type!");
+ return ConstantFP::get(DestTy, BitsToDouble(CI->getZExtValue()));
+ }
+ // Otherwise, can't fold this (packed?)
+ return 0;
}
- break;
+
+ // Handle ConstantFP input.
+ if (const ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
+ // FP -> Integral.
+ if (DestTy->isIntegral()) {
+ if (DestTy == Type::FloatTy)
+ return ConstantInt::get(DestTy, FloatToBits(FP->getValue()));
+ assert(DestTy == Type::DoubleTy && "Unknown FP type!");
+ return ConstantInt::get(DestTy, DoubleToBits(FP->getValue()));
+ }
+ }
+ return 0;
default:
assert(!"Invalid CE CastInst opcode");
break;