aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/Instructions.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2006-11-27 01:05:10 +0000
committerReid Spencer <rspencer@reidspencer.com>2006-11-27 01:05:10 +0000
commit3da59db637a887474c1b1346c1f3ccf53b6c4663 (patch)
treeb061e2133efdb9ea9bb334c1b15ceea881bb88f8 /lib/VMCore/Instructions.cpp
parent5fed9b90447a9a95a1f670ccd9c23aea8c937451 (diff)
downloadexternal_llvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.tar.gz
external_llvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.tar.bz2
external_llvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.zip
For PR950:
The long awaited CAST patch. This introduces 12 new instructions into LLVM to replace the cast instruction. Corresponding changes throughout LLVM are provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the exception of 175.vpr which fails only on a slight floating point output difference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Instructions.cpp')
-rw-r--r--lib/VMCore/Instructions.cpp601
1 files changed, 583 insertions, 18 deletions
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index f559c6324e..d421adb291 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1226,18 +1226,571 @@ bool BinaryOperator::swapOperands() {
// CastInst Class
//===----------------------------------------------------------------------===//
-/// isTruncIntCast - Return true if this is a truncating integer cast
-/// instruction, e.g. a cast from long to uint.
-bool CastInst::isTruncIntCast() const {
- // The dest type has to be integral, the input has to be integer.
- if (!getType()->isIntegral() || !getOperand(0)->getType()->isInteger())
+// Just determine if this cast only deals with integral->integral conversion.
+bool CastInst::isIntegerCast() const {
+ switch (getOpcode()) {
+ default: return false;
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::Trunc:
+ return true;
+ case Instruction::BitCast:
+ return getOperand(0)->getType()->isIntegral() && getType()->isIntegral();
+ }
+}
+
+bool CastInst::isLosslessCast() const {
+ // Only BitCast can be lossless, exit fast if we're not BitCast
+ if (getOpcode() != Instruction::BitCast)
return false;
- // Has to be large to smaller.
- return getOperand(0)->getType()->getPrimitiveSizeInBits() >
- getType()->getPrimitiveSizeInBits();
+ // Identity cast is always lossless
+ const Type* SrcTy = getOperand(0)->getType();
+ const Type* DstTy = getType();
+ if (SrcTy == DstTy)
+ return true;
+
+ // The remaining possibilities are lossless if the typeID of the source type
+ // matches the type ID of the destination in size and fundamental type. This
+ // prevents things like int -> ptr, int -> float, packed -> int, mismatched
+ // packed types of the same size, and etc.
+ switch (SrcTy->getTypeID()) {
+ case Type::UByteTyID: return DstTy == Type::SByteTy;
+ case Type::SByteTyID: return DstTy == Type::UByteTy;
+ case Type::UShortTyID: return DstTy == Type::ShortTy;
+ case Type::ShortTyID: return DstTy == Type::UShortTy;
+ case Type::UIntTyID: return DstTy == Type::IntTy;
+ case Type::IntTyID: return DstTy == Type::UIntTy;
+ case Type::ULongTyID: return DstTy == Type::LongTy;
+ case Type::LongTyID: return DstTy == Type::ULongTy;
+ case Type::PointerTyID: return isa<PointerType>(DstTy);
+ default:
+ break;
+ }
+ return false; // Other types have no identity values
+}
+
+/// This function determines if the CastInst does not require any bits to be
+/// changed in order to effect the cast. Essentially, it identifies cases where
+/// no code gen is necessary for the cast, hence the name no-op cast. For
+/// example, the following are all no-op casts:
+/// # bitcast uint %X, int
+/// # bitcast uint* %x, sbyte*
+/// # bitcast packed< 2 x int > %x, packed< 4 x short>
+/// # ptrtoint uint* %x, uint ; on 32-bit plaforms only
+/// @brief Determine if a cast is a no-op.
+bool CastInst::isNoopCast(const Type *IntPtrTy) const {
+ switch (getOpcode()) {
+ default:
+ assert(!"Invalid CastOp");
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ return false; // These always modify bits
+ case Instruction::BitCast:
+ return true; // BitCast never modifies bits.
+ case Instruction::PtrToInt:
+ return IntPtrTy->getPrimitiveSizeInBits() ==
+ getType()->getPrimitiveSizeInBits();
+ case Instruction::IntToPtr:
+ return IntPtrTy->getPrimitiveSizeInBits() ==
+ getOperand(0)->getType()->getPrimitiveSizeInBits();
+ }
+}
+
+/// This function determines if a pair of casts can be eliminated and what
+/// opcode should be used in the elimination. This assumes that there are two
+/// instructions like this:
+/// * %F = firstOpcode SrcTy %x to MidTy
+/// * %S = secondOpcode MidTy %F to DstTy
+/// The function returns a resultOpcode so these two casts can be replaced with:
+/// * %Replacement = resultOpcode %SrcTy %x to DstTy
+/// If no such cast is permited, the function returns 0.
+unsigned CastInst::isEliminableCastPair(
+ Instruction::CastOps firstOp, Instruction::CastOps secondOp,
+ const Type *SrcTy, const Type *MidTy, const Type *DstTy, const Type *IntPtrTy)
+{
+ // Define the 144 possibilities for these two cast instructions. The values
+ // in this matrix determine what to do in a given situation and select the
+ // case in the switch below. The rows correspond to firstOp, the columns
+ // correspond to secondOp. In looking at the table below, keep in mind
+ // the following cast properties:
+ //
+ // Size Compare Source Destination
+ // Operator Src ? Size Type Sign Type Sign
+ // -------- ------------ ------------------- ---------------------
+ // TRUNC > Integer Any Integral Any
+ // ZEXT < Integral Unsigned Integer Any
+ // SEXT < Integral Signed Integer Any
+ // FPTOUI n/a FloatPt n/a Integral Unsigned
+ // FPTOSI n/a FloatPt n/a Integral Signed
+ // UITOFP n/a Integral Unsigned FloatPt n/a
+ // SITOFP n/a Integral Signed FloatPt n/a
+ // FPTRUNC > FloatPt n/a FloatPt n/a
+ // FPEXT < FloatPt n/a FloatPt n/a
+ // PTRTOINT n/a Pointer n/a Integral Unsigned
+ // INTTOPTR n/a Integral Unsigned Pointer n/a
+ // BITCONVERT = FirstClass n/a FirstClass n/a
+ //
+ const unsigned numCastOps =
+ Instruction::CastOpsEnd - Instruction::CastOpsBegin;
+ static const uint8_t CastResults[numCastOps][numCastOps] = {
+ // T F F U S F F P I B -+
+ // R Z S P P I I T P 2 N T |
+ // U E E 2 2 2 2 R E I T C +- secondOp
+ // N X X U S F F N X N 2 V |
+ // C T T I I P P C T T P T -+
+ { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // Trunc -+
+ { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3 }, // ZExt |
+ { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3 }, // SExt |
+ { 0, 1, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToUI |
+ { 0, 0, 1,99,99, 0, 0,99,99,99, 0, 3 }, // FPToSI |
+ { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // UIToFP +- firstOp
+ { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // SIToFP |
+ { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4 }, // FPTrunc |
+ { 99,99,99, 2, 2,99,99,10, 2,99,99, 4 }, // FPExt |
+ { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3 }, // PtrToInt |
+ { 99,99,99,99,99,99,99,99,99,13,99,12 }, // IntToPtr |
+ { 5, 5, 5, 6, 6, 5, 5, 6, 6,11, 5, 1 }, // BitCast -+
+ };
+
+ int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin]
+ [secondOp-Instruction::CastOpsBegin];
+ switch (ElimCase) {
+ case 0:
+ // categorically disallowed
+ return 0;
+ case 1:
+ // allowed, use first cast's opcode
+ return firstOp;
+ case 2:
+ // allowed, use second cast's opcode
+ return secondOp;
+ case 3:
+ // no-op cast in second op implies firstOp as long as the DestTy
+ // is integer
+ if (DstTy->isInteger())
+ return firstOp;
+ return 0;
+ case 4:
+ // no-op cast in second op implies firstOp as long as the DestTy
+ // is floating point
+ if (DstTy->isFloatingPoint())
+ return firstOp;
+ return 0;
+ case 5:
+ // no-op cast in first op implies secondOp as long as the SrcTy
+ // is an integer
+ if (SrcTy->isInteger())
+ return secondOp;
+ return 0;
+ case 6:
+ // no-op cast in first op implies secondOp as long as the SrcTy
+ // is a floating point
+ if (SrcTy->isFloatingPoint())
+ return secondOp;
+ return 0;
+ case 7: {
+ // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
+ unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
+ unsigned MidSize = MidTy->getPrimitiveSizeInBits();
+ if (MidSize >= PtrSize)
+ return Instruction::BitCast;
+ return 0;
+ }
+ case 8: {
+ // ext, trunc -> bitcast, if the SrcTy and DstTy are same size
+ // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy)
+ // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy)
+ unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ if (SrcSize == DstSize)
+ return Instruction::BitCast;
+ else if (SrcSize < DstSize)
+ return firstOp;
+ return secondOp;
+ }
+ case 9: // zext, sext -> zext, because sext can't sign extend after zext
+ return Instruction::ZExt;
+ case 10:
+ // fpext followed by ftrunc is allowed if the bit size returned to is
+ // the same as the original, in which case its just a bitcast
+ if (SrcTy == DstTy)
+ return Instruction::BitCast;
+ return 0; // If the types are not the same we can't eliminate it.
+ case 11:
+ // bitcast followed by ptrtoint is allowed as long as the bitcast
+ // is a pointer to pointer cast.
+ if (isa<PointerType>(SrcTy) && isa<PointerType>(MidTy))
+ return secondOp;
+ return 0;
+ case 12:
+ // inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast
+ if (isa<PointerType>(MidTy) && isa<PointerType>(DstTy))
+ return firstOp;
+ return 0;
+ case 13: {
+ // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
+ unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
+ unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ if (SrcSize <= PtrSize && SrcSize == DstSize)
+ return Instruction::BitCast;
+ return 0;
+ }
+ case 99:
+ // cast combination can't happen (error in input). This is for all cases
+ // where the MidTy is not the same for the two cast instructions.
+ assert(!"Invalid Cast Combination");
+ return 0;
+ default:
+ assert(!"Error in CastResults table!!!");
+ return 0;
+ }
+ return 0;
+}
+
+CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
+ const std::string &Name, Instruction *InsertBefore) {
+ // Construct and return the appropriate CastInst subclass
+ switch (op) {
+ case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
+ case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore);
+ case SExt: return new SExtInst (S, Ty, Name, InsertBefore);
+ case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore);
+ case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore);
+ case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore);
+ case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore);
+ case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore);
+ case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore);
+ case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore);
+ case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore);
+ case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore);
+ default:
+ assert(!"Invalid opcode provided");
+ }
+ return 0;
}
+CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
+ const std::string &Name, BasicBlock *InsertAtEnd) {
+ // Construct and return the appropriate CastInst subclass
+ switch (op) {
+ case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd);
+ case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd);
+ case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd);
+ case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd);
+ case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd);
+ case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd);
+ case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd);
+ case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd);
+ case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd);
+ case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd);
+ case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd);
+ case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd);
+ default:
+ assert(!"Invalid opcode provided");
+ }
+ return 0;
+}
+
+// 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:
+// checkCast( getCastOpcode(Val, Ty), Val, 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) {
+ // Get the bit sizes, we'll need these
+ const Type *SrcTy = Src->getType();
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
+
+ // Run through the possibilities ...
+ if (DestTy->isIntegral()) { // Casting to integral
+ if (SrcTy->isIntegral()) { // Casting from integral
+ if (DestBits < SrcBits)
+ return Trunc; // int -> smaller int
+ else if (DestBits > SrcBits) { // its an extension
+ if (SrcTy->isSigned())
+ return SExt; // signed -> SEXT
+ else
+ return ZExt; // unsigned -> ZEXT
+ } else {
+ return BitCast; // Same size, No-op cast
+ }
+ } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ if (DestTy->isSigned())
+ return FPToSI; // FP -> sint
+ else
+ return FPToUI; // FP -> uint
+ } else if (const PackedType *PTy = dyn_cast<PackedType>(SrcTy)) {
+ assert(DestBits == PTy->getBitWidth() &&
+ "Casting packed to integer of different width");
+ return BitCast; // Same size, no-op cast
+ } else {
+ assert(isa<PointerType>(SrcTy) &&
+ "Casting from a value that is not first-class type");
+ return PtrToInt; // ptr -> int
+ }
+ } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
+ if (SrcTy->isIntegral()) { // Casting from integral
+ if (SrcTy->isSigned())
+ return SIToFP; // sint -> FP
+ else
+ return UIToFP; // uint -> FP
+ } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ if (DestBits < SrcBits) {
+ return FPTrunc; // FP -> smaller FP
+ } else if (DestBits > SrcBits) {
+ return FPExt; // FP -> larger FP
+ } else {
+ return BitCast; // same size, no-op cast
+ }
+ } else if (const PackedType *PTy = dyn_cast<PackedType>(SrcTy)) {
+ assert(DestBits == PTy->getBitWidth() &&
+ "Casting packed to floating point of different width");
+ return BitCast; // same size, no-op cast
+ } else {
+ assert(0 && "Casting pointer or non-first class to float");
+ }
+ } else if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) {
+ if (const PackedType *SrcPTy = dyn_cast<PackedType>(SrcTy)) {
+ assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
+ "Casting packed to packed of different widths");
+ return BitCast; // packed -> packed
+ } else if (DestPTy->getBitWidth() == SrcBits) {
+ return BitCast; // float/int -> packed
+ } else {
+ assert(!"Illegal cast to packed (wrong type or size)");
+ }
+ } else if (isa<PointerType>(DestTy)) {
+ if (isa<PointerType>(SrcTy)) {
+ return BitCast; // ptr -> ptr
+ } else if (SrcTy->isIntegral()) {
+ return IntToPtr; // int -> ptr
+ } else {
+ assert(!"Casting pointer to other than pointer or int");
+ }
+ } else {
+ assert(!"Casting to type that is not first-class");
+ }
+
+ // If we fall through to here we probably hit an assertion cast above
+ // and assertions are not turned on. Anything we return is an error, so
+ // BitCast is as good a choice as any.
+ return BitCast;
+}
+
+//===----------------------------------------------------------------------===//
+// CastInst SubClass Constructors
+//===----------------------------------------------------------------------===//
+
+/// Check that the construction parameters for a CastInst are correct. This
+/// could be broken out into the separate constructors but it is useful to have
+/// it in one place and to eliminate the redundant code for getting the sizes
+/// of the types involved.
+static bool
+checkCast(Instruction::CastOps op, Value *S, const Type *DstTy) {
+
+ // Check for type sanity on the arguments
+ const Type *SrcTy = S->getType();
+ if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType())
+ return false;
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+
+ // Switch on the opcode provided
+ switch (op) {
+ default: return false; // This is an input error
+ case Instruction::Trunc:
+ return SrcTy->isInteger() && DstTy->isIntegral() && SrcBitSize > DstBitSize;
+ case Instruction::ZExt:
+ return SrcTy->isIntegral() && DstTy->isInteger() && SrcBitSize < DstBitSize;
+ case Instruction::SExt:
+ return SrcTy->isIntegral() && DstTy->isInteger() && SrcBitSize < DstBitSize;
+ case Instruction::FPTrunc:
+ return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() &&
+ SrcBitSize > DstBitSize;
+ case Instruction::FPExt:
+ return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() &&
+ SrcBitSize < DstBitSize;
+ case Instruction::UIToFP:
+ return SrcTy->isIntegral() && DstTy->isFloatingPoint();
+ case Instruction::SIToFP:
+ return SrcTy->isIntegral() && DstTy->isFloatingPoint();
+ case Instruction::FPToUI:
+ return SrcTy->isFloatingPoint() && DstTy->isIntegral();
+ case Instruction::FPToSI:
+ return SrcTy->isFloatingPoint() && DstTy->isIntegral();
+ case Instruction::PtrToInt:
+ return isa<PointerType>(SrcTy) && DstTy->isIntegral();
+ case Instruction::IntToPtr:
+ return SrcTy->isIntegral() && isa<PointerType>(DstTy);
+ case Instruction::BitCast:
+ // BitCast implies a no-op cast of type only. No bits change.
+ // However, you can't cast pointers to anything but pointers.
+ if (isa<PointerType>(SrcTy) != isa<PointerType>(DstTy))
+ return false;
+
+ // Now we know we're not dealing with a pointer/non-poiner mismatch. In all
+ // these cases, the cast is okay if the source and destination bit widths
+ // are identical.
+ return SrcBitSize == DstBitSize;
+ }
+}
+
+TruncInst::TruncInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, Trunc, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal Trunc");
+}
+
+TruncInst::TruncInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, Trunc, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal Trunc");
+}
+
+ZExtInst::ZExtInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, ZExt, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal ZExt");
+}
+
+ZExtInst::ZExtInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, ZExt, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal ZExt");
+}
+SExtInst::SExtInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, SExt, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal SExt");
+}
+
+SExtInst::SExtInst::SExtInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, SExt, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal SExt");
+}
+
+FPTruncInst::FPTruncInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPTrunc");
+}
+
+FPTruncInst::FPTruncInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPTrunc");
+}
+
+FPExtInst::FPExtInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, FPExt, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPExt");
+}
+
+FPExtInst::FPExtInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPExt");
+}
+
+UIToFPInst::UIToFPInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, UIToFP, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal UIToFP");
+}
+
+UIToFPInst::UIToFPInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal UIToFP");
+}
+
+SIToFPInst::SIToFPInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, SIToFP, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal SIToFP");
+}
+
+SIToFPInst::SIToFPInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, SIToFP, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal SIToFP");
+}
+
+FPToUIInst::FPToUIInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, FPToUI, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToUI");
+}
+
+FPToUIInst::FPToUIInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, FPToUI, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToUI");
+}
+
+FPToSIInst::FPToSIInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, FPToSI, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToSI");
+}
+
+FPToSIInst::FPToSIInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, FPToSI, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToSI");
+}
+
+PtrToIntInst::PtrToIntInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal PtrToInt");
+}
+
+PtrToIntInst::PtrToIntInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, PtrToInt, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal PtrToInt");
+}
+
+IntToPtrInst::IntToPtrInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal IntToPtr");
+}
+
+IntToPtrInst::IntToPtrInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, IntToPtr, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal IntToPtr");
+}
+
+BitCastInst::BitCastInst(
+ Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+) : CastInst(Ty, BitCast, S, Name, InsertBefore) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal BitCast");
+}
+
+BitCastInst::BitCastInst(
+ Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+) : CastInst(Ty, BitCast, S, Name, InsertAtEnd) {
+ assert(checkCast(getOpcode(), S, Ty) && "Illegal BitCast");
+}
//===----------------------------------------------------------------------===//
// SetCondInst Class
@@ -1608,16 +2161,28 @@ CmpInst* CmpInst::clone() const {
Ops[0], Ops[1]);
}
-MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
-AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); }
-FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); }
-LoadInst *LoadInst::clone() const { return new LoadInst(*this); }
-StoreInst *StoreInst::clone() const { return new StoreInst(*this); }
-CastInst *CastInst::clone() const { return new CastInst(*this); }
-CallInst *CallInst::clone() const { return new CallInst(*this); }
-ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); }
-SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
-VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
+MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
+AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); }
+FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); }
+LoadInst *LoadInst::clone() const { return new LoadInst(*this); }
+StoreInst *StoreInst::clone() const { return new StoreInst(*this); }
+CastInst *TruncInst::clone() const { return new TruncInst(*this); }
+CastInst *ZExtInst::clone() const { return new ZExtInst(*this); }
+CastInst *SExtInst::clone() const { return new SExtInst(*this); }
+CastInst *FPTruncInst::clone() const { return new FPTruncInst(*this); }
+CastInst *FPExtInst::clone() const { return new FPExtInst(*this); }
+CastInst *UIToFPInst::clone() const { return new UIToFPInst(*this); }
+CastInst *SIToFPInst::clone() const { return new SIToFPInst(*this); }
+CastInst *FPToUIInst::clone() const { return new FPToUIInst(*this); }
+CastInst *FPToSIInst::clone() const { return new FPToSIInst(*this); }
+CastInst *PtrToIntInst::clone() const { return new PtrToIntInst(*this); }
+CastInst *IntToPtrInst::clone() const { return new IntToPtrInst(*this); }
+CastInst *BitCastInst::clone() const { return new BitCastInst(*this); }
+CallInst *CallInst::clone() const { return new CallInst(*this); }
+ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); }
+SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
+VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
+
ExtractElementInst *ExtractElementInst::clone() const {
return new ExtractElementInst(*this);
}