Index: include/llvm/Analysis/TargetFolder.h =================================================================== --- include/llvm/Analysis/TargetFolder.h +++ include/llvm/Analysis/TargetFolder.h @@ -211,6 +211,13 @@ return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); } + Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C, + Type *DestTy) const { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy)); + } + //===--------------------------------------------------------------------===// // Compare Instructions //===--------------------------------------------------------------------===// Index: include/llvm/IR/ConstantFolder.h =================================================================== --- include/llvm/IR/ConstantFolder.h +++ include/llvm/IR/ConstantFolder.h @@ -159,6 +159,12 @@ Constant *CreatePointerCast(Constant *C, Type *DestTy) const { return ConstantExpr::getPointerCast(C, DestTy); } + + Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C, + Type *DestTy) const { + return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy); + } + Constant *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { return ConstantExpr::getIntegerCast(C, DestTy, isSigned); Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -1198,6 +1198,21 @@ return Insert(Folder.CreatePointerCast(VC, DestTy), Name); return Insert(CastInst::CreatePointerCast(V, DestTy), Name); } + + Value *CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, + const Twine &Name = "") { + if (V->getType() == DestTy) + return V; + + if (Constant *VC = dyn_cast(V)) { + return Insert(Folder.CreatePointerBitCastOrAddrSpaceCast(VC, DestTy), + Name); + } + + return Insert(CastInst::CreatePointerBitCastOrAddrSpaceCast(V, DestTy), + Name); + } + Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name = "") { if (V->getType() == DestTy) Index: include/llvm/IR/InstrTypes.h =================================================================== --- include/llvm/IR/InstrTypes.h +++ include/llvm/IR/InstrTypes.h @@ -475,6 +475,22 @@ Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); + /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + static CastInst *CreatePointerBitCastOrAddrSpaceCast( + Value *S, ///< The pointer value to be casted (operand 0) + Type *Ty, ///< The type to which operand is casted + const Twine &Name, ///< The name for the instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + static CastInst *CreatePointerBitCastOrAddrSpaceCast( + Value *S, ///< The pointer value to be casted (operand 0) + Type *Ty, ///< The type to which cast should be made + const Twine &Name = "", ///< Name for the instruction + Instruction *InsertBefore = 0 ///< Place to insert the instruction + ); + /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The pointer value to be casted (operand 0) Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -2478,11 +2478,7 @@ if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd); - Type *STy = S->getType(); - if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) - return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); - - return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); + return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertAtEnd); } /// @brief Create a BitCast or a PtrToInt cast instruction @@ -2500,14 +2496,36 @@ if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); - Type *STy = S->getType(); - if (STy->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore); +} + +CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( + Value *S, Type *Ty, + const Twine &Name, + BasicBlock *InsertAtEnd) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) + return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); + + return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); +} + +CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( + Value *S, Type *Ty, + const Twine &Name, + Instruction *InsertBefore) { + assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); + assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); + + if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } -CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, +CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned, const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&