diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 4b356067998..ff1be051bc9 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -697,10 +697,13 @@ public: 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 *getNUWMul(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 *getExactSDiv(Constant *C1, Constant *C2); /// Transparently provide more efficient getOperand methods. diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index b5cc65962e8..5ce1a9df45d 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -299,6 +299,27 @@ public: return BO; } + /// CreateNUWMul - Create a Mul operator with the NUW flag set. + /// + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateMul(V1, V2, Name); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateMul(V1, V2, Name, BB); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateMul(V1, V2, Name, I); + BO->setHasNoUnsignedWrap(true); + return BO; + } + /// CreateExactSDiv - Create an SDiv operator with the exact flag set. /// static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, @@ -334,6 +355,10 @@ public: Instruction *InsertBefore = 0); static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); + static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "", + Instruction *InsertBefore = 0); + static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "", Instruction *InsertBefore = 0); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name, diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index 1339e9fac6a..ea6c5fd82a0 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -39,6 +39,9 @@ public: 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 *CreateFAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFAdd(LHS, RHS); } @@ -48,6 +51,9 @@ public: 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 *CreateFSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFSub(LHS, RHS); } @@ -57,6 +63,9 @@ public: 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 *CreateFMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFMul(LHS, RHS); } @@ -115,6 +124,9 @@ public: Constant *CreateNSWNeg(Constant *C) const { return ConstantExpr::getNSWNeg(C); } + Constant *CreateNUWNeg(Constant *C) const { + return ConstantExpr::getNUWNeg(C); + } Constant *CreateFNeg(Constant *C) const { return ConstantExpr::getFNeg(C); } diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index eabf6ad4e5f..9f0dce2ca04 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -318,6 +318,12 @@ public: return Folder.CreateNSWAdd(LC, RC); return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name); } + Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWAdd(LC, RC); + return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name); + } Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -336,6 +342,12 @@ public: return Folder.CreateNSWSub(LC, RC); return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name); } + Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWSub(LC, RC); + return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name); + } Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -354,6 +366,12 @@ public: return Folder.CreateNSWMul(LC, RC); return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name); } + Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWMul(LC, RC); + return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name); + } Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -484,6 +502,11 @@ public: return Folder.CreateNSWNeg(VC); return Insert(BinaryOperator::CreateNSWNeg(V), Name); } + Value *CreateNUWNeg(Value *V, const Twine &Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateNUWNeg(VC); + return Insert(BinaryOperator::CreateNUWNeg(V), Name); + } Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast(V)) return Folder.CreateFNeg(VC); diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 78a9035b6c1..01256e18a5c 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -45,6 +45,9 @@ public: Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWAdd(LHS, RHS); } + Value *CreateNUWAdd(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWAdd(LHS, RHS); + } Value *CreateFAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFAdd(LHS, RHS); } @@ -54,6 +57,9 @@ public: Value *CreateNSWSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWSub(LHS, RHS); } + Value *CreateNUWSub(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWSub(LHS, RHS); + } Value *CreateFSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFSub(LHS, RHS); } @@ -63,6 +69,9 @@ public: Value *CreateNSWMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWMul(LHS, RHS); } + Value *CreateNUWMul(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWMul(LHS, RHS); + } Value *CreateFMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFMul(LHS, RHS); } @@ -121,6 +130,9 @@ public: Value *CreateNSWNeg(Constant *C) const { return BinaryOperator::CreateNSWNeg(C); } + Value *CreateNUWNeg(Constant *C) const { + return BinaryOperator::CreateNUWNeg(C); + } Value *CreateNot(Constant *C) const { return BinaryOperator::CreateNot(C); } diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 59dd29be7a8..384c49396a8 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -52,6 +52,9 @@ public: 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 *CreateFAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFAdd(LHS, RHS)); } @@ -61,6 +64,9 @@ public: 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 *CreateFSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFSub(LHS, RHS)); } @@ -70,6 +76,9 @@ public: 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 *CreateFMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFMul(LHS, RHS)); } @@ -128,6 +137,9 @@ public: Constant *CreateNSWNeg(Constant *C) const { return Fold(ConstantExpr::getNSWNeg(C)); } + Constant *CreateNUWNeg(Constant *C) const { + return Fold(ConstantExpr::getNUWNeg(C)); + } Constant *CreateFNeg(Constant *C) const { return Fold(ConstantExpr::getFNeg(C)); } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 762fbe4c9ad..2250626051b 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -645,18 +645,29 @@ Constant* ConstantExpr::getNSWNeg(Constant* C) { return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C); } +Constant* ConstantExpr::getNUWNeg(Constant* C) { + assert(C->getType()->isIntOrIntVector() && + "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::getNUWMul(Constant* C1, Constant* C2) { - return getTy(C1->getType(), Instruction::Mul, C1, C2, +Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::Sub, C1, C2, OverflowingBinaryOperator::NoUnsignedWrap); } @@ -665,6 +676,11 @@ Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) { OverflowingBinaryOperator::NoSignedWrap); } +Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::Mul, C1, C2, + OverflowingBinaryOperator::NoUnsignedWrap); +} + Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { return getTy(C1->getType(), Instruction::SDiv, C1, C2, SDivOperator::IsExact); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index a9b2cab28e9..4ec82953c19 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1786,6 +1786,18 @@ BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertAtEnd); } +BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name, + Instruction *InsertBefore) { + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); + return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertBefore); +} + +BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd) { + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); + return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertAtEnd); +} + BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());