diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 5648d992b95..24a8803c4bb 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -664,32 +664,35 @@ public: /// getAlignOf constant expr - computes the alignment of a type in a target /// independent way (Note: the return type is an i64). - static Constant *getAlignOf(const Type* Ty); + static Constant *getAlignOf(const Type *Ty); /// getSizeOf constant expr - computes the (alloc) size of a type (in /// address-units, not bits) in a target independent way (Note: the return /// type is an i64). /// - static Constant *getSizeOf(const Type* Ty); + static Constant *getSizeOf(const Type *Ty); /// getOffsetOf constant expr - computes the offset of a struct field in a /// target independent way (Note: the return type is an i64). /// - static Constant *getOffsetOf(const StructType* STy, unsigned FieldNo); + static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo); /// getOffsetOf constant expr - This is a generalized form of getOffsetOf, /// which supports any aggregate type, and any Constant index. /// - static Constant *getOffsetOf(const Type* Ty, Constant *FieldNo); + static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo); - static Constant *getNeg(Constant *C); + static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false); static Constant *getFNeg(Constant *C); static Constant *getNot(Constant *C); - static Constant *getAdd(Constant *C1, Constant *C2); + static Constant *getAdd(Constant *C1, Constant *C2, + bool HasNUW = false, bool HasNSW = false); static Constant *getFAdd(Constant *C1, Constant *C2); - static Constant *getSub(Constant *C1, Constant *C2); + static Constant *getSub(Constant *C1, Constant *C2, + bool HasNUW = false, bool HasNSW = false); static Constant *getFSub(Constant *C1, Constant *C2); - static Constant *getMul(Constant *C1, Constant *C2); + static Constant *getMul(Constant *C1, Constant *C2, + bool HasNUW = false, bool HasNSW = false); static Constant *getFMul(Constant *C1, Constant *C2); static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false); static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false); @@ -700,7 +703,8 @@ public: static Constant *getAnd(Constant *C1, Constant *C2); static Constant *getOr(Constant *C1, Constant *C2); static Constant *getXor(Constant *C1, Constant *C2); - static Constant *getShl(Constant *C1, Constant *C2); + static Constant *getShl(Constant *C1, Constant *C2, + bool HasNUW = false, bool HasNSW = false); static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false); static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false); static Constant *getTrunc (Constant *C, const Type *Ty); @@ -716,16 +720,32 @@ public: static Constant *getIntToPtr(Constant *C, const Type *Ty); static Constant *getBitCast (Constant *C, const Type *Ty); - static Constant *getNSWNeg(Constant *C); - static Constant *getNUWNeg(Constant *C); - static Constant *getNSWAdd(Constant *C1, Constant *C2); - static Constant *getNUWAdd(Constant *C1, Constant *C2); - static Constant *getNSWSub(Constant *C1, Constant *C2); - static Constant *getNUWSub(Constant *C1, Constant *C2); - static Constant *getNSWMul(Constant *C1, Constant *C2); - static Constant *getNUWMul(Constant *C1, Constant *C2); - static Constant *getNSWShl(Constant *C1, Constant *C2); - static Constant *getNUWShl(Constant *C1, Constant *C2); + static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); } + static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); } + static Constant *getNSWAdd(Constant *C1, Constant *C2) { + return getAdd(C1, C2, false, true); + } + static Constant *getNUWAdd(Constant *C1, Constant *C2) { + return getAdd(C1, C2, true, false); + } + static Constant *getNSWSub(Constant *C1, Constant *C2) { + return getSub(C1, C2, false, true); + } + static Constant *getNUWSub(Constant *C1, Constant *C2) { + return getSub(C1, C2, true, false); + } + static Constant *getNSWMul(Constant *C1, Constant *C2) { + return getMul(C1, C2, false, true); + } + static Constant *getNUWMul(Constant *C1, Constant *C2) { + return getMul(C1, C2, true, false); + } + static Constant *getNSWShl(Constant *C1, Constant *C2) { + return getShl(C1, C2, false, true); + } + static Constant *getNUWShl(Constant *C1, Constant *C2) { + return getShl(C1, C2, true, false); + } static Constant *getExactSDiv(Constant *C1, Constant *C2) { return getSDiv(C1, C2, true); } diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index e56d3f6bce9..bd3765d592d 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -33,38 +33,23 @@ public: // Binary Operators //===--------------------------------------------------------------------===// - Constant *CreateAdd(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getAdd(LHS, RHS); - } - Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNSWAdd(LHS, RHS); - } - Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNUWAdd(LHS, RHS); + Constant *CreateAdd(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW); } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFAdd(LHS, RHS); } - Constant *CreateSub(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getSub(LHS, RHS); - } - Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNSWSub(LHS, RHS); - } - Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNUWSub(LHS, RHS); + Constant *CreateSub(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW); } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFSub(LHS, RHS); } - Constant *CreateMul(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getMul(LHS, RHS); - } - Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNSWMul(LHS, RHS); - } - Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getNUWMul(LHS, RHS); + Constant *CreateMul(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW); } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFMul(LHS, RHS); @@ -89,8 +74,9 @@ public: Constant *CreateFRem(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFRem(LHS, RHS); } - Constant *CreateShl(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getShl(LHS, RHS); + Constant *CreateShl(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW); } Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false) const { @@ -119,14 +105,9 @@ public: // Unary Operators //===--------------------------------------------------------------------===// - Constant *CreateNeg(Constant *C) const { - return ConstantExpr::getNeg(C); - } - Constant *CreateNSWNeg(Constant *C) const { - return ConstantExpr::getNSWNeg(C); - } - Constant *CreateNUWNeg(Constant *C) const { - return ConstantExpr::getNUWNeg(C); + Constant *CreateNeg(Constant *C, + bool HasNUW = false, bool HasNSW = false) const { + return ConstantExpr::getNeg(C, HasNUW, HasNSW); } Constant *CreateFNeg(Constant *C) const { return ConstantExpr::getFNeg(C); diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index c1d2e898e0a..2394a59c09c 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -448,24 +448,30 @@ public: //===--------------------------------------------------------------------===// // Instruction creation methods: Binary Operators //===--------------------------------------------------------------------===// - - Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "") { +private: + BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc, + Value *LHS, Value *RHS, + const Twine &Name, + bool HasNUW, bool HasNSW) { + BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); + if (HasNUW) BO->setHasNoUnsignedWrap(); + if (HasNSW) BO->setHasNoSignedWrap(); + return BO; + } +public: + Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateAdd(LC, RC), Name); - return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name); + return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); + return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, + HasNUW, HasNSW); } Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNSWAdd(LC, RC), Name); - return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name); + return CreateAdd(LHS, RHS, Name, false, true); } Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNUWAdd(LC, RC), Name); - return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name); + return CreateAdd(LHS, RHS, Name, true, false); } Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) @@ -473,23 +479,19 @@ public: return Insert(Folder.CreateFAdd(LC, RC), Name); return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name); } - Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Insert(Folder.CreateSub(LC, RC), Name); - return Insert(BinaryOperator::CreateSub(LHS, RHS), Name); + return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, + HasNUW, HasNSW); } Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNSWSub(LC, RC), Name); - return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name); + return CreateSub(LHS, RHS, Name, false, true); } Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNUWSub(LC, RC), Name); - return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name); + return CreateSub(LHS, RHS, Name, true, false); } Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) @@ -497,23 +499,19 @@ public: return Insert(Folder.CreateFSub(LC, RC), Name); return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name); } - Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Insert(Folder.CreateMul(LC, RC), Name); - return Insert(BinaryOperator::CreateMul(LHS, RHS), Name); + return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, + HasNUW, HasNSW); } Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNSWMul(LC, RC), Name); - return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name); + return CreateMul(LHS, RHS, Name, false, true); } Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { - if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateNUWMul(LC, RC), Name); - return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name); + return CreateMul(LHS, RHS, Name, true, false); } Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) @@ -570,17 +568,23 @@ public: return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); } - Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateShl(LC, RC), Name); - return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); + return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name); + return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name, + HasNUW, HasNSW); } - Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") { - return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name); + Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { + return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, + HasNUW, HasNSW); } - Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") { - return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name); + Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { + return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, + HasNUW, HasNSW); } Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "", @@ -672,20 +676,20 @@ public: return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); } - Value *CreateNeg(Value *V, const Twine &Name = "") { + Value *CreateNeg(Value *V, const Twine &Name = "", + bool HasNUW = false, bool HasNSW = false) { if (Constant *VC = dyn_cast(V)) - return Insert(Folder.CreateNeg(VC), Name); - return Insert(BinaryOperator::CreateNeg(V), Name); + return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name); + BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name); + if (HasNUW) BO->setHasNoUnsignedWrap(); + if (HasNSW) BO->setHasNoSignedWrap(); + return BO; } Value *CreateNSWNeg(Value *V, const Twine &Name = "") { - if (Constant *VC = dyn_cast(V)) - return Insert(Folder.CreateNSWNeg(VC), Name); - return Insert(BinaryOperator::CreateNSWNeg(V), Name); + return CreateNeg(V, Name, false, true); } Value *CreateNUWNeg(Value *V, const Twine &Name = "") { - if (Constant *VC = dyn_cast(V)) - return Insert(Folder.CreateNUWNeg(VC), Name); - return Insert(BinaryOperator::CreateNUWNeg(V), Name); + return CreateNeg(V, Name, true, false); } Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast(V)) diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index efae4b1e3b4..20ca5571ffa 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -46,38 +46,23 @@ public: // Binary Operators //===--------------------------------------------------------------------===// - Constant *CreateAdd(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getAdd(LHS, RHS)); - } - Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNSWAdd(LHS, RHS)); - } - Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNUWAdd(LHS, RHS)); + Constant *CreateAdd(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW)); } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFAdd(LHS, RHS)); } - Constant *CreateSub(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getSub(LHS, RHS)); - } - Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNSWSub(LHS, RHS)); - } - Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNUWSub(LHS, RHS)); + Constant *CreateSub(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW)); } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFSub(LHS, RHS)); } - Constant *CreateMul(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getMul(LHS, RHS)); - } - Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNSWMul(LHS, RHS)); - } - Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getNUWMul(LHS, RHS)); + Constant *CreateMul(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW)); } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFMul(LHS, RHS)); @@ -100,8 +85,9 @@ public: Constant *CreateFRem(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFRem(LHS, RHS)); } - Constant *CreateShl(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getShl(LHS, RHS)); + Constant *CreateShl(Constant *LHS, Constant *RHS, + bool HasNUW = false, bool HasNSW = false) const { + return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW)); } Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ return Fold(ConstantExpr::getLShr(LHS, RHS, isExact)); @@ -128,14 +114,9 @@ public: // Unary Operators //===--------------------------------------------------------------------===// - Constant *CreateNeg(Constant *C) const { - return Fold(ConstantExpr::getNeg(C)); - } - Constant *CreateNSWNeg(Constant *C) const { - return Fold(ConstantExpr::getNSWNeg(C)); - } - Constant *CreateNUWNeg(Constant *C) const { - return Fold(ConstantExpr::getNUWNeg(C)); + Constant *CreateNeg(Constant *C, + bool HasNUW = false, bool HasNSW = false) const { + return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW)); } Constant *CreateFNeg(Constant *C) const { return Fold(ConstantExpr::getFNeg(C)); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 4ce2af10ecf..1cd6b0bc2cf 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -639,58 +639,6 @@ Constant *ConstantVector::get(Constant *const* Vals, unsigned NumVals) { return get(std::vector(Vals, Vals+NumVals)); } -Constant *ConstantExpr::getNSWNeg(Constant *C) { - assert(C->getType()->isIntOrIntVectorTy() && - "Cannot NEG a nonintegral value!"); - return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); -} - -Constant *ConstantExpr::getNUWNeg(Constant *C) { - assert(C->getType()->isIntOrIntVectorTy() && - "Cannot NEG a nonintegral value!"); - return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); -} - -Constant *ConstantExpr::getNSWAdd(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant *ConstantExpr::getNUWAdd(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Add, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant *ConstantExpr::getNSWSub(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant *ConstantExpr::getNUWSub(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Sub, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant *ConstantExpr::getNSWMul(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant *ConstantExpr::getNUWMul(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - -Constant *ConstantExpr::getNSWShl(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Shl, C1, C2, - OverflowingBinaryOperator::NoSignedWrap); -} - -Constant *ConstantExpr::getNUWShl(Constant *C1, Constant *C2) { - return getTy(C1->getType(), Instruction::Shl, C1, C2, - OverflowingBinaryOperator::NoUnsignedWrap); -} - // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into // Constant.h @@ -1823,20 +1771,17 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); } -Constant *ConstantExpr::getNeg(Constant *C) { +Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { assert(C->getType()->isIntOrIntVectorTy() && "Cannot NEG a nonintegral value!"); - return get(Instruction::Sub, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getSub(ConstantFP::getZeroValueForNegation(C->getType()), + C, HasNUW, HasNSW); } Constant *ConstantExpr::getFNeg(Constant *C) { assert(C->getType()->isFPOrFPVectorTy() && "Cannot FNEG a non-floating-point value!"); - return get(Instruction::FSub, - ConstantFP::getZeroValueForNegation(C->getType()), - C); + return getFSub(ConstantFP::getZeroValueForNegation(C->getType()), C); } Constant *ConstantExpr::getNot(Constant *C) { @@ -1845,24 +1790,33 @@ Constant *ConstantExpr::getNot(Constant *C) { return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType())); } -Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) { - return get(Instruction::Add, C1, C2); +Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Add, C1, C2, Flags); } Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) { return get(Instruction::FAdd, C1, C2); } -Constant *ConstantExpr::getSub(Constant *C1, Constant *C2) { - return get(Instruction::Sub, C1, C2); +Constant *ConstantExpr::getSub(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Sub, C1, C2, Flags); } Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) { return get(Instruction::FSub, C1, C2); } -Constant *ConstantExpr::getMul(Constant *C1, Constant *C2) { - return get(Instruction::Mul, C1, C2); +Constant *ConstantExpr::getMul(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Mul, C1, C2, Flags); } Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) { @@ -1907,8 +1861,11 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) { return get(Instruction::Xor, C1, C2); } -Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) { - return get(Instruction::Shl, C1, C2); +Constant *ConstantExpr::getShl(Constant *C1, Constant *C2, + bool HasNUW, bool HasNSW) { + unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) | + (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0); + return get(Instruction::Shl, C1, C2, Flags); } Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact) {