[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