aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Constants.h18
-rw-r--r--include/llvm/InstrTypes.h48
-rw-r--r--lib/VMCore/Constants.cpp22
-rw-r--r--lib/VMCore/Instructions.cpp48
4 files changed, 134 insertions, 2 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index d4744d4d72..47255de655 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -541,6 +541,24 @@ public:
const Type *Ty ///< The type to which the constant is converted
);
+ // @brief Create a ZExt or BitCast cast constant expression
+ static Constant *getZExtOrBitCast(
+ Constant *C, ///< The constant to zext or bitcast
+ const Type *Ty ///< The type to zext or bitcast C to
+ );
+
+ // @brief Create a SExt or BitCast cast constant expression
+ static Constant *getSExtOrBitCast(
+ Constant *C, ///< The constant to zext or bitcast
+ const Type *Ty ///< The type to zext or bitcast C to
+ );
+
+ // @brief Create a Trunc or BitCast cast constant expression
+ static Constant *getTruncOrBitCast(
+ Constant *C, ///< The constant to zext or bitcast
+ const Type *Ty ///< The type to zext or bitcast C to
+ );
+
// This method uses the CastInst::getCastOpcode method to infer the
// cast opcode to use.
// @brief Get a ConstantExpr Conversion operator that casts C to Ty
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 07d13da59d..0878a9c4b5 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -299,6 +299,54 @@ public:
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *createZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *createZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *createSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *createSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *createTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *createTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
/// Returns the opcode necessary to cast Val into Ty using usual casting
/// rules.
static Instruction::CastOps getCastOpcode(
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 17a5eaeabf..966108748b 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1534,6 +1534,24 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
return 0;
}
+Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
+ if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return getCast(Instruction::BitCast, C, Ty);
+ return getCast(Instruction::ZExt, C, Ty);
+}
+
+Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
+ if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return getCast(Instruction::BitCast, C, Ty);
+ return getCast(Instruction::SExt, C, Ty);
+}
+
+Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
+ if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return getCast(Instruction::BitCast, C, Ty);
+ return getCast(Instruction::Trunc, C, Ty);
+}
+
Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
assert(C->getType()->isInteger() && "Trunc operand must be integer");
assert(Ty->isIntegral() && "Trunc produces only integral");
@@ -1616,14 +1634,14 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
// can't cast pointers to anything but pointers.
const Type *SrcTy = C->getType();
assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) &&
- "Bitcast cannot cast pointer to non-pointer and vice versa");
+ "BitCast cannot cast pointer to non-pointer and vice versa");
// Now we know we're not dealing with mismatched pointer casts (ptr->nonptr
// or nonptr->ptr). For all the other types, the cast is okay if source and
// destination bit widths are identical.
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
- assert(SrcBitSize == DstBitSize && "Bitcast requies types of same width");
+ assert(SrcBitSize == DstBitSize && "BitCast requies types of same width");
return getFoldedCast(Instruction::BitCast, C, DstTy);
}
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index de1ebced7b..8c1f47d8af 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1500,6 +1500,54 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
return 0;
}
+CastInst *CastInst::createZExtOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ Instruction *InsertBefore) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+ return create(Instruction::ZExt, S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createZExtOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+ return create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
+}
+
+CastInst *CastInst::createSExtOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ Instruction *InsertBefore) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+ return create(Instruction::SExt, S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createSExtOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+ return create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
+}
+
+CastInst *CastInst::createTruncOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ Instruction *InsertBefore) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+ return create(Instruction::Trunc, S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createTruncOrBitCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+ return create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
+}
+
// Provide a way to get a "cast" where the cast opcode is inferred from the
// types and size of the operand. This, basically, is a parallel of the
// logic in the checkCast function below. This axiom should hold: