Add utility routines for creating integer negation operators with NSW set.
authorDan Gohman <gohman@apple.com>
Fri, 18 Dec 2009 02:58:50 +0000 (02:58 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 18 Dec 2009 02:58:50 +0000 (02:58 +0000)
Integer negation only overflows with INT_MIN, but that's an important case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91662 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Constants.h
include/llvm/InstrTypes.h
include/llvm/Support/ConstantFolder.h
include/llvm/Support/IRBuilder.h
include/llvm/Support/NoFolder.h
include/llvm/Support/TargetFolder.h
lib/VMCore/Constants.cpp
lib/VMCore/Instructions.cpp

index caa13f6ac6894eb913c52cfc0ebca38165af45e0..7440f99c50d054e9ef191f4aca9ca3143893b36e 100644 (file)
@@ -692,6 +692,7 @@ public:
   static Constant *getIntToPtr(Constant *C, const Type *Ty);
   static Constant *getBitCast (Constant *C, const Type *Ty);
 
+  static Constant *getNSWNeg(Constant *C);
   static Constant *getNSWAdd(Constant *C1, Constant *C2);
   static Constant *getNSWSub(Constant *C1, Constant *C2);
   static Constant *getExactSDiv(Constant *C1, Constant *C2);
index bc899699d902fadd2c382913c8e55175b234ce4f..b25290226bb738c49540987c562551911daca3d8 100644 (file)
@@ -308,6 +308,10 @@ public:
                                    Instruction *InsertBefore = 0);
   static BinaryOperator *CreateNeg(Value *Op, const Twine &Name,
                                    BasicBlock *InsertAtEnd);
+  static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "",
+                                      Instruction *InsertBefore = 0);
+  static BinaryOperator *CreateNSWNeg(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,
index b73cea04aba8d3b62770ac53cd3d4ee2e7b9e896..eea33dfff617bdaeb024d308a1a4be2a2bdf9bcf 100644 (file)
@@ -109,6 +109,9 @@ public:
   Constant *CreateNeg(Constant *C) const {
     return ConstantExpr::getNeg(C);
   }
+  Constant *CreateNSWNeg(Constant *C) const {
+    return ConstantExpr::getNSWNeg(C);
+  }
   Constant *CreateFNeg(Constant *C) const {
     return ConstantExpr::getFNeg(C);
   }
index 1310d70545f6fbcc16c4462ef6b59bffc36605fd..22b05d6a10de8acbcc6d78f8b230242d154f231f 100644 (file)
@@ -478,6 +478,11 @@ public:
       return Folder.CreateNeg(VC);
     return Insert(BinaryOperator::CreateNeg(V), Name);
   }
+  Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Folder.CreateNSWNeg(VC);
+    return Insert(BinaryOperator::CreateNSWNeg(V), Name);
+  }
   Value *CreateFNeg(Value *V, const Twine &Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateFNeg(VC);
index 7f2f1497f39f6d8bbcb64fbaf38ffa081dcd222b..f6f4c5b3c854c42b68ae0da443ce8464faf26ef2 100644 (file)
@@ -115,6 +115,9 @@ public:
   Value *CreateNeg(Constant *C) const {
     return BinaryOperator::CreateNeg(C);
   }
+  Value *CreateNSWNeg(Constant *C) const {
+    return BinaryOperator::CreateNSWNeg(C);
+  }
   Value *CreateNot(Constant *C) const {
     return BinaryOperator::CreateNot(C);
   }
index afed853e86793a5bac591bc137c933d2c4e32871..9aa762570e86413eb815f09f75a734f32442bf6b 100644 (file)
@@ -122,6 +122,9 @@ public:
   Constant *CreateNeg(Constant *C) const {
     return Fold(ConstantExpr::getNeg(C));
   }
+  Constant *CreateNSWNeg(Constant *C) const {
+    return Fold(ConstantExpr::getNSWNeg(C));
+  }
   Constant *CreateFNeg(Constant *C) const {
     return Fold(ConstantExpr::getFNeg(C));
   }
index a62f75b1c8062ab9c49b7be4373af0b35c86efe5..2507402f89929658d01a2e7c0e7cd34986cdc712 100644 (file)
@@ -627,6 +627,12 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
   return get(std::vector<Constant*>(Vals, Vals+NumVals));
 }
 
+Constant* ConstantExpr::getNSWNeg(Constant* C) {
+  assert(C->getType()->isIntOrIntVector() &&
+         "Cannot NEG a nonintegral value!");
+  return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+}
+
 Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
   return getTy(C1->getType(), Instruction::Add, C1, C2,
                OverflowingBinaryOperator::NoSignedWrap);
index b03ee93dbe751974c531d43f232d1a2601d5a265..97fec399e48b02355ec2ffdc815fd8234a5ee18f 100644 (file)
@@ -1772,6 +1772,18 @@ BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name,
                             Op->getType(), Name, InsertAtEnd);
 }
 
+BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name,
+                                             Instruction *InsertBefore) {
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+  return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertBefore);
+}
+
+BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name,
+                                             BasicBlock *InsertAtEnd) {
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+  return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertAtEnd);
+}
+
 BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name,
                                            Instruction *InsertBefore) {
   Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());