[llvm-commits] [llvm] r80998 - in /llvm/trunk: include/llvm/Constants.h include/llvm/InstrTypes.h include/llvm/Instructions.h include/llvm/Operator.h include/llvm/Value.h lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/Transfo

Daniel Dunbar daniel at zuster.org
Sat Sep 5 18:12:36 PDT 2009


Hi Dan,

This was causing MiniSAT to fail (timeout) on x86_64. I pulled it for
now, can you take a look?

Thanks,
 - Daniel

On Fri, Sep 4, 2009 at 5:08 AM, Dan Gohman<gohman at apple.com> wrote:
> Author: djg
> Date: Fri Sep  4 07:08:11 2009
> New Revision: 80998
>
> URL: http://llvm.org/viewvc/llvm-project?rev=80998&view=rev
> Log:
> 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.
>
> Removed:
>    llvm/trunk/test/Assembler/flags-plain.ll
>    llvm/trunk/test/Assembler/flags-reversed.ll
>    llvm/trunk/test/Assembler/flags-signed.ll
>    llvm/trunk/test/Assembler/flags-unsigned.ll
> Modified:
>    llvm/trunk/include/llvm/Constants.h
>    llvm/trunk/include/llvm/InstrTypes.h
>    llvm/trunk/include/llvm/Instructions.h
>    llvm/trunk/include/llvm/Operator.h
>    llvm/trunk/include/llvm/Value.h
>    llvm/trunk/lib/AsmParser/LLParser.cpp
>    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
>    llvm/trunk/lib/VMCore/Constants.cpp
>    llvm/trunk/lib/VMCore/ConstantsContext.h
>    llvm/trunk/lib/VMCore/Instructions.cpp
>    llvm/trunk/test/Assembler/flags.ll
>
> Modified: llvm/trunk/include/llvm/Constants.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Constants.h (original)
> +++ llvm/trunk/include/llvm/Constants.h Fri Sep  4 07:08:11 2009
> @@ -571,13 +571,17 @@
>   // These private methods are used by the type resolution code to create
>   // ConstantExprs in intermediate forms.
>   static Constant *getTy(const Type *Ty, unsigned Opcode,
> -                         Constant *C1, Constant *C2);
> +                         Constant *C1, Constant *C2,
> +                         unsigned Flags = 0);
>   static Constant *getCompareTy(unsigned short pred, Constant *C1,
>                                 Constant *C2);
>   static Constant *getSelectTy(const Type *Ty,
>                                Constant *C1, Constant *C2, Constant *C3);
>   static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
>                                       Value* const *Idxs, unsigned NumIdxs);
> +  static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
> +                                              Value* const *Idxs,
> +                                              unsigned NumIdxs);
>   static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
>                                        Constant *Idx);
>   static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
> @@ -718,7 +722,8 @@
>   /// get - Return a binary or shift operator constant expression,
>   /// folding if possible.
>   ///
> -  static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
> +  static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
> +                       unsigned Flags = 0);
>
>   /// @brief Return an ICmp or FCmp comparison operator constant expression.
>   static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
>
> Modified: llvm/trunk/include/llvm/InstrTypes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/InstrTypes.h (original)
> +++ llvm/trunk/include/llvm/InstrTypes.h Fri Sep  4 07:08:11 2009
> @@ -200,19 +200,19 @@
>   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
>                                       const Twine &Name = "") {
>     BinaryOperator *BO = CreateAdd(V1, V2, Name);
> -    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
> +    BO->setHasNoSignedWrap(true);
>     return BO;
>   }
>   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
>                                       const Twine &Name, BasicBlock *BB) {
>     BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
> -    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
> +    BO->setHasNoSignedWrap(true);
>     return BO;
>   }
>   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
>                                       const Twine &Name, Instruction *I) {
>     BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
> -    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
> +    BO->setHasNoSignedWrap(true);
>     return BO;
>   }
>
> @@ -221,19 +221,19 @@
>   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
>                                          const Twine &Name = "") {
>     BinaryOperator *BO = CreateSDiv(V1, V2, Name);
> -    cast<SDivOperator>(BO)->setIsExact(true);
> +    BO->setIsExact(true);
>     return BO;
>   }
>   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
>                                          const Twine &Name, BasicBlock *BB) {
>     BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
> -    cast<SDivOperator>(BO)->setIsExact(true);
> +    BO->setIsExact(true);
>     return BO;
>   }
>   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
>                                          const Twine &Name, Instruction *I) {
>     BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
> -    cast<SDivOperator>(BO)->setIsExact(true);
> +    BO->setIsExact(true);
>     return BO;
>   }
>
> @@ -287,6 +287,21 @@
>   ///
>   bool swapOperands();
>
> +  /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
> +  /// which must be an operator which supports this flag. See LangRef.html
> +  /// for the meaning of this flag.
> +  void setHasNoUnsignedWrap(bool);
> +
> +  /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
> +  /// which must be an operator which supports this flag. See LangRef.html
> +  /// for the meaning of this flag.
> +  void setHasNoSignedWrap(bool);
> +
> +  /// setIsExact - Set or clear the exact flag on this instruction,
> +  /// which must be an operator which supports this flag. See LangRef.html
> +  /// for the meaning of this flag.
> +  void setIsExact(bool);
> +
>   // Methods for support type inquiry through isa, cast, and dyn_cast:
>   static inline bool classof(const BinaryOperator *) { return true; }
>   static inline bool classof(const Instruction *I) {
>
> Modified: llvm/trunk/include/llvm/Instructions.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Instructions.h (original)
> +++ llvm/trunk/include/llvm/Instructions.h Fri Sep  4 07:08:11 2009
> @@ -496,7 +496,7 @@
>                                            Instruction *InsertBefore = 0) {
>     GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
>                                     NameStr, InsertBefore);
> -    cast<GEPOperator>(GEP)->setIsInBounds(true);
> +    GEP->setIsInBounds(true);
>     return GEP;
>   }
>   template<typename InputIterator>
> @@ -507,21 +507,21 @@
>                                            BasicBlock *InsertAtEnd) {
>     GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
>                                     NameStr, InsertAtEnd);
> -    cast<GEPOperator>(GEP)->setIsInBounds(true);
> +    GEP->setIsInBounds(true);
>     return GEP;
>   }
>   static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
>                                            const Twine &NameStr = "",
>                                            Instruction *InsertBefore = 0) {
>     GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
> -    cast<GEPOperator>(GEP)->setIsInBounds(true);
> +    GEP->setIsInBounds(true);
>     return GEP;
>   }
>   static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
>                                            const Twine &NameStr,
>                                            BasicBlock *InsertAtEnd) {
>     GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
> -    cast<GEPOperator>(GEP)->setIsInBounds(true);
> +    GEP->setIsInBounds(true);
>     return GEP;
>   }
>
> @@ -602,6 +602,10 @@
>   /// a constant offset between them.
>   bool hasAllConstantIndices() const;
>
> +  /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
> +  /// See LangRef.html for the meaning of inbounds on a getelementptr.
> +  void setIsInBounds(bool);
> +
>   // Methods for support type inquiry through isa, cast, and dyn_cast:
>   static inline bool classof(const GetElementPtrInst *) { return true; }
>   static inline bool classof(const Instruction *I) {
>
> Modified: llvm/trunk/include/llvm/Operator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Operator.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Operator.h (original)
> +++ llvm/trunk/include/llvm/Operator.h Fri Sep  4 07:08:11 2009
> @@ -21,6 +21,8 @@
>  namespace llvm {
>
>  class GetElementPtrInst;
> +class BinaryOperator;
> +class ConstantExpr;
>
>  /// Operator - This is a utility class that provides an abstraction for the
>  /// common functionality between Instructions and ConstantExprs.
> @@ -67,24 +69,37 @@
>  /// despite that operator having the potential for overflow.
>  ///
>  class OverflowingBinaryOperator : public Operator {
> +public:
> +  enum {
> +    NoUnsignedWrap = (1 << 0),
> +    NoSignedWrap   = (1 << 1)
> +  };
> +
> +private:
>   ~OverflowingBinaryOperator(); // do not implement
> +
> +  friend class BinaryOperator;
> +  friend class ConstantExpr;
> +  void setHasNoUnsignedWrap(bool B) {
> +    SubclassOptionalData =
> +      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
> +  }
> +  void setHasNoSignedWrap(bool B) {
> +    SubclassOptionalData =
> +      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
> +  }
> +
>  public:
>   /// hasNoUnsignedWrap - Test whether this operation is known to never
>   /// undergo unsigned overflow, aka the nuw property.
>   bool hasNoUnsignedWrap() const {
> -    return SubclassOptionalData & (1 << 0);
> -  }
> -  void setHasNoUnsignedWrap(bool B) {
> -    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
> +    return SubclassOptionalData & NoUnsignedWrap;
>   }
>
>   /// hasNoSignedWrap - Test whether this operation is known to never
>   /// undergo signed overflow, aka the nsw property.
>   bool hasNoSignedWrap() const {
> -    return SubclassOptionalData & (1 << 1);
> -  }
> -  void setHasNoSignedWrap(bool B) {
> -    SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
> +    return SubclassOptionalData & NoSignedWrap;
>   }
>
>   static inline bool classof(const OverflowingBinaryOperator *) { return true; }
> @@ -161,15 +176,25 @@
>  /// SDivOperator - An Operator with opcode Instruction::SDiv.
>  ///
>  class SDivOperator : public Operator {
> +public:
> +  enum {
> +    IsExact = (1 << 0)
> +  };
> +
> +private:
>   ~SDivOperator(); // do not implement
> +
> +  friend class BinaryOperator;
> +  friend class ConstantExpr;
> +  void setIsExact(bool B) {
> +    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
> +  }
> +
>  public:
>   /// isExact - Test whether this division is known to be exact, with
>   /// zero remainder.
>   bool isExact() const {
> -    return SubclassOptionalData & (1 << 0);
> -  }
> -  void setIsExact(bool B) {
> -    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
> +    return SubclassOptionalData & IsExact;
>   }
>
>   // Methods for support type inquiry through isa, cast, and dyn_cast:
> @@ -187,15 +212,24 @@
>  };
>
>  class GEPOperator : public Operator {
> +  enum {
> +    IsInBounds = (1 << 0)
> +  };
> +
>   ~GEPOperator(); // do not implement
> +
> +  friend class GetElementPtrInst;
> +  friend class ConstantExpr;
> +  void setIsInBounds(bool B) {
> +    SubclassOptionalData =
> +      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
> +  }
> +
>  public:
>   /// isInBounds - Test whether this is an inbounds GEP, as defined
>   /// by LangRef.html.
>   bool isInBounds() const {
> -    return SubclassOptionalData & (1 << 0);
> -  }
> -  void setIsInBounds(bool B) {
> -    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
> +    return SubclassOptionalData & IsInBounds;
>   }
>
>   inline op_iterator       idx_begin()       { return op_begin()+1; }
>
> Modified: llvm/trunk/include/llvm/Value.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Value.h (original)
> +++ llvm/trunk/include/llvm/Value.h Fri Sep  4 07:08:11 2009
> @@ -146,12 +146,6 @@
>   // Only use when in type resolution situations!
>   void uncheckedReplaceAllUsesWith(Value *V);
>
> -  /// clearOptionalData - Clear any optional optimization data from this Value.
> -  /// Transformation passes must call this method whenever changing the IR
> -  /// in a way that would affect the values produced by this Value, unless
> -  /// it takes special care to ensure correctness in some other way.
> -  void clearOptionalData() { SubclassOptionalData = 0; }
> -
>   //----------------------------------------------------------------------
>   // Methods for handling the chain of uses of this Value.
>   //
> @@ -240,6 +234,13 @@
>     return SubclassID;
>   }
>
> +  /// getRawSubclassOptionalData - Return the raw optional flags value
> +  /// contained in this value. This should only be used when testing two
> +  /// Values for equivalence.
> +  unsigned getRawSubclassOptionalData() const {
> +    return SubclassOptionalData;
> +  }
> +
>   /// hasSameSubclassOptionalData - Test whether the optional flags contained
>   /// in this value are equal to the optional flags in the given value.
>   bool hasSameSubclassOptionalData(const Value *V) const {
>
> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Fri Sep  4 07:08:11 2009
> @@ -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;
>  }
>
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Sep  4 07:08:11 2009
> @@ -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;
>     }
>
>
> Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Sep  4 07:08:11 2009
> @@ -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");
>
>
> Modified: llvm/trunk/lib/VMCore/Constants.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Constants.cpp (original)
> +++ llvm/trunk/lib/VMCore/Constants.cpp Fri Sep  4 07:08:11 2009
> @@ -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;
>
> Modified: llvm/trunk/lib/VMCore/ConstantsContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantsContext.h?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/VMCore/ConstantsContext.h (original)
> +++ llvm/trunk/lib/VMCore/ConstantsContext.h Fri Sep  4 07:08:11 2009
> @@ -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;
>
> Modified: llvm/trunk/lib/VMCore/Instructions.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Instructions.cpp (original)
> +++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Sep  4 07:08:11 2009
> @@ -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
>  //===----------------------------------------------------------------------===//
>
> Removed: llvm/trunk/test/Assembler/flags-plain.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-plain.ll?rev=80997&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags-plain.ll (original)
> +++ llvm/trunk/test/Assembler/flags-plain.ll (removed)
> @@ -1,28 +0,0 @@
> -; RUN: llvm-as < %s | llvm-dis | FileCheck %s
> -
> - at addr = external global i64
> -
> -define i64 @add_plain_ce() {
> -; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @sub_plain_ce() {
> -; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @mul_plain_ce() {
> -; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @sdiv_plain_ce() {
> -; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64* @gep_plain_ce() {
> -; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
> -        ret i64* getelementptr (i64* @addr, i64 171)
> -}
>
> Removed: llvm/trunk/test/Assembler/flags-reversed.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-reversed.ll?rev=80997&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags-reversed.ll (original)
> +++ llvm/trunk/test/Assembler/flags-reversed.ll (removed)
> @@ -1,18 +0,0 @@
> -; RUN: llvm-as < %s | llvm-dis | FileCheck %s
> -
> - at addr = external global i64
> -
> -define i64 @add_both_reversed_ce() {
> -; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @sub_both_reversed_ce() {
> -; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @mul_both_reversed_ce() {
> -; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
>
> Removed: llvm/trunk/test/Assembler/flags-signed.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-signed.ll?rev=80997&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags-signed.ll (original)
> +++ llvm/trunk/test/Assembler/flags-signed.ll (removed)
> @@ -1,18 +0,0 @@
> -; RUN: llvm-as < %s | llvm-dis | FileCheck %s
> -
> - at addr = external global i64
> -
> -define i64 @add_signed_ce() {
> -; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @sub_signed_ce() {
> -; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @mul_signed_ce() {
> -; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
>
> Removed: llvm/trunk/test/Assembler/flags-unsigned.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-unsigned.ll?rev=80997&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags-unsigned.ll (original)
> +++ llvm/trunk/test/Assembler/flags-unsigned.ll (removed)
> @@ -1,18 +0,0 @@
> -; RUN: llvm-as < %s | llvm-dis | FileCheck %s
> -
> - at addr = external global i64
> -
> -define i64 @add_unsigned_ce() {
> -; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @sub_unsigned_ce() {
> -; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
> -
> -define i64 @mul_unsigned_ce() {
> -; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -       ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> -}
>
> Modified: llvm/trunk/test/Assembler/flags.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags.ll?rev=80998&r1=80997&r2=80998&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags.ll (original)
> +++ llvm/trunk/test/Assembler/flags.ll Fri Sep  4 07:08:11 2009
> @@ -141,4 +141,72 @@
>         ret i64* getelementptr inbounds (i64* @addr, i64 171)
>  }
>
> +define i64 @add_plain_ce() {
> +; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @sub_plain_ce() {
> +; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @mul_plain_ce() {
> +; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @sdiv_plain_ce() {
> +; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64* @gep_plain_ce() {
> +; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
> +        ret i64* getelementptr (i64* @addr, i64 171)
> +}
> +
> +define i64 @add_both_reversed_ce() {
> +; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @sub_both_reversed_ce() {
> +; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
>
> +define i64 @mul_both_reversed_ce() {
> +; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @add_signed_ce() {
> +; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @sub_signed_ce() {
> +; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @mul_signed_ce() {
> +; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @add_unsigned_ce() {
> +; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @sub_unsigned_ce() {
> +; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
> +
> +define i64 @mul_unsigned_ce() {
> +; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +       ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list