diff options
Diffstat (limited to 'lib/IR/Instructions.cpp')
-rw-r--r-- | lib/IR/Instructions.cpp | 78 |
1 files changed, 65 insertions, 13 deletions
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index a5ceacb..57a4f0b 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -364,8 +364,9 @@ bool CallInst::paramHasAttr(unsigned i, Attribute::AttrKind A) const { /// IsConstantOne - Return true only if val is constant int 1 static bool IsConstantOne(Value *val) { - assert(val && "IsConstantOne does not work with NULL val"); - return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne(); + assert(val && "IsConstantOne does not work with nullptr val"); + const ConstantInt *CVal = dyn_cast<ConstantInt>(val); + return CVal && CVal->isOne(); } static Instruction *createMalloc(Instruction *InsertBefore, @@ -418,7 +419,7 @@ static Instruction *createMalloc(Instruction *InsertBefore, Value *MallocFunc = MallocF; if (!MallocFunc) // prototype malloc as "void *malloc(size_t)" - MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL); + MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, nullptr); PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); CallInst *MCall = nullptr; Instruction *Result = nullptr; @@ -491,7 +492,7 @@ static Instruction* createFree(Value* Source, Instruction *InsertBefore, Type *VoidTy = Type::getVoidTy(M->getContext()); Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); // prototype free as "void free(void*)" - Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL); + Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, nullptr); CallInst* Result = nullptr; Value *PtrCast = Source; if (InsertBefore) { @@ -2030,6 +2031,39 @@ bool BinaryOperator::isExact() const { return cast<PossiblyExactOperator>(this)->isExact(); } +void BinaryOperator::copyIRFlags(const Value *V) { + // Copy the wrapping flags. + if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { + setHasNoSignedWrap(OB->hasNoSignedWrap()); + setHasNoUnsignedWrap(OB->hasNoUnsignedWrap()); + } + + // Copy the exact flag. + if (auto *PE = dyn_cast<PossiblyExactOperator>(V)) + setIsExact(PE->isExact()); + + // Copy the fast-math flags. + if (auto *FP = dyn_cast<FPMathOperator>(V)) + copyFastMathFlags(FP->getFastMathFlags()); +} + +void BinaryOperator::andIRFlags(const Value *V) { + if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { + setHasNoSignedWrap(hasNoSignedWrap() & OB->hasNoSignedWrap()); + setHasNoUnsignedWrap(hasNoUnsignedWrap() & OB->hasNoUnsignedWrap()); + } + + if (auto *PE = dyn_cast<PossiblyExactOperator>(V)) + setIsExact(isExact() & PE->isExact()); + + if (auto *FP = dyn_cast<FPMathOperator>(V)) { + FastMathFlags FM = getFastMathFlags(); + FM &= FP->getFastMathFlags(); + copyFastMathFlags(FM); + } +} + + //===----------------------------------------------------------------------===// // FPMathOperator Class //===----------------------------------------------------------------------===// @@ -2039,7 +2073,7 @@ bool BinaryOperator::isExact() const { /// default precision. float FPMathOperator::getFPAccuracy() const { const MDNode *MD = - cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); + cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath); if (!MD) return 0.0; ConstantFP *Accuracy = cast<ConstantFP>(MD->getOperand(0)); @@ -2478,11 +2512,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, 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 +2530,36 @@ CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, 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() && |