aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Constants.cpp13
-rw-r--r--lib/VMCore/Instructions.cpp23
2 files changed, 26 insertions, 10 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 71615b2c4a..10fdda504c 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1486,9 +1486,11 @@ static inline Constant *getFoldedCast(
return ExprConstants->getOrCreate(Ty, Key);
}
-Constant *ConstantExpr::getCast( Constant *C, const Type *Ty ) {
+Constant *ConstantExpr::getInferredCast(Constant *C, bool SrcIsSigned,
+ const Type *Ty, bool DestIsSigned) {
// Note: we can't inline this because it requires the Instructions.h header
- return getCast(CastInst::getCastOpcode(C, Ty), C, Ty);
+ return getCast(
+ CastInst::getCastOpcode(C, SrcIsSigned, Ty, DestIsSigned), C, Ty);
}
Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
@@ -1612,10 +1614,9 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
Constant *ConstantExpr::getSizeOf(const Type *Ty) {
// sizeof is implemented as: (ulong) gep (Ty*)null, 1
- return getCast(
- getGetElementPtr(getNullValue(PointerType::get(Ty)),
- std::vector<Constant*>(1, ConstantInt::get(Type::UIntTy, 1))),
- Type::ULongTy);
+ return getCast(Instruction::PtrToInt, getGetElementPtr(getNullValue(
+ PointerType::get(Ty)), std::vector<Constant*>(1,
+ ConstantInt::get(Type::UIntTy, 1))), Type::ULongTy);
}
Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index f486642317..de1ebced7b 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1507,7 +1507,8 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
// should not assert in checkCast. In other words, this produces a "correct"
// casting opcode for the arguments passed to it.
Instruction::CastOps
-CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
+CastInst::getCastOpcode(
+ const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
// Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
@@ -1519,7 +1520,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
if (DestBits < SrcBits)
return Trunc; // int -> smaller int
else if (DestBits > SrcBits) { // its an extension
- if (SrcTy->isSigned())
+ if (SrcIsSigned)
return SExt; // signed -> SEXT
else
return ZExt; // unsigned -> ZEXT
@@ -1527,7 +1528,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
return BitCast; // Same size, No-op cast
}
} else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
- if (DestTy->isSigned())
+ if (DestIsSigned)
return FPToSI; // FP -> sint
else
return FPToUI; // FP -> uint
@@ -1542,7 +1543,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
}
} else if (DestTy->isFloatingPoint()) { // Casting to floating pt
if (SrcTy->isIntegral()) { // Casting from integral
- if (SrcTy->isSigned())
+ if (SrcIsSigned)
return SIToFP; // sint -> FP
else
return UIToFP; // uint -> FP
@@ -1649,6 +1650,20 @@ checkCast(Instruction::CastOps op, Value *S, const Type *DstTy) {
}
}
+CastInst *CastInst::createInferredCast(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore)
+{
+ return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
+ Name, InsertBefore);
+}
+
+CastInst *CastInst::createInferredCast(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
+{
+ return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
+ Name, InsertAtEnd);
+}
+
TruncInst::TruncInst(
Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
) : CastInst(Ty, Trunc, S, Name, InsertBefore) {