Include optional subclass flags, such as inbounds, nsw, etc., in the
Constant uniquing tables. This allows distinct ConstantExpr objects
with the same operation and different flags.

Even though a ConstantExpr "a + b" is either always overflowing or
never overflowing (due to being a ConstantExpr), it's still necessary
to be able to represent it both with and without overflow flags at
the same time within the IR, because the safety of the flag may
depend on the context of the use. If the constant really does overflow,
it wouldn't ever be safe to use with the flag set, however the use
may be in code that is never actually executed.

This also makes it possible to merge all the flags tests into a single test.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80998 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 3ef4aaf..b7b95d7 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -2095,13 +2095,11 @@
     if (!Val0->getType()->isIntOrIntVector() &&
         !Val0->getType()->isFPOrFPVector())
       return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
-    Constant *C = ConstantExpr::get(Opc, Val0, Val1);
-    if (NUW)
-      cast<OverflowingBinaryOperator>(C)->setHasNoUnsignedWrap(true);
-    if (NSW)
-      cast<OverflowingBinaryOperator>(C)->setHasNoSignedWrap(true);
-    if (Exact)
-      cast<SDivOperator>(C)->setIsExact(true);
+    unsigned Flags = 0;
+    if (NUW)   Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+    if (NSW)   Flags |= OverflowingBinaryOperator::NoSignedWrap;
+    if (Exact) Flags |= SDivOperator::IsExact;
+    Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
     ID.ConstantVal = C;
     ID.Kind = ValID::t_Constant;
     return false;
@@ -2157,10 +2155,12 @@
                                              (Value**)(Elts.data() + 1),
                                              Elts.size() - 1))
         return Error(ID.Loc, "invalid indices for getelementptr");
-      ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
-                                              Elts.data() + 1, Elts.size() - 1);
-      if (InBounds)
-        cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true);
+      ID.ConstantVal = InBounds ?
+        ConstantExpr::getInBoundsGetElementPtr(Elts[0],
+                                               Elts.data() + 1,
+                                               Elts.size() - 1) :
+        ConstantExpr::getGetElementPtr(Elts[0],
+                                       Elts.data() + 1, Elts.size() - 1);
     } else if (Opc == Instruction::Select) {
       if (Elts.size() != 3)
         return Error(ID.Loc, "expected three operands to select");
@@ -2681,9 +2681,9 @@
           return Error(ModifierLoc, "nsw only applies to integer operations");
       }
       if (NUW)
-        cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
+        cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
       if (NSW)
-        cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedWrap(true);
+        cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
     }
     return Result;
   }
@@ -2698,7 +2698,7 @@
     bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
     if (!Result)
       if (Exact)
-        cast<SDivOperator>(Inst)->setIsExact(true);
+        cast<BinaryOperator>(Inst)->setIsExact(true);
     return Result;
   }
 
@@ -3501,7 +3501,7 @@
     return Error(Loc, "invalid getelementptr indices");
   Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
   if (InBounds)
-    cast<GEPOperator>(Inst)->setIsInBounds(true);
+    cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
   return false;
 }
 
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 9ed75ab..05f7b52 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -883,19 +883,6 @@
   return false;
 }
 
-static void SetOptimizationFlags(Value *V, uint64_t Flags) {
-  if (OverflowingBinaryOperator *OBO =
-        dyn_cast<OverflowingBinaryOperator>(V)) {
-    if (Flags & (1 << bitc::OBO_NO_SIGNED_WRAP))
-      OBO->setHasNoSignedWrap(true);
-    if (Flags & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
-      OBO->setHasNoUnsignedWrap(true);
-  } else if (SDivOperator *Div = dyn_cast<SDivOperator>(V)) {
-    if (Flags & (1 << bitc::SDIV_EXACT))
-      Div->setIsExact(true);
-  }
-}
-
 bool BitcodeReader::ParseConstants() {
   if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
     return Error("Malformed block record");
@@ -1047,10 +1034,22 @@
       } else {
         Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
         Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
-        V = ConstantExpr::get(Opc, LHS, RHS);
+        unsigned Flags = 0;
+        if (Record.size() >= 4) {
+          if (Opc == Instruction::Add ||
+              Opc == Instruction::Sub ||
+              Opc == Instruction::Mul) {
+            if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoSignedWrap;
+            if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+          } else if (Opc == Instruction::SDiv) {
+            if (Record[3] & (1 << bitc::SDIV_EXACT))
+              Flags |= SDivOperator::IsExact;
+          }
+        }
+        V = ConstantExpr::get(Opc, LHS, RHS, Flags);
       }
-      if (Record.size() >= 4)
-        SetOptimizationFlags(V, Record[3]);
       break;
     }  
     case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
@@ -1075,10 +1074,12 @@
         if (!ElTy) return Error("Invalid CE_GEP record");
         Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
       }
-      V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], 
-                                               Elts.size()-1);
       if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
-        cast<GEPOperator>(V)->setIsInBounds(true);
+        V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1],
+                                                   Elts.size()-1);
+      else
+        V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
+                                           Elts.size()-1);
       break;
     }
     case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
@@ -1610,8 +1611,19 @@
       int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
       if (Opc == -1) return Error("Invalid BINOP record");
       I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
-      if (OpNum < Record.size())
-        SetOptimizationFlags(I, Record[3]);
+      if (OpNum < Record.size()) {
+        if (Opc == Instruction::Add ||
+            Opc == Instruction::Sub ||
+            Opc == Instruction::Mul) {
+          if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
+          if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
+        } else if (Opc == Instruction::SDiv) {
+          if (Record[3] & (1 << bitc::SDIV_EXACT))
+            cast<BinaryOperator>(I)->setIsExact(true);
+        }
+      }
       break;
     }
     case bitc::FUNC_CODE_INST_CAST: {    // CAST: [opval, opty, destty, castopc]
@@ -1645,7 +1657,7 @@
 
       I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
       if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
-        cast<GEPOperator>(I)->setIsInBounds(true);
+        cast<GetElementPtrInst>(I)->setIsInBounds(true);
       break;
     }
       
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index ce2f452..432b88f 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -8086,11 +8086,11 @@
           // If we were able to index down into an element, create the GEP
           // and bitcast the result.  This eliminates one bitcast, potentially
           // two.
-          Value *NGEP = Builder->CreateGEP(OrigBase, NewIndices.begin(),
-                                           NewIndices.end());
+          Value *NGEP = cast<GEPOperator>(GEP)->isInBounds() ?
+            Builder->CreateInBoundsGEP(OrigBase,
+                                       NewIndices.begin(), NewIndices.end()) :
+            Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
           NGEP->takeName(GEP);
-          if (isa<Instruction>(NGEP) && cast<GEPOperator>(GEP)->isInBounds())
-            cast<GEPOperator>(NGEP)->setIsInBounds(true);
           
           if (isa<BitCastInst>(CI))
             return new BitCastInst(NGEP, CI.getType());
@@ -8805,11 +8805,8 @@
     // If we found a path from the src to dest, create the getelementptr now.
     if (SrcElTy == DstElTy) {
       SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
-      Instruction *GEP = GetElementPtrInst::Create(Src,
-                                                   Idxs.begin(), Idxs.end(), "",
-                                                   ((Instruction*) NULL));
-      cast<GEPOperator>(GEP)->setIsInBounds(true);
-      return GEP;
+      return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(), "",
+                                               ((Instruction*) NULL));
     }
   }
 
@@ -10481,12 +10478,11 @@
   }
   
   Value *Base = FixedOperands[0];
-  GetElementPtrInst *GEP =
+  return cast<GEPOperator>(FirstInst)->isInBounds() ?
+    GetElementPtrInst::CreateInBounds(Base, FixedOperands.begin()+1,
+                                      FixedOperands.end()) :
     GetElementPtrInst::Create(Base, FixedOperands.begin()+1,
                               FixedOperands.end());
-  if (cast<GEPOperator>(FirstInst)->isInBounds())
-    cast<GEPOperator>(GEP)->setIsInBounds(true);
-  return GEP;
 }
 
 
@@ -10889,14 +10885,13 @@
       Indices.append(GEP.idx_begin()+1, GEP.idx_end());
     }
 
-    if (!Indices.empty()) {
-      GetElementPtrInst *NewGEP =
+    if (!Indices.empty())
+      return (cast<GEPOperator>(&GEP)->isInBounds() &&
+              Src->isInBounds()) ?
+        GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
+                                          Indices.end(), GEP.getName()) :
         GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
                                   Indices.end(), GEP.getName());
-      if (cast<GEPOperator>(&GEP)->isInBounds() && Src->isInBounds())
-        cast<GEPOperator>(NewGEP)->setIsInBounds(true);
-      return NewGEP;
-    }
   }
   
   // Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
@@ -10926,12 +10921,11 @@
         if (CATy->getElementType() == XTy->getElementType()) {
           // -> GEP i8* X, ...
           SmallVector<Value*, 8> Indices(GEP.idx_begin()+1, GEP.idx_end());
-          GetElementPtrInst *NewGEP =
+          return cast<GEPOperator>(&GEP)->isInBounds() ?
+            GetElementPtrInst::CreateInBounds(X, Indices.begin(), Indices.end(),
+                                              GEP.getName()) :
             GetElementPtrInst::Create(X, Indices.begin(), Indices.end(),
                                       GEP.getName());
-          if (cast<GEPOperator>(&GEP)->isInBounds())
-            cast<GEPOperator>(NewGEP)->setIsInBounds(true);
-          return NewGEP;
         }
         
         if (const ArrayType *XATy = dyn_cast<ArrayType>(XTy->getElementType())){
@@ -10959,10 +10953,9 @@
         Value *Idx[2];
         Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
         Idx[1] = GEP.getOperand(1);
-        Value *NewGEP =
+        Value *NewGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
+          Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
           Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
-        if (cast<GEPOperator>(&GEP)->isInBounds())
-          cast<GEPOperator>(NewGEP)->setIsInBounds(true);
         // V and GEP are both pointer types --> BitCast
         return new BitCastInst(NewGEP, GEP.getType());
       }
@@ -11019,9 +11012,9 @@
           Value *Idx[2];
           Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
           Idx[1] = NewIdx;
-          Value *NewGEP = Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
-          if (cast<GEPOperator>(&GEP)->isInBounds())
-            cast<GEPOperator>(NewGEP)->setIsInBounds(true);
+          Value *NewGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
+            Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
+            Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
           // The NewGEP must be pointer typed, so must the old one -> BitCast
           return new BitCastInst(NewGEP, GEP.getType());
         }
@@ -11069,10 +11062,11 @@
       const Type *InTy =
         cast<PointerType>(BCI->getOperand(0)->getType())->getElementType();
       if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
-        Value *NGEP = Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
-                                         NewIndices.end());
-        if (cast<GEPOperator>(&GEP)->isInBounds())
-          cast<GEPOperator>(NGEP)->setIsInBounds(true);
+        Value *NGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
+          Builder->CreateInBoundsGEP(BCI->getOperand(0), NewIndices.begin(),
+                                     NewIndices.end()) :
+          Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
+                             NewIndices.end());
         
         if (NGEP->getType() == GEP.getType())
           return ReplaceInstUsesWith(GEP, NGEP);
@@ -11115,9 +11109,8 @@
       Value *Idx[2];
       Idx[0] = NullIdx;
       Idx[1] = NullIdx;
-      Value *V = GetElementPtrInst::Create(New, Idx, Idx + 2,
-                                           New->getName()+".sub", It);
-      cast<GEPOperator>(V)->setIsInBounds(true);
+      Value *V = GetElementPtrInst::CreateInBounds(New, Idx, Idx + 2,
+                                                   New->getName()+".sub", It);
 
       // Now make everything use the getelementptr instead of the original
       // allocation.
@@ -11486,11 +11479,9 @@
   
   // SIOp0 is a pointer to aggregate and this is a store to the first field,
   // emit a GEP to index into its first field.
-  if (!NewGEPIndices.empty()) {
-    CastOp = IC.Builder->CreateGEP(CastOp, NewGEPIndices.begin(),
-                                   NewGEPIndices.end());
-    cast<GEPOperator>(CastOp)->setIsInBounds(true);
-  }
+  if (!NewGEPIndices.empty())
+    CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices.begin(),
+                                           NewGEPIndices.end());
   
   NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
                                    SIOp0->getName()+".c");
@@ -12160,8 +12151,7 @@
                                             PointerType::get(EI.getType(), AS),
                                             I->getOperand(0)->getName());
         Value *GEP =
-          Builder->CreateGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
-        cast<GEPOperator>(GEP)->setIsInBounds(true);
+          Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
         
         LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
 
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 37efafc..a5b4f28 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -632,21 +632,13 @@
 }
 
 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;
+  return getTy(C1->getType(), Instruction::Add, C1, C2,
+               OverflowingBinaryOperator::NoSignedWrap);
 }
 
 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;
+  return getTy(C1->getType(), Instruction::SDiv, C1, C2,
+               SDivOperator::IsExact);
 }
 
 // Utility function for determining if a ConstantExpr is a CastOp or not. This
@@ -729,15 +721,19 @@
     for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
       Ops[i-1] = getOperand(i);
     if (OpNo == 0)
-      return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
+      return cast<GEPOperator>(this)->isInBounds() ?
+        ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) :
+        ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
     Ops[OpNo-1] = Op;
-    return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
+    return cast<GEPOperator>(this)->isInBounds() ?
+      ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) :
+      ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
   }
   default:
     assert(getNumOperands() == 2 && "Must be binary operator?");
     Op0 = (OpNo == 0) ? Op : getOperand(0);
     Op1 = (OpNo == 1) ? Op : getOperand(1);
-    return ConstantExpr::get(getOpcode(), Op0, Op1);
+    return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData);
   }
 }
 
@@ -779,13 +775,15 @@
   case Instruction::ShuffleVector:
     return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
   case Instruction::GetElementPtr:
-    return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
+    return cast<GEPOperator>(this)->isInBounds() ?
+      ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) :
+      ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
   case Instruction::ICmp:
   case Instruction::FCmp:
     return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
   default:
     assert(getNumOperands() == 2 && "Must be binary operator?");
-    return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]);
+    return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData);
   }
 }
 
@@ -1031,8 +1029,9 @@
   Operands.reserve(CE->getNumOperands());
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
-  return ExprMapKeyType(CE->getOpcode(), Operands, 
+  return ExprMapKeyType(CE->getOpcode(), Operands,
       CE->isCompare() ? CE->getPredicate() : 0,
+      CE->getRawSubclassOptionalData(),
       CE->hasIndices() ?
         CE->getIndices() : SmallVector<unsigned, 4>());
 }
@@ -1280,7 +1279,8 @@
 }
 
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
-                              Constant *C1, Constant *C2) {
+                              Constant *C1, Constant *C2,
+                              unsigned Flags) {
   // Check the operands for consistency first
   assert(Opcode >= Instruction::BinaryOpsBegin &&
          Opcode <  Instruction::BinaryOpsEnd   &&
@@ -1294,7 +1294,7 @@
       return FC;          // Fold a few common cases...
 
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key(Opcode, argVec);
+  ExprMapKeyType Key(Opcode, argVec, 0, Flags);
   
   LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
   
@@ -1322,7 +1322,8 @@
   }
 }
 
-Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
+                            unsigned Flags) {
   // API compatibility: Adjust integer opcodes to floating-point opcodes.
   if (C1->getType()->isFPOrFPVector()) {
     if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
@@ -1387,7 +1388,7 @@
   }
 #endif
 
-  return getTy(C1->getType(), Opcode, C1, C2);
+  return getTy(C1->getType(), Opcode, C1, C2, Flags);
 }
 
 Constant* ConstantExpr::getSizeOf(const Type* Ty) {
@@ -1481,6 +1482,36 @@
   return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
 }
 
+Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
+                                                   Constant *C,
+                                                   Value* const *Idxs,
+                                                   unsigned NumIdx) {
+  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
+                                           Idxs+NumIdx) ==
+         cast<PointerType>(ReqTy)->getElementType() &&
+         "GEP indices invalid!");
+
+  if (Constant *FC = ConstantFoldGetElementPtr(
+                              ReqTy->getContext(), C, (Constant**)Idxs, NumIdx))
+    return FC;          // Fold a few common cases...
+
+  assert(isa<PointerType>(C->getType()) &&
+         "Non-pointer type for constant GetElementPtr expression");
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.reserve(NumIdx+1);
+  ArgVec.push_back(C);
+  for (unsigned i = 0; i != NumIdx; ++i)
+    ArgVec.push_back(cast<Constant>(Idxs[i]));
+  const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
+                           GEPOperator::IsInBounds);
+
+  LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
+
+  // Implicitly locked.
+  return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
+}
+
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                          unsigned NumIdx) {
   // Get the result type of the getelementptr!
@@ -1494,12 +1525,12 @@
 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;
+  // Get the result type of the getelementptr!
+  const Type *Ty = 
+    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
+  assert(Ty && "GEP indices invalid!");
+  unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
+  return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
 }
 
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
@@ -2104,7 +2135,7 @@
     Constant *C2 = getOperand(1);
     if (C1 == From) C1 = To;
     if (C2 == From) C2 = To;
-    Replacement = ConstantExpr::get(getOpcode(), C1, C2);
+    Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
   } else {
     llvm_unreachable("Unknown ConstantExpr type!");
     return;
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index 718470a..16975b3 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -53,10 +53,12 @@
   void *operator new(size_t s) {
     return User::operator new(s, 2);
   }
-  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
+  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
+                     unsigned Flags)
     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
     Op<0>() = C1;
     Op<1>() = C2;
+    SubclassOptionalData = Flags;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -206,9 +208,12 @@
 public:
   static GetElementPtrConstantExpr *Create(Constant *C,
                                            const std::vector<Constant*>&IdxList,
-                                           const Type *DestTy) {
-    return
+                                           const Type *DestTy,
+                                           unsigned Flags) {
+    GetElementPtrConstantExpr *Result =
       new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
+    Result->SubclassOptionalData = Flags;
+    return Result;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -291,26 +296,32 @@
 
   ExprMapKeyType(unsigned opc,
       const std::vector<Constant*> &ops,
-      unsigned short pred = 0,
+      unsigned short flags = 0,
+      unsigned short optionalflags = 0,
       const IndexList &inds = IndexList())
-        : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
-  uint16_t opcode;
-  uint16_t predicate;
+        : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
+        operands(ops), indices(inds) {}
+  uint8_t opcode;
+  uint8_t subclassoptionaldata;
+  uint16_t subclassdata;
   std::vector<Constant*> operands;
   IndexList indices;
   bool operator==(const ExprMapKeyType& that) const {
     return this->opcode == that.opcode &&
-           this->predicate == that.predicate &&
+           this->subclassdata == that.subclassdata &&
+           this->subclassoptionaldata == that.subclassoptionaldata &&
            this->operands == that.operands &&
            this->indices == that.indices;
   }
   bool operator<(const ExprMapKeyType & that) const {
-    return this->opcode < that.opcode ||
-      (this->opcode == that.opcode && this->predicate < that.predicate) ||
-      (this->opcode == that.opcode && this->predicate == that.predicate &&
-       this->operands < that.operands) ||
-      (this->opcode == that.opcode && this->predicate == that.predicate &&
-       this->operands == that.operands && this->indices < that.indices);
+    if (this->opcode != that.opcode) return this->opcode < that.opcode;
+    if (this->operands != that.operands) return this->operands < that.operands;
+    if (this->subclassdata != that.subclassdata)
+      return this->subclassdata < that.subclassdata;
+    if (this->subclassoptionaldata != that.subclassoptionaldata)
+      return this->subclassoptionaldata < that.subclassoptionaldata;
+    if (this->indices != that.indices) return this->indices < that.indices;
+    return false;
   }
 
   bool operator!=(const ExprMapKeyType& that) const {
@@ -354,7 +365,8 @@
       return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
     if ((V.opcode >= Instruction::BinaryOpsBegin &&
          V.opcode < Instruction::BinaryOpsEnd))
-      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
+      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
+                                    V.subclassoptionaldata);
     if (V.opcode == Instruction::Select)
       return new SelectConstantExpr(V.operands[0], V.operands[1], 
                                     V.operands[2]);
@@ -373,17 +385,18 @@
       return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
     if (V.opcode == Instruction::GetElementPtr) {
       std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
-      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
+      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
+                                               V.subclassoptionaldata);
     }
 
     // The compare instructions are weird. We have to encode the predicate
     // value and it is combined with the instruction opcode by multiplying
     // the opcode by one hundred. We must decode this to get the predicate.
     if (V.opcode == Instruction::ICmp)
-      return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, 
+      return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
                                      V.operands[0], V.operands[1]);
     if (V.opcode == Instruction::FCmp) 
-      return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, 
+      return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
                                      V.operands[0], V.operands[1]);
     llvm_unreachable("Invalid ConstantExpr!");
     return 0;
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 2d4ab55..9d8e047 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1171,6 +1171,9 @@
   return true;
 }
 
+void GetElementPtrInst::setIsInBounds(bool B) {
+  cast<GEPOperator>(this)->setIsInBounds(B);
+}
 
 //===----------------------------------------------------------------------===//
 //                           ExtractElementInst Implementation
@@ -1716,6 +1719,18 @@
   return false;
 }
 
+void BinaryOperator::setHasNoUnsignedWrap(bool b) {
+  cast<OverflowingBinaryOperator>(this)->setHasNoUnsignedWrap(b);
+}
+
+void BinaryOperator::setHasNoSignedWrap(bool b) {
+  cast<OverflowingBinaryOperator>(this)->setHasNoSignedWrap(b);
+}
+
+void BinaryOperator::setIsExact(bool b) {
+  cast<SDivOperator>(this)->setIsExact(b);
+}
+
 //===----------------------------------------------------------------------===//
 //                                CastInst Class
 //===----------------------------------------------------------------------===//