From 35bda8914c0d1c02a6f90f42e7810c83150737e1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 6 Feb 2011 21:44:57 +0000 Subject: enhance vmcore to know that udiv's can be exact, and add a trivial instcombine xform to exercise this. Nothing forms exact udivs yet though. This is progress on PR8862 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124992 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/LLVMBitCodes.h | 8 +++--- include/llvm/Constants.h | 1 + include/llvm/InstrTypes.h | 2 +- include/llvm/Operator.h | 53 ++++++++++++++++++++++++++++++------- 4 files changed, 50 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index d15c3ce93e..7692bd2872 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -199,10 +199,10 @@ namespace bitc { OBO_NO_SIGNED_WRAP = 1 }; - /// SDivOperatorOptionalFlags - Flags for serializing SDivOperator's - /// SubclassOptionalData contents. - enum SDivOperatorOptionalFlags { - SDIV_EXACT = 0 + /// PossiblyExactOperatorOptionalFlags - Flags for serializing + /// PossiblyExactOperator's SubclassOptionalData contents. + enum PossiblyExactOperatorOptionalFlags { + PEO_EXACT = 0 }; // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index a7653948f1..b782737d31 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -725,6 +725,7 @@ public: static Constant *getNSWMul(Constant *C1, Constant *C2); static Constant *getNUWMul(Constant *C1, Constant *C2); static Constant *getExactSDiv(Constant *C1, Constant *C2); + static Constant *getExactUDiv(Constant *C1, Constant *C2); /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 9dcf688358..1bb50b78fa 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -341,7 +341,7 @@ public: BO->setIsExact(true); return BO; } - + /// Helper functions to construct and inspect unary operations (NEG and NOT) /// via binary operators SUB and XOR: /// diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 3aae586f14..288edf1224 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -173,30 +173,47 @@ public: } }; -/// SDivOperator - An Operator with opcode Instruction::SDiv. -/// -class SDivOperator : public Operator { +/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as +/// "exact", indicating that no bits are destroyed. +class PossiblyExactOperator : 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); } - + +private: + ~PossiblyExactOperator(); // do not implement public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. bool isExact() const { return SubclassOptionalData & IsExact; } - + + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::SDiv || + CE->getOpcode() == Instruction::UDiv; + } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::SDiv || + I->getOpcode() == Instruction::UDiv; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + +/// SDivOperator - An Operator with opcode Instruction::SDiv. +/// +class SDivOperator : public PossiblyExactOperator { +public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SDivOperator *) { return true; } static inline bool classof(const ConstantExpr *CE) { @@ -211,6 +228,24 @@ public: } }; +/// UDivOperator - An Operator with opcode Instruction::SDiv. +/// +class UDivOperator : public PossiblyExactOperator { +public: + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UDivOperator *) { return true; } + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::UDiv; + } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::UDiv; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + class GEPOperator : public Operator { enum { IsInBounds = (1 << 0) -- cgit v1.2.3-70-g09d2