mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 22:24:07 +00:00
Reappy r80998, now that the GlobalOpt bug that it exposed on MiniSAT is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81172 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -571,13 +571,17 @@ protected:
|
|||||||
// These private methods are used by the type resolution code to create
|
// These private methods are used by the type resolution code to create
|
||||||
// ConstantExprs in intermediate forms.
|
// ConstantExprs in intermediate forms.
|
||||||
static Constant *getTy(const Type *Ty, unsigned Opcode,
|
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,
|
static Constant *getCompareTy(unsigned short pred, Constant *C1,
|
||||||
Constant *C2);
|
Constant *C2);
|
||||||
static Constant *getSelectTy(const Type *Ty,
|
static Constant *getSelectTy(const Type *Ty,
|
||||||
Constant *C1, Constant *C2, Constant *C3);
|
Constant *C1, Constant *C2, Constant *C3);
|
||||||
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
|
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
|
||||||
Value* const *Idxs, unsigned NumIdxs);
|
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,
|
static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
|
||||||
Constant *Idx);
|
Constant *Idx);
|
||||||
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
|
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
|
||||||
@ -718,7 +722,8 @@ public:
|
|||||||
/// get - Return a binary or shift operator constant expression,
|
/// get - Return a binary or shift operator constant expression,
|
||||||
/// folding if possible.
|
/// 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.
|
/// @brief Return an ICmp or FCmp comparison operator constant expression.
|
||||||
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
|
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
|
||||||
|
@ -200,19 +200,19 @@ public:
|
|||||||
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
||||||
const Twine &Name = "") {
|
const Twine &Name = "") {
|
||||||
BinaryOperator *BO = CreateAdd(V1, V2, Name);
|
BinaryOperator *BO = CreateAdd(V1, V2, Name);
|
||||||
cast<AddOperator>(BO)->setHasNoSignedWrap(true);
|
BO->setHasNoSignedWrap(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
||||||
const Twine &Name, BasicBlock *BB) {
|
const Twine &Name, BasicBlock *BB) {
|
||||||
BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
|
BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
|
||||||
cast<AddOperator>(BO)->setHasNoSignedWrap(true);
|
BO->setHasNoSignedWrap(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
|
||||||
const Twine &Name, Instruction *I) {
|
const Twine &Name, Instruction *I) {
|
||||||
BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
|
BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
|
||||||
cast<AddOperator>(BO)->setHasNoSignedWrap(true);
|
BO->setHasNoSignedWrap(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,19 +221,19 @@ public:
|
|||||||
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
||||||
const Twine &Name = "") {
|
const Twine &Name = "") {
|
||||||
BinaryOperator *BO = CreateSDiv(V1, V2, Name);
|
BinaryOperator *BO = CreateSDiv(V1, V2, Name);
|
||||||
cast<SDivOperator>(BO)->setIsExact(true);
|
BO->setIsExact(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
||||||
const Twine &Name, BasicBlock *BB) {
|
const Twine &Name, BasicBlock *BB) {
|
||||||
BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
|
BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
|
||||||
cast<SDivOperator>(BO)->setIsExact(true);
|
BO->setIsExact(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
|
||||||
const Twine &Name, Instruction *I) {
|
const Twine &Name, Instruction *I) {
|
||||||
BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
|
BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
|
||||||
cast<SDivOperator>(BO)->setIsExact(true);
|
BO->setIsExact(true);
|
||||||
return BO;
|
return BO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,6 +287,21 @@ public:
|
|||||||
///
|
///
|
||||||
bool swapOperands();
|
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:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const BinaryOperator *) { return true; }
|
static inline bool classof(const BinaryOperator *) { return true; }
|
||||||
static inline bool classof(const Instruction *I) {
|
static inline bool classof(const Instruction *I) {
|
||||||
|
@ -496,7 +496,7 @@ public:
|
|||||||
Instruction *InsertBefore = 0) {
|
Instruction *InsertBefore = 0) {
|
||||||
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
|
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
|
||||||
NameStr, InsertBefore);
|
NameStr, InsertBefore);
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
GEP->setIsInBounds(true);
|
||||||
return GEP;
|
return GEP;
|
||||||
}
|
}
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
@ -507,21 +507,21 @@ public:
|
|||||||
BasicBlock *InsertAtEnd) {
|
BasicBlock *InsertAtEnd) {
|
||||||
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
|
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
|
||||||
NameStr, InsertAtEnd);
|
NameStr, InsertAtEnd);
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
GEP->setIsInBounds(true);
|
||||||
return GEP;
|
return GEP;
|
||||||
}
|
}
|
||||||
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
|
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
|
||||||
const Twine &NameStr = "",
|
const Twine &NameStr = "",
|
||||||
Instruction *InsertBefore = 0) {
|
Instruction *InsertBefore = 0) {
|
||||||
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
|
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
GEP->setIsInBounds(true);
|
||||||
return GEP;
|
return GEP;
|
||||||
}
|
}
|
||||||
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
|
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
|
||||||
const Twine &NameStr,
|
const Twine &NameStr,
|
||||||
BasicBlock *InsertAtEnd) {
|
BasicBlock *InsertAtEnd) {
|
||||||
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
|
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
GEP->setIsInBounds(true);
|
||||||
return GEP;
|
return GEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,6 +602,10 @@ public:
|
|||||||
/// a constant offset between them.
|
/// a constant offset between them.
|
||||||
bool hasAllConstantIndices() const;
|
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:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const GetElementPtrInst *) { return true; }
|
static inline bool classof(const GetElementPtrInst *) { return true; }
|
||||||
static inline bool classof(const Instruction *I) {
|
static inline bool classof(const Instruction *I) {
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class GetElementPtrInst;
|
class GetElementPtrInst;
|
||||||
|
class BinaryOperator;
|
||||||
|
class ConstantExpr;
|
||||||
|
|
||||||
/// Operator - This is a utility class that provides an abstraction for the
|
/// Operator - This is a utility class that provides an abstraction for the
|
||||||
/// common functionality between Instructions and ConstantExprs.
|
/// common functionality between Instructions and ConstantExprs.
|
||||||
@ -67,24 +69,37 @@ public:
|
|||||||
/// despite that operator having the potential for overflow.
|
/// despite that operator having the potential for overflow.
|
||||||
///
|
///
|
||||||
class OverflowingBinaryOperator : public Operator {
|
class OverflowingBinaryOperator : public Operator {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
NoUnsignedWrap = (1 << 0),
|
||||||
|
NoSignedWrap = (1 << 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
~OverflowingBinaryOperator(); // do not implement
|
~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:
|
public:
|
||||||
/// hasNoUnsignedWrap - Test whether this operation is known to never
|
/// hasNoUnsignedWrap - Test whether this operation is known to never
|
||||||
/// undergo unsigned overflow, aka the nuw property.
|
/// undergo unsigned overflow, aka the nuw property.
|
||||||
bool hasNoUnsignedWrap() const {
|
bool hasNoUnsignedWrap() const {
|
||||||
return SubclassOptionalData & (1 << 0);
|
return SubclassOptionalData & NoUnsignedWrap;
|
||||||
}
|
|
||||||
void setHasNoUnsignedWrap(bool B) {
|
|
||||||
SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// hasNoSignedWrap - Test whether this operation is known to never
|
/// hasNoSignedWrap - Test whether this operation is known to never
|
||||||
/// undergo signed overflow, aka the nsw property.
|
/// undergo signed overflow, aka the nsw property.
|
||||||
bool hasNoSignedWrap() const {
|
bool hasNoSignedWrap() const {
|
||||||
return SubclassOptionalData & (1 << 1);
|
return SubclassOptionalData & NoSignedWrap;
|
||||||
}
|
|
||||||
void setHasNoSignedWrap(bool B) {
|
|
||||||
SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool classof(const OverflowingBinaryOperator *) { return true; }
|
static inline bool classof(const OverflowingBinaryOperator *) { return true; }
|
||||||
@ -161,15 +176,25 @@ public:
|
|||||||
/// SDivOperator - An Operator with opcode Instruction::SDiv.
|
/// SDivOperator - An Operator with opcode Instruction::SDiv.
|
||||||
///
|
///
|
||||||
class SDivOperator : public Operator {
|
class SDivOperator : public Operator {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
IsExact = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
~SDivOperator(); // do not implement
|
~SDivOperator(); // do not implement
|
||||||
|
|
||||||
|
friend class BinaryOperator;
|
||||||
|
friend class ConstantExpr;
|
||||||
|
void setIsExact(bool B) {
|
||||||
|
SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// isExact - Test whether this division is known to be exact, with
|
/// isExact - Test whether this division is known to be exact, with
|
||||||
/// zero remainder.
|
/// zero remainder.
|
||||||
bool isExact() const {
|
bool isExact() const {
|
||||||
return SubclassOptionalData & (1 << 0);
|
return SubclassOptionalData & IsExact;
|
||||||
}
|
|
||||||
void setIsExact(bool B) {
|
|
||||||
SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
@ -187,15 +212,24 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class GEPOperator : public Operator {
|
class GEPOperator : public Operator {
|
||||||
|
enum {
|
||||||
|
IsInBounds = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
~GEPOperator(); // do not implement
|
~GEPOperator(); // do not implement
|
||||||
|
|
||||||
|
friend class GetElementPtrInst;
|
||||||
|
friend class ConstantExpr;
|
||||||
|
void setIsInBounds(bool B) {
|
||||||
|
SubclassOptionalData =
|
||||||
|
(SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// isInBounds - Test whether this is an inbounds GEP, as defined
|
/// isInBounds - Test whether this is an inbounds GEP, as defined
|
||||||
/// by LangRef.html.
|
/// by LangRef.html.
|
||||||
bool isInBounds() const {
|
bool isInBounds() const {
|
||||||
return SubclassOptionalData & (1 << 0);
|
return SubclassOptionalData & IsInBounds;
|
||||||
}
|
|
||||||
void setIsInBounds(bool B) {
|
|
||||||
SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline op_iterator idx_begin() { return op_begin()+1; }
|
inline op_iterator idx_begin() { return op_begin()+1; }
|
||||||
|
@ -146,12 +146,6 @@ public:
|
|||||||
// Only use when in type resolution situations!
|
// Only use when in type resolution situations!
|
||||||
void uncheckedReplaceAllUsesWith(Value *V);
|
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.
|
// Methods for handling the chain of uses of this Value.
|
||||||
//
|
//
|
||||||
@ -240,6 +234,13 @@ public:
|
|||||||
return SubclassID;
|
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
|
/// hasSameSubclassOptionalData - Test whether the optional flags contained
|
||||||
/// in this value are equal to the optional flags in the given value.
|
/// in this value are equal to the optional flags in the given value.
|
||||||
bool hasSameSubclassOptionalData(const Value *V) const {
|
bool hasSameSubclassOptionalData(const Value *V) const {
|
||||||
|
@ -2095,13 +2095,11 @@ bool LLParser::ParseValID(ValID &ID) {
|
|||||||
if (!Val0->getType()->isIntOrIntVector() &&
|
if (!Val0->getType()->isIntOrIntVector() &&
|
||||||
!Val0->getType()->isFPOrFPVector())
|
!Val0->getType()->isFPOrFPVector())
|
||||||
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
|
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
|
||||||
Constant *C = ConstantExpr::get(Opc, Val0, Val1);
|
unsigned Flags = 0;
|
||||||
if (NUW)
|
if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
|
||||||
cast<OverflowingBinaryOperator>(C)->setHasNoUnsignedWrap(true);
|
if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap;
|
||||||
if (NSW)
|
if (Exact) Flags |= SDivOperator::IsExact;
|
||||||
cast<OverflowingBinaryOperator>(C)->setHasNoSignedWrap(true);
|
Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
|
||||||
if (Exact)
|
|
||||||
cast<SDivOperator>(C)->setIsExact(true);
|
|
||||||
ID.ConstantVal = C;
|
ID.ConstantVal = C;
|
||||||
ID.Kind = ValID::t_Constant;
|
ID.Kind = ValID::t_Constant;
|
||||||
return false;
|
return false;
|
||||||
@ -2157,10 +2155,12 @@ bool LLParser::ParseValID(ValID &ID) {
|
|||||||
(Value**)(Elts.data() + 1),
|
(Value**)(Elts.data() + 1),
|
||||||
Elts.size() - 1))
|
Elts.size() - 1))
|
||||||
return Error(ID.Loc, "invalid indices for getelementptr");
|
return Error(ID.Loc, "invalid indices for getelementptr");
|
||||||
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
|
ID.ConstantVal = InBounds ?
|
||||||
Elts.data() + 1, Elts.size() - 1);
|
ConstantExpr::getInBoundsGetElementPtr(Elts[0],
|
||||||
if (InBounds)
|
Elts.data() + 1,
|
||||||
cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true);
|
Elts.size() - 1) :
|
||||||
|
ConstantExpr::getGetElementPtr(Elts[0],
|
||||||
|
Elts.data() + 1, Elts.size() - 1);
|
||||||
} else if (Opc == Instruction::Select) {
|
} else if (Opc == Instruction::Select) {
|
||||||
if (Elts.size() != 3)
|
if (Elts.size() != 3)
|
||||||
return Error(ID.Loc, "expected three operands to select");
|
return Error(ID.Loc, "expected three operands to select");
|
||||||
@ -2681,9 +2681,9 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|||||||
return Error(ModifierLoc, "nsw only applies to integer operations");
|
return Error(ModifierLoc, "nsw only applies to integer operations");
|
||||||
}
|
}
|
||||||
if (NUW)
|
if (NUW)
|
||||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
|
cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
|
||||||
if (NSW)
|
if (NSW)
|
||||||
cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedWrap(true);
|
cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -2698,7 +2698,7 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|||||||
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
|
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
if (Exact)
|
if (Exact)
|
||||||
cast<SDivOperator>(Inst)->setIsExact(true);
|
cast<BinaryOperator>(Inst)->setIsExact(true);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3501,7 +3501,7 @@ bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
return Error(Loc, "invalid getelementptr indices");
|
return Error(Loc, "invalid getelementptr indices");
|
||||||
Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
|
Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
|
||||||
if (InBounds)
|
if (InBounds)
|
||||||
cast<GEPOperator>(Inst)->setIsInBounds(true);
|
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,19 +883,6 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {
|
|||||||
return false;
|
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() {
|
bool BitcodeReader::ParseConstants() {
|
||||||
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
|
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
|
||||||
return Error("Malformed block record");
|
return Error("Malformed block record");
|
||||||
@ -1047,10 +1034,22 @@ bool BitcodeReader::ParseConstants() {
|
|||||||
} else {
|
} else {
|
||||||
Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
|
Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
|
||||||
Constant *RHS = ValueList.getConstantFwdRef(Record[2], 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;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
|
case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
|
||||||
@ -1075,10 +1074,12 @@ bool BitcodeReader::ParseConstants() {
|
|||||||
if (!ElTy) return Error("Invalid CE_GEP record");
|
if (!ElTy) return Error("Invalid CE_GEP record");
|
||||||
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
|
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)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
|
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
|
||||||
@ -1610,8 +1611,19 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||||||
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
|
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
|
||||||
if (Opc == -1) return Error("Invalid BINOP record");
|
if (Opc == -1) return Error("Invalid BINOP record");
|
||||||
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
||||||
if (OpNum < Record.size())
|
if (OpNum < Record.size()) {
|
||||||
SetOptimizationFlags(I, Record[3]);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
|
case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
|
||||||
@ -1645,7 +1657,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||||||
|
|
||||||
I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
|
I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
|
||||||
if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
|
if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
|
||||||
cast<GEPOperator>(I)->setIsInBounds(true);
|
cast<GetElementPtrInst>(I)->setIsInBounds(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8086,11 +8086,11 @@ Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
|
|||||||
// If we were able to index down into an element, create the GEP
|
// If we were able to index down into an element, create the GEP
|
||||||
// and bitcast the result. This eliminates one bitcast, potentially
|
// and bitcast the result. This eliminates one bitcast, potentially
|
||||||
// two.
|
// two.
|
||||||
Value *NGEP = Builder->CreateGEP(OrigBase, NewIndices.begin(),
|
Value *NGEP = cast<GEPOperator>(GEP)->isInBounds() ?
|
||||||
NewIndices.end());
|
Builder->CreateInBoundsGEP(OrigBase,
|
||||||
|
NewIndices.begin(), NewIndices.end()) :
|
||||||
|
Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
|
||||||
NGEP->takeName(GEP);
|
NGEP->takeName(GEP);
|
||||||
if (isa<Instruction>(NGEP) && cast<GEPOperator>(GEP)->isInBounds())
|
|
||||||
cast<GEPOperator>(NGEP)->setIsInBounds(true);
|
|
||||||
|
|
||||||
if (isa<BitCastInst>(CI))
|
if (isa<BitCastInst>(CI))
|
||||||
return new BitCastInst(NGEP, CI.getType());
|
return new BitCastInst(NGEP, CI.getType());
|
||||||
@ -8805,11 +8805,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
|
|||||||
// If we found a path from the src to dest, create the getelementptr now.
|
// If we found a path from the src to dest, create the getelementptr now.
|
||||||
if (SrcElTy == DstElTy) {
|
if (SrcElTy == DstElTy) {
|
||||||
SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
|
SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
|
||||||
Instruction *GEP = GetElementPtrInst::Create(Src,
|
return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(), "",
|
||||||
Idxs.begin(), Idxs.end(), "",
|
((Instruction*) NULL));
|
||||||
((Instruction*) NULL));
|
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
|
||||||
return GEP;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10481,12 +10478,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value *Base = FixedOperands[0];
|
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,
|
GetElementPtrInst::Create(Base, FixedOperands.begin()+1,
|
||||||
FixedOperands.end());
|
FixedOperands.end());
|
||||||
if (cast<GEPOperator>(FirstInst)->isInBounds())
|
|
||||||
cast<GEPOperator>(GEP)->setIsInBounds(true);
|
|
||||||
return GEP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10889,14 +10885,13 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
Indices.append(GEP.idx_begin()+1, GEP.idx_end());
|
Indices.append(GEP.idx_begin()+1, GEP.idx_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Indices.empty()) {
|
if (!Indices.empty())
|
||||||
GetElementPtrInst *NewGEP =
|
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(),
|
GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
|
||||||
Indices.end(), GEP.getName());
|
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).
|
// Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
|
||||||
@ -10926,12 +10921,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
if (CATy->getElementType() == XTy->getElementType()) {
|
if (CATy->getElementType() == XTy->getElementType()) {
|
||||||
// -> GEP i8* X, ...
|
// -> GEP i8* X, ...
|
||||||
SmallVector<Value*, 8> Indices(GEP.idx_begin()+1, GEP.idx_end());
|
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(),
|
GetElementPtrInst::Create(X, Indices.begin(), Indices.end(),
|
||||||
GEP.getName());
|
GEP.getName());
|
||||||
if (cast<GEPOperator>(&GEP)->isInBounds())
|
|
||||||
cast<GEPOperator>(NewGEP)->setIsInBounds(true);
|
|
||||||
return NewGEP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const ArrayType *XATy = dyn_cast<ArrayType>(XTy->getElementType())){
|
if (const ArrayType *XATy = dyn_cast<ArrayType>(XTy->getElementType())){
|
||||||
@ -10959,10 +10953,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
Value *Idx[2];
|
Value *Idx[2];
|
||||||
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
||||||
Idx[1] = GEP.getOperand(1);
|
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());
|
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
|
// V and GEP are both pointer types --> BitCast
|
||||||
return new BitCastInst(NewGEP, GEP.getType());
|
return new BitCastInst(NewGEP, GEP.getType());
|
||||||
}
|
}
|
||||||
@ -11019,9 +11012,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
Value *Idx[2];
|
Value *Idx[2];
|
||||||
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
||||||
Idx[1] = NewIdx;
|
Idx[1] = NewIdx;
|
||||||
Value *NewGEP = Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
|
Value *NewGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
|
||||||
if (cast<GEPOperator>(&GEP)->isInBounds())
|
Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
|
||||||
cast<GEPOperator>(NewGEP)->setIsInBounds(true);
|
Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
|
||||||
// The NewGEP must be pointer typed, so must the old one -> BitCast
|
// The NewGEP must be pointer typed, so must the old one -> BitCast
|
||||||
return new BitCastInst(NewGEP, GEP.getType());
|
return new BitCastInst(NewGEP, GEP.getType());
|
||||||
}
|
}
|
||||||
@ -11069,10 +11062,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
const Type *InTy =
|
const Type *InTy =
|
||||||
cast<PointerType>(BCI->getOperand(0)->getType())->getElementType();
|
cast<PointerType>(BCI->getOperand(0)->getType())->getElementType();
|
||||||
if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
|
if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
|
||||||
Value *NGEP = Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
|
Value *NGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
|
||||||
NewIndices.end());
|
Builder->CreateInBoundsGEP(BCI->getOperand(0), NewIndices.begin(),
|
||||||
if (cast<GEPOperator>(&GEP)->isInBounds())
|
NewIndices.end()) :
|
||||||
cast<GEPOperator>(NGEP)->setIsInBounds(true);
|
Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
|
||||||
|
NewIndices.end());
|
||||||
|
|
||||||
if (NGEP->getType() == GEP.getType())
|
if (NGEP->getType() == GEP.getType())
|
||||||
return ReplaceInstUsesWith(GEP, NGEP);
|
return ReplaceInstUsesWith(GEP, NGEP);
|
||||||
@ -11115,9 +11109,8 @@ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
|
|||||||
Value *Idx[2];
|
Value *Idx[2];
|
||||||
Idx[0] = NullIdx;
|
Idx[0] = NullIdx;
|
||||||
Idx[1] = NullIdx;
|
Idx[1] = NullIdx;
|
||||||
Value *V = GetElementPtrInst::Create(New, Idx, Idx + 2,
|
Value *V = GetElementPtrInst::CreateInBounds(New, Idx, Idx + 2,
|
||||||
New->getName()+".sub", It);
|
New->getName()+".sub", It);
|
||||||
cast<GEPOperator>(V)->setIsInBounds(true);
|
|
||||||
|
|
||||||
// Now make everything use the getelementptr instead of the original
|
// Now make everything use the getelementptr instead of the original
|
||||||
// allocation.
|
// allocation.
|
||||||
@ -11486,11 +11479,9 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
|
|
||||||
// SIOp0 is a pointer to aggregate and this is a store to the first field,
|
// SIOp0 is a pointer to aggregate and this is a store to the first field,
|
||||||
// emit a GEP to index into its first field.
|
// emit a GEP to index into its first field.
|
||||||
if (!NewGEPIndices.empty()) {
|
if (!NewGEPIndices.empty())
|
||||||
CastOp = IC.Builder->CreateGEP(CastOp, NewGEPIndices.begin(),
|
CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices.begin(),
|
||||||
NewGEPIndices.end());
|
NewGEPIndices.end());
|
||||||
cast<GEPOperator>(CastOp)->setIsInBounds(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
|
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
|
||||||
SIOp0->getName()+".c");
|
SIOp0->getName()+".c");
|
||||||
|
@ -632,21 +632,13 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
|
Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
|
||||||
Constant *C = getAdd(C1, C2);
|
return getTy(C1->getType(), Instruction::Add, C1, C2,
|
||||||
// Set nsw attribute, assuming constant folding didn't eliminate the
|
OverflowingBinaryOperator::NoSignedWrap);
|
||||||
// Add.
|
|
||||||
if (AddOperator *Add = dyn_cast<AddOperator>(C))
|
|
||||||
Add->setHasNoSignedWrap(true);
|
|
||||||
return C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
|
Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
|
||||||
Constant *C = getSDiv(C1, C2);
|
return getTy(C1->getType(), Instruction::SDiv, C1, C2,
|
||||||
// Set exact attribute, assuming constant folding didn't eliminate the
|
SDivOperator::IsExact);
|
||||||
// SDiv.
|
|
||||||
if (SDivOperator *SDiv = dyn_cast<SDivOperator>(C))
|
|
||||||
SDiv->setIsExact(true);
|
|
||||||
return C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function for determining if a ConstantExpr is a CastOp or not. This
|
// Utility function for determining if a ConstantExpr is a CastOp or not. This
|
||||||
@ -729,15 +721,19 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
|
|||||||
for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
|
for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
|
||||||
Ops[i-1] = getOperand(i);
|
Ops[i-1] = getOperand(i);
|
||||||
if (OpNo == 0)
|
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;
|
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:
|
default:
|
||||||
assert(getNumOperands() == 2 && "Must be binary operator?");
|
assert(getNumOperands() == 2 && "Must be binary operator?");
|
||||||
Op0 = (OpNo == 0) ? Op : getOperand(0);
|
Op0 = (OpNo == 0) ? Op : getOperand(0);
|
||||||
Op1 = (OpNo == 1) ? Op : getOperand(1);
|
Op1 = (OpNo == 1) ? Op : getOperand(1);
|
||||||
return ConstantExpr::get(getOpcode(), Op0, Op1);
|
return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -779,13 +775,15 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const {
|
|||||||
case Instruction::ShuffleVector:
|
case Instruction::ShuffleVector:
|
||||||
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
|
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
|
||||||
case Instruction::GetElementPtr:
|
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::ICmp:
|
||||||
case Instruction::FCmp:
|
case Instruction::FCmp:
|
||||||
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
|
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
|
||||||
default:
|
default:
|
||||||
assert(getNumOperands() == 2 && "Must be binary operator?");
|
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 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
|
|||||||
Operands.reserve(CE->getNumOperands());
|
Operands.reserve(CE->getNumOperands());
|
||||||
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
|
||||||
Operands.push_back(cast<Constant>(CE->getOperand(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->isCompare() ? CE->getPredicate() : 0,
|
||||||
|
CE->getRawSubclassOptionalData(),
|
||||||
CE->hasIndices() ?
|
CE->hasIndices() ?
|
||||||
CE->getIndices() : SmallVector<unsigned, 4>());
|
CE->getIndices() : SmallVector<unsigned, 4>());
|
||||||
}
|
}
|
||||||
@ -1280,7 +1279,8 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
|
Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
|
||||||
Constant *C1, Constant *C2) {
|
Constant *C1, Constant *C2,
|
||||||
|
unsigned Flags) {
|
||||||
// Check the operands for consistency first
|
// Check the operands for consistency first
|
||||||
assert(Opcode >= Instruction::BinaryOpsBegin &&
|
assert(Opcode >= Instruction::BinaryOpsBegin &&
|
||||||
Opcode < Instruction::BinaryOpsEnd &&
|
Opcode < Instruction::BinaryOpsEnd &&
|
||||||
@ -1294,7 +1294,7 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
|
|||||||
return FC; // Fold a few common cases...
|
return FC; // Fold a few common cases...
|
||||||
|
|
||||||
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
|
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;
|
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
|
||||||
|
|
||||||
@ -1322,7 +1322,8 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// API compatibility: Adjust integer opcodes to floating-point opcodes.
|
||||||
if (C1->getType()->isFPOrFPVector()) {
|
if (C1->getType()->isFPOrFPVector()) {
|
||||||
if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
|
if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
|
||||||
@ -1387,7 +1388,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return getTy(C1->getType(), Opcode, C1, C2);
|
return getTy(C1->getType(), Opcode, C1, C2, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant* ConstantExpr::getSizeOf(const Type* Ty) {
|
Constant* ConstantExpr::getSizeOf(const Type* Ty) {
|
||||||
@ -1481,6 +1482,36 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
|
|||||||
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
|
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,
|
Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
|
||||||
unsigned NumIdx) {
|
unsigned NumIdx) {
|
||||||
// Get the result type of the getelementptr!
|
// Get the result type of the getelementptr!
|
||||||
@ -1494,12 +1525,12 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
|
|||||||
Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
|
Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
|
||||||
Value* const *Idxs,
|
Value* const *Idxs,
|
||||||
unsigned NumIdx) {
|
unsigned NumIdx) {
|
||||||
Constant *Result = getGetElementPtr(C, Idxs, NumIdx);
|
// Get the result type of the getelementptr!
|
||||||
// Set in bounds attribute, assuming constant folding didn't eliminate the
|
const Type *Ty =
|
||||||
// GEP.
|
GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
|
||||||
if (GEPOperator *GEP = dyn_cast<GEPOperator>(Result))
|
assert(Ty && "GEP indices invalid!");
|
||||||
GEP->setIsInBounds(true);
|
unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
|
||||||
return Result;
|
return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
|
Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
|
||||||
@ -2104,7 +2135,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
|
|||||||
Constant *C2 = getOperand(1);
|
Constant *C2 = getOperand(1);
|
||||||
if (C1 == From) C1 = To;
|
if (C1 == From) C1 = To;
|
||||||
if (C2 == From) C2 = To;
|
if (C2 == From) C2 = To;
|
||||||
Replacement = ConstantExpr::get(getOpcode(), C1, C2);
|
Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
|
||||||
} else {
|
} else {
|
||||||
llvm_unreachable("Unknown ConstantExpr type!");
|
llvm_unreachable("Unknown ConstantExpr type!");
|
||||||
return;
|
return;
|
||||||
|
@ -53,10 +53,12 @@ public:
|
|||||||
void *operator new(size_t s) {
|
void *operator new(size_t s) {
|
||||||
return User::operator new(s, 2);
|
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) {
|
: ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
|
||||||
Op<0>() = C1;
|
Op<0>() = C1;
|
||||||
Op<1>() = C2;
|
Op<1>() = C2;
|
||||||
|
SubclassOptionalData = Flags;
|
||||||
}
|
}
|
||||||
/// Transparently provide more efficient getOperand methods.
|
/// Transparently provide more efficient getOperand methods.
|
||||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||||
@ -206,9 +208,12 @@ class GetElementPtrConstantExpr : public ConstantExpr {
|
|||||||
public:
|
public:
|
||||||
static GetElementPtrConstantExpr *Create(Constant *C,
|
static GetElementPtrConstantExpr *Create(Constant *C,
|
||||||
const std::vector<Constant*>&IdxList,
|
const std::vector<Constant*>&IdxList,
|
||||||
const Type *DestTy) {
|
const Type *DestTy,
|
||||||
return
|
unsigned Flags) {
|
||||||
|
GetElementPtrConstantExpr *Result =
|
||||||
new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
|
new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
|
||||||
|
Result->SubclassOptionalData = Flags;
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
/// Transparently provide more efficient getOperand methods.
|
/// Transparently provide more efficient getOperand methods.
|
||||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||||
@ -291,26 +296,32 @@ struct ExprMapKeyType {
|
|||||||
|
|
||||||
ExprMapKeyType(unsigned opc,
|
ExprMapKeyType(unsigned opc,
|
||||||
const std::vector<Constant*> &ops,
|
const std::vector<Constant*> &ops,
|
||||||
unsigned short pred = 0,
|
unsigned short flags = 0,
|
||||||
|
unsigned short optionalflags = 0,
|
||||||
const IndexList &inds = IndexList())
|
const IndexList &inds = IndexList())
|
||||||
: opcode(opc), predicate(pred), operands(ops), indices(inds) {}
|
: opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
|
||||||
uint16_t opcode;
|
operands(ops), indices(inds) {}
|
||||||
uint16_t predicate;
|
uint8_t opcode;
|
||||||
|
uint8_t subclassoptionaldata;
|
||||||
|
uint16_t subclassdata;
|
||||||
std::vector<Constant*> operands;
|
std::vector<Constant*> operands;
|
||||||
IndexList indices;
|
IndexList indices;
|
||||||
bool operator==(const ExprMapKeyType& that) const {
|
bool operator==(const ExprMapKeyType& that) const {
|
||||||
return this->opcode == that.opcode &&
|
return this->opcode == that.opcode &&
|
||||||
this->predicate == that.predicate &&
|
this->subclassdata == that.subclassdata &&
|
||||||
|
this->subclassoptionaldata == that.subclassoptionaldata &&
|
||||||
this->operands == that.operands &&
|
this->operands == that.operands &&
|
||||||
this->indices == that.indices;
|
this->indices == that.indices;
|
||||||
}
|
}
|
||||||
bool operator<(const ExprMapKeyType & that) const {
|
bool operator<(const ExprMapKeyType & that) const {
|
||||||
return this->opcode < that.opcode ||
|
if (this->opcode != that.opcode) return this->opcode < that.opcode;
|
||||||
(this->opcode == that.opcode && this->predicate < that.predicate) ||
|
if (this->operands != that.operands) return this->operands < that.operands;
|
||||||
(this->opcode == that.opcode && this->predicate == that.predicate &&
|
if (this->subclassdata != that.subclassdata)
|
||||||
this->operands < that.operands) ||
|
return this->subclassdata < that.subclassdata;
|
||||||
(this->opcode == that.opcode && this->predicate == that.predicate &&
|
if (this->subclassoptionaldata != that.subclassoptionaldata)
|
||||||
this->operands == that.operands && this->indices < that.indices);
|
return this->subclassoptionaldata < that.subclassoptionaldata;
|
||||||
|
if (this->indices != that.indices) return this->indices < that.indices;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ExprMapKeyType& that) const {
|
bool operator!=(const ExprMapKeyType& that) const {
|
||||||
@ -354,7 +365,8 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
|
|||||||
return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
|
return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
|
||||||
if ((V.opcode >= Instruction::BinaryOpsBegin &&
|
if ((V.opcode >= Instruction::BinaryOpsBegin &&
|
||||||
V.opcode < Instruction::BinaryOpsEnd))
|
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)
|
if (V.opcode == Instruction::Select)
|
||||||
return new SelectConstantExpr(V.operands[0], V.operands[1],
|
return new SelectConstantExpr(V.operands[0], V.operands[1],
|
||||||
V.operands[2]);
|
V.operands[2]);
|
||||||
@ -373,17 +385,18 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
|
|||||||
return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
|
return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
|
||||||
if (V.opcode == Instruction::GetElementPtr) {
|
if (V.opcode == Instruction::GetElementPtr) {
|
||||||
std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
|
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
|
// The compare instructions are weird. We have to encode the predicate
|
||||||
// value and it is combined with the instruction opcode by multiplying
|
// value and it is combined with the instruction opcode by multiplying
|
||||||
// the opcode by one hundred. We must decode this to get the predicate.
|
// the opcode by one hundred. We must decode this to get the predicate.
|
||||||
if (V.opcode == Instruction::ICmp)
|
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]);
|
V.operands[0], V.operands[1]);
|
||||||
if (V.opcode == Instruction::FCmp)
|
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]);
|
V.operands[0], V.operands[1]);
|
||||||
llvm_unreachable("Invalid ConstantExpr!");
|
llvm_unreachable("Invalid ConstantExpr!");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1171,6 +1171,9 @@ bool GetElementPtrInst::hasAllConstantIndices() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetElementPtrInst::setIsInBounds(bool B) {
|
||||||
|
cast<GEPOperator>(this)->setIsInBounds(B);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ExtractElementInst Implementation
|
// ExtractElementInst Implementation
|
||||||
@ -1716,6 +1719,18 @@ bool BinaryOperator::swapOperands() {
|
|||||||
return false;
|
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
|
// CastInst Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
|
||||||
|
|
||||||
@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)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
|
||||||
|
|
||||||
@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)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
|
||||||
|
|
||||||
@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)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
|
||||||
|
|
||||||
@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)
|
|
||||||
}
|
|
@ -141,4 +141,72 @@ define i64* @gep_nw_ce() {
|
|||||||
ret i64* getelementptr inbounds (i64* @addr, i64 171)
|
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)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user