Revert 80959. It isn't sufficient to solve the full problem. And it
introduced regressions in the Ocaml bindings tests.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80969 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 9bc0093..109eaad 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -203,21 +203,15 @@
   if (Offset != 0)
     return 0;
 
-  // Create the GEP constant expr.
-  Constant *C = ConstantExpr::getGetElementPtr(Ptr,
-                                               &NewIdxs[0], NewIdxs.size());
-  assert(cast<PointerType>(C->getType())->getElementType() == Ty &&
-         "Computed GetElementPtr has unexpected type!");
-
   // If the base is the start of a GlobalVariable and all the array indices
   // remain in their static bounds, the GEP is inbounds. We can check that
   // all indices are in bounds by just checking the first index only
-  // because we've just normalized all the indices. We can mutate the
-  // Constant in place because we've proven that the indices are in bounds,
-  // so they'll always be in bounds.
-  if (isa<GlobalVariable>(Ptr) && NewIdxs[0]->isNullValue())
-    if (GEPOperator *GEP = dyn_cast<GEPOperator>(C))
-      GEP->setIsInBounds(true);
+  // because we've just normalized all the indices.
+  Constant *C = isa<GlobalVariable>(Ptr) && NewIdxs[0]->isNullValue() ?
+    ConstantExpr::getInBoundsGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size()) :
+    ConstantExpr::getGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size());
+  assert(cast<PointerType>(C->getType())->getElementType() == Ty &&
+         "Computed GetElementPtr has unexpected type!");
 
   // If we ended up indexing a member with a type that doesn't match
   // the type of what the original indices indexed, add a cast.
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index a869467..701a195 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -122,7 +122,9 @@
         }
 
         if (ElTy == DPTy->getElementType())
-          return ConstantExpr::getGetElementPtr(V, &IdxList[0], IdxList.size());
+          // This GEP is inbounds because all indices are zero.
+          return ConstantExpr::getInBoundsGetElementPtr(V, &IdxList[0],
+                                                        IdxList.size());
       }
 
   // Handle casts from one vector constant to another.  We know that the src 
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 1ddc1e2..37efafc 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -631,6 +631,24 @@
   return get(std::vector<Constant*>(Vals, Vals+NumVals));
 }
 
+Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
+  Constant *C = getAdd(C1, C2);
+  // Set nsw attribute, assuming constant folding didn't eliminate the
+  // Add.
+  if (AddOperator *Add = dyn_cast<AddOperator>(C))
+    Add->setHasNoSignedWrap(true);
+  return C;
+}
+
+Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
+  Constant *C = getSDiv(C1, C2);
+  // Set exact attribute, assuming constant folding didn't eliminate the
+  // SDiv.
+  if (SDivOperator *SDiv = dyn_cast<SDivOperator>(C))
+    SDiv->setIsExact(true);
+  return C;
+}
+
 // 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
@@ -1473,11 +1491,28 @@
   return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
 }
 
+Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
+                                                 Value* const *Idxs,
+                                                 unsigned NumIdx) {
+  Constant *Result = getGetElementPtr(C, Idxs, NumIdx);
+  // Set in bounds attribute, assuming constant folding didn't eliminate the
+  // GEP.
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(Result))
+    GEP->setIsInBounds(true);
+  return Result;
+}
+
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
                                          unsigned NumIdx) {
   return getGetElementPtr(C, (Value* const *)Idxs, NumIdx);
 }
 
+Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
+                                                 Constant* const *Idxs,
+                                                 unsigned NumIdx) {
+  return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx);
+}
+
 Constant *
 ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
   assert(LHS->getType() == RHS->getType());
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index 240b27a..1dbf5c4 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -535,6 +535,13 @@
                                    unwrap<Constant>(RHSConstant)));
 }
 
+LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant,
+                             LLVMValueRef RHSConstant) {
+  return wrap(ConstantExpr::getNSWAdd(
+                                      unwrap<Constant>(LHSConstant),
+                                      unwrap<Constant>(RHSConstant)));
+}
+
 LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
   return wrap(ConstantExpr::getFAdd(
                                     unwrap<Constant>(LHSConstant),
@@ -576,6 +583,13 @@
                                     unwrap<Constant>(RHSConstant)));
 }
 
+LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant,
+                                LLVMValueRef RHSConstant) {
+  return wrap(ConstantExpr::getExactSDiv(
+                                         unwrap<Constant>(LHSConstant),
+                                         unwrap<Constant>(RHSConstant)));
+}
+
 LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
   return wrap(ConstantExpr::getFDiv(
                                     unwrap<Constant>(LHSConstant),
@@ -659,6 +673,14 @@
                                              NumIndices));
 }
 
+LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
+                                  LLVMValueRef *ConstantIndices,
+                                  unsigned NumIndices) {
+  Constant* Val = unwrap<Constant>(ConstantVal);
+  Constant** Idxs = unwrap<Constant>(ConstantIndices, NumIndices);
+  return wrap(ConstantExpr::getInBoundsGetElementPtr(Val, Idxs, NumIndices));
+}
+
 LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
   return wrap(ConstantExpr::getTrunc(
                                      unwrap<Constant>(ConstantVal),