For PR950:

This patch removes the SetCC instructions and replaces them with the ICmp
and FCmp instructions. The SetCondInst instruction has been removed and
been replaced with ICmpInst and FCmpInst.

llvm-svn: 32751
This commit is contained in:
Reid Spencer 2006-12-23 06:05:41 +00:00
parent f171af97d5
commit 266e42b312
84 changed files with 7699 additions and 6406 deletions

View File

@ -58,7 +58,7 @@ static Function *CreateFibFunction(Module *M) {
BasicBlock* RecurseBB = new BasicBlock("recurse", FibF);
// Create the "if (arg < 2) goto exitbb"
Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB);
Value *CondInst = new ICmpInst(ICmpInst::ICMP_SLE, ArgX, Two, "cond", BB);
new BranchInst(RetBB, RecurseBB, CondInst, BB);
// Create: ret int 1

View File

@ -83,7 +83,7 @@ static Function *CreateFibFunction(Module *M)
BasicBlock* RecurseBB = new BasicBlock("recurse", FibF);
// Create the "if (arg < 2) goto exitbb"
Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB);
Value *CondInst = new ICmpInst(ICmpInst::ICMP_SLE, ArgX, Two, "cond", BB);
new BranchInst(RetBB, RecurseBB, CondInst, BB);
// Create: ret int 1

View File

@ -426,8 +426,10 @@ namespace llvm {
/// looking at this is that it returns the first iteration number where the
/// value is not in the condition, thus computing the exit count. If the
/// iteration count can't be computed, an instance of SCEVCouldNotCompute is
/// returned.
SCEVHandle getNumIterationsInRange(ConstantRange Range) const;
/// returned. The isSigned parameter indicates whether the ConstantRange
/// should be treated as signed or unsigned.
SCEVHandle getNumIterationsInRange(ConstantRange Range,
bool isSigned) const;
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
const SCEVHandle &Conc) const;

View File

@ -496,8 +496,8 @@ protected:
// ConstantExprs in intermediate forms.
static Constant *getTy(const Type *Ty, unsigned Opcode,
Constant *C1, Constant *C2);
static Constant *getCompareTy(unsigned Opcode, unsigned short pred,
Constant *C1, Constant *C2);
static Constant *getCompareTy(unsigned short pred, Constant *C1,
Constant *C2);
static Constant *getShiftTy(const Type *Ty,
unsigned Opcode, Constant *C1, Constant *C2);
static Constant *getSelectTy(const Type *Ty,
@ -604,8 +604,7 @@ public:
static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
/// @brief Return an ICmp or FCmp comparison operator constant expression.
static Constant *getCompare(unsigned Opcode, unsigned short pred,
Constant *C1, Constant *C2);
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
/// ConstantExpr::get* - Return some common constants without having to
/// specify the full Instruction::OPCODE identifier.
@ -624,12 +623,6 @@ public:
static Constant *getAnd(Constant *C1, Constant *C2);
static Constant *getOr(Constant *C1, Constant *C2);
static Constant *getXor(Constant *C1, Constant *C2);
static Constant *getSetEQ(Constant *C1, Constant *C2);
static Constant *getSetNE(Constant *C1, Constant *C2);
static Constant *getSetLT(Constant *C1, Constant *C2);
static Constant *getSetGT(Constant *C1, Constant *C2);
static Constant *getSetLE(Constant *C1, Constant *C2);
static Constant *getSetGE(Constant *C1, Constant *C2);
static Constant* getICmp(unsigned short pred, Constant* LHS, Constant* RHS);
static Constant* getFCmp(unsigned short pred, Constant* LHS, Constant* RHS);
static Constant *getShl(Constant *C1, Constant *C2);

View File

@ -543,6 +543,20 @@ public:
/// @brief Determine if this is an equals/not equals predicate.
bool isEquality();
/// @returns true if the predicate is unsigned, false otherwise.
/// @brief Determine if the predicate is an unsigned operation.
static bool isUnsigned(unsigned short predicate);
/// @returns true if the predicate is signed, false otherwise.
/// @brief Determine if the predicate is an signed operation.
static bool isSigned(unsigned short predicate);
/// @brief Determine if the predicate is an ordered operation.
static bool isOrdered(unsigned short predicate);
/// @brief Determine if the predicate is an unordered operation.
static bool isUnordered(unsigned short predicate);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const CmpInst *) { return true; }
static inline bool classof(const Instruction *I) {

View File

@ -118,61 +118,53 @@ HANDLE_BINARY_INST(15, FRem , BinaryOperator)
HANDLE_BINARY_INST(16, And , BinaryOperator)
HANDLE_BINARY_INST(17, Or , BinaryOperator)
HANDLE_BINARY_INST(18, Xor , BinaryOperator)
// Binary comparison operators...
HANDLE_BINARY_INST(19, SetEQ , SetCondInst)
HANDLE_BINARY_INST(20, SetNE , SetCondInst)
HANDLE_BINARY_INST(21, SetLE , SetCondInst)
HANDLE_BINARY_INST(22, SetGE , SetCondInst)
HANDLE_BINARY_INST(23, SetLT , SetCondInst)
HANDLE_BINARY_INST(24, SetGT , SetCondInst)
LAST_BINARY_INST(24)
LAST_BINARY_INST(18)
// Memory operators...
FIRST_MEMORY_INST(25)
HANDLE_MEMORY_INST(25, Malloc, MallocInst) // Heap management instructions
HANDLE_MEMORY_INST(26, Free , FreeInst )
HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(29, Store , StoreInst )
HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(30)
FIRST_MEMORY_INST(19)
HANDLE_MEMORY_INST(19, Malloc, MallocInst) // Heap management instructions
HANDLE_MEMORY_INST(20, Free , FreeInst )
HANDLE_MEMORY_INST(21, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(22, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(23, Store , StoreInst )
HANDLE_MEMORY_INST(24, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(24)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(31)
HANDLE_CAST_INST(31, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(32, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(33, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(34, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(35, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(36, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(37, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(38, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(39, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(40, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(41, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(42, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(42)
FIRST_CAST_INST(25)
HANDLE_CAST_INST(25, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(26, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(27, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(28, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(29, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(30, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(31, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(32, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(33, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(34, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(35, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(36, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(36)
// Other operators...
FIRST_OTHER_INST(43)
HANDLE_OTHER_INST(43, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(44, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(45, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(46, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(47, Shl , ShiftInst ) // Shift Left operations (logical)
HANDLE_OTHER_INST(48, LShr , ShiftInst ) // Logical Shift right (unsigned)
HANDLE_OTHER_INST(49, AShr , ShiftInst ) // Arithmetic shift right (signed)
HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector.
HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
LAST_OTHER_INST(56)
FIRST_OTHER_INST(37)
HANDLE_OTHER_INST(37, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(38, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(39, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(40, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(41, Shl , ShiftInst ) // Shift Left operations (logical)
HANDLE_OTHER_INST(42, LShr , ShiftInst ) // Logical Shift right (unsigned)
HANDLE_OTHER_INST(43, AShr , ShiftInst ) // Arithmetic shift right (signed)
HANDLE_OTHER_INST(44, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(45, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(46, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector.
HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
LAST_OTHER_INST(50)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@ -71,6 +71,16 @@ public:
/// extra information (e.g. load is volatile) agree.
bool isIdenticalTo(Instruction *I) const;
/// This function determines if the specified instruction executes the same
/// operation as the current one. This means that the opcodes, type, operand
/// types and any other factors affecting the operation must be the same. This
/// is similar to isIdenticalTo except the operands themselves don't have to
/// be identical.
/// @returns true if the specified instruction is the same operation as
/// the current one.
/// @brief Determine if one instruction is the same operation as another.
bool isSameOperationAs(Instruction *I) const;
/// use_back - Specialize the methods defined in Value, as we know that an
/// instruction can only be used by other instructions.
Instruction *use_back() { return cast<Instruction>(*use_begin());}
@ -155,12 +165,6 @@ public:
bool isCommutative() const { return isCommutative(getOpcode()); }
static bool isCommutative(unsigned op);
/// isComparison - Return true if the instruction is a Set* instruction:
///
bool isComparison() const { return isComparison(getOpcode()); }
static bool isComparison(unsigned op);
/// isTrappingInstruction - Return true if the instruction may trap.
///
bool isTrapping() const {

View File

@ -440,7 +440,8 @@ public:
ICMP_SLT = 40, ///< signed less than
ICMP_SLE = 41, ///< signed less or equal
FIRST_ICMP_PREDICATE = ICMP_EQ,
LAST_ICMP_PREDICATE = ICMP_SLE
LAST_ICMP_PREDICATE = ICMP_SLE,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
};
/// @brief Constructor with insert-before-instruction semantics.
@ -490,16 +491,30 @@ public:
/// This is a static version that you can use without an instruction
/// available.
/// @brief Return the predicate as if the operands were swapped.
static Predicate getSwappedPredicate(Predicate Opcode);
static Predicate getSwappedPredicate(Predicate pred);
/// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
/// @returns the predicate that would be the result if the operand were
/// regarded as signed.
/// @brief Return the signed version of the predicate
Predicate getSignedPredicate() const {
return getSignedPredicate(getPredicate());
}
/// This is a static version that you can use without an instruction.
/// @brief Return the signed version of the predicate.
static Predicate getSignedPredicate(Predicate pred);
/// This also tests for commutativity. If isEquality() returns true then
/// the predicate is also commutative. Only the equality predicates are
/// commutative.
/// the predicate is also commutative.
/// @returns true if the predicate of this instruction is EQ or NE.
/// @brief Determine if this is an equality predicate.
bool isEquality() const {
return SubclassData == ICMP_EQ || SubclassData == ICMP_NE;
}
/// @returns true if the predicate of this ICmpInst is commutative
/// @brief Determine if this relation is commutative.
bool isCommutative() const { return isEquality(); }
/// @returns true if the predicate is relational (not EQ or NE).
@ -508,6 +523,14 @@ public:
return !isEquality();
}
/// @returns true if the predicate of this ICmpInst is signed, false otherwise
/// @brief Determine if this instruction's predicate is signed.
bool isSignedPredicate() { return isSignedPredicate(getPredicate()); }
/// @returns true if the predicate provided is signed, false otherwise
/// @brief Determine if the predicate is signed.
static bool isSignedPredicate(Predicate pred);
/// Exchange the two operands to this instruction in such a way that it does
/// not modify the semantics of the instruction. The predicate value may be
/// changed to retain the same result if the predicate is order dependent
@ -559,7 +582,8 @@ public:
FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal
FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded)
FIRST_FCMP_PREDICATE = FCMP_FALSE,
LAST_FCMP_PREDICATE = FCMP_TRUE
LAST_FCMP_PREDICATE = FCMP_TRUE,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1
};
/// @brief Constructor with insert-before-instruction semantics.
@ -646,71 +670,6 @@ public:
}
};
//===----------------------------------------------------------------------===//
// SetCondInst Class
//===----------------------------------------------------------------------===//
/// SetCondInst class - Represent a setCC operator, where CC is eq, ne, lt, gt,
/// le, or ge.
///
class SetCondInst : public BinaryOperator {
public:
SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS,
const std::string &Name = "", Instruction *InsertBefore = 0);
SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS,
const std::string &Name, BasicBlock *InsertAtEnd);
/// getInverseCondition - Return the inverse of the current condition opcode.
/// For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
///
BinaryOps getInverseCondition() const {
return getInverseCondition(getOpcode());
}
/// getInverseCondition - Static version that you can use without an
/// instruction available.
///
static BinaryOps getInverseCondition(BinaryOps Opcode);
/// getSwappedCondition - Return the condition opcode that would be the result
/// of exchanging the two operands of the setcc instruction without changing
/// the result produced. Thus, seteq->seteq, setle->setge, setlt->setgt, etc.
///
BinaryOps getSwappedCondition() const {
return getSwappedCondition(getOpcode());
}
/// getSwappedCondition - Static version that you can use without an
/// instruction available.
///
static BinaryOps getSwappedCondition(BinaryOps Opcode);
/// isEquality - Return true if this comparison is an ==/!= comparison.
///
bool isEquality() const {
return getOpcode() == SetEQ || getOpcode() == SetNE;
}
/// isRelational - Return true if this comparison is a </>/<=/>= comparison.
///
bool isRelational() const {
return !isEquality();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SetCondInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == SetEQ || I->getOpcode() == SetNE ||
I->getOpcode() == SetLE || I->getOpcode() == SetGE ||
I->getOpcode() == SetLT || I->getOpcode() == SetGT;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
//===----------------------------------------------------------------------===//
// CallInst Class
//===----------------------------------------------------------------------===//

View File

@ -36,7 +36,7 @@
#include <typeinfo>
#include <cassert>
//#define USE_OLD_PASSMANAGER 1
#define USE_OLD_PASSMANAGER 1
namespace llvm {

View File

@ -12,13 +12,19 @@
// constant, which MAY wrap around the end of the numeric range. To do this, it
// keeps track of a [lower, upper) bound, which specifies an interval just like
// STL iterators. When used with boolean values, the following are important
// ranges (other integral ranges use min/max values for special range values):
// ranges: :
//
// [F, F) = {} = Empty set
// [T, F) = {T}
// [F, T) = {F}
// [T, T) = {F, T} = Full set
//
// The other integral ranges use min/max values for special range values. For
// example, for 8-bit types, it uses:
// [0, 0) = {} = Empty set
// [255, 255) = {0..255} = Full Set
//
// Note that ConstantRange always keeps unsigned values.
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
@ -51,9 +57,11 @@ class ConstantRange {
///
ConstantRange(Constant *Lower, Constant *Upper);
/// Initialize a set of values that all satisfy the condition with C.
///
ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C);
/// Initialize a set of values that all satisfy the predicate with C. The
/// predicate should be either an ICmpInst::Predicate or FCmpInst::Predicate
/// value.
/// @brief Get a range for a relation with a constant integral.
ConstantRange(unsigned short predicate, ConstantIntegral *C);
/// getLower - Return the lower value for this range...
///
@ -79,11 +87,13 @@ class ConstantRange {
/// isWrappedSet - Return true if this set wraps around the top of the range,
/// for example: [100, 8)
///
bool isWrappedSet() const;
bool isWrappedSet(bool isSigned) const;
/// contains - Return true if the specified value is in the set.
/// The isSigned parameter indicates whether the comparisons should be
/// performed as if the values are signed or not.
///
bool contains(ConstantInt *Val) const;
bool contains(ConstantInt *Val, bool isSigned) const;
/// getSingleElement - If this set contains a single element, return it,
/// otherwise return null.
@ -117,7 +127,7 @@ class ConstantRange {
/// one of the sets but not the other. For example: [100, 8) intersect [3,
/// 120) yields [3, 120)
///
ConstantRange intersectWith(const ConstantRange &CR) const;
ConstantRange intersectWith(const ConstantRange &CR, bool isSigned) const;
/// union - Return the range that results from the union of this range with
/// another range. The resultant range is guaranteed to include the elements
@ -125,7 +135,7 @@ class ConstantRange {
/// [3, 15), which includes 9, 10, and 11, which were not included in either
/// set before.
///
ConstantRange unionWith(const ConstantRange &CR) const;
ConstantRange unionWith(const ConstantRange &CR, bool isSigned) const;
/// zeroExtend - Return a new range in the specified integer type, which must
/// be strictly larger than the current type. The returned range will

View File

@ -167,7 +167,6 @@ public:
RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitSetCondInst(SetCondInst &I) { DELEGATE(BinaryOperator);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}

View File

@ -247,13 +247,6 @@ struct BinaryOpClass_match {
}
};
template<typename LHS, typename RHS>
inline BinaryOpClass_match<LHS, RHS, SetCondInst, Instruction::BinaryOps>
m_SetCond(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
return BinaryOpClass_match<LHS, RHS,
SetCondInst, Instruction::BinaryOps>(Op, L, R);
}
template<typename LHS, typename RHS>
inline BinaryOpClass_match<LHS, RHS, ShiftInst, Instruction::OtherOps>
m_Shift(Instruction::OtherOps &Op, const LHS &L, const RHS &R) {
@ -269,6 +262,45 @@ m_Shift(const LHS &L, const RHS &R) {
ShiftInst, Instruction::OtherOps>(Op, L, R);
}
//===----------------------------------------------------------------------===//
// Matchers for CmpInst classes
//
template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
struct CmpClass_match {
PredicateTy &Predicate;
LHS_t L;
RHS_t R;
CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
const RHS_t &RHS)
: Predicate(Pred), L(LHS), R(RHS) {}
template<typename OpTy>
bool match(OpTy *V) {
if (Class *I = dyn_cast<Class>(V))
if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
Predicate = I->getPredicate();
return true;
}
return false;
}
};
template<typename LHS, typename RHS>
inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
return CmpClass_match<LHS, RHS,
ICmpInst, ICmpInst::Predicate>(Pred, L, R);
}
template<typename LHS, typename RHS>
inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
return CmpClass_match<LHS, RHS,
FCmpInst, FCmpInst::Predicate>(Pred, L, R);
}
//===----------------------------------------------------------------------===//
// Matchers for unary operators
//

View File

@ -49,13 +49,15 @@ bool ConstantFoldTerminator(BasicBlock *BB);
Constant *ConstantFoldInstruction(Instruction *I);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified opcode and operands. If successful, the constant result is
/// returned, if not, null is returned. Note that this function can fail when
/// attempting to fold instructions like loads and stores, which have no
/// constant expression form.
/// specified operands. If successful, the constant result is returned, if not,
/// null is returned. Note that this function can fail when attempting to
/// fold instructions like loads and stores, which have no constant expression
/// form.
///
Constant *ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
const std::vector<Constant*> &Ops);
Constant *ConstantFoldInstOperands(
const Instruction *I, ///< The model instruction
const std::vector<Constant*> &Ops ///< The constant operands to use.
);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a

View File

@ -590,7 +590,8 @@ BasicAliasAnalysis::CheckGEPInstructions(
// Make sure they are comparable (ie, not constant expressions), and
// make sure the GEP with the smaller leading constant is GEP1.
if (G1OC) {
Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC);
Constant *Compare = ConstantExpr::getICmp(ICmpInst::ICMP_SGT,
G1OC, G2OC);
if (ConstantBool *CV = dyn_cast<ConstantBool>(Compare)) {
if (CV->getValue()) // If they are comparable and G2 > G1
std::swap(GEP1Ops, GEP2Ops); // Make GEP1 < GEP2

View File

@ -24,56 +24,43 @@
#include "llvm/Support/ConstantRange.h"
#include "llvm/Constants.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Support/Streams.h"
#include <ostream>
using namespace llvm;
static ConstantIntegral *getMaxValue(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::BoolTyID: return ConstantBool::getTrue();
case Type::SByteTyID:
case Type::ShortTyID:
case Type::IntTyID:
case Type::LongTyID: {
// Calculate 011111111111111...
unsigned TypeBits = Ty->getPrimitiveSize()*8;
int64_t Val = INT64_MAX; // All ones
Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
return ConstantInt::get(Ty, Val);
}
case Type::UByteTyID:
case Type::UShortTyID:
case Type::UIntTyID:
case Type::ULongTyID: return ConstantInt::getAllOnesValue(Ty);
default: return 0;
static ConstantIntegral *getMaxValue(const Type *Ty, bool isSigned = false) {
if (Ty == Type::BoolTy)
return ConstantBool::getTrue();
if (Ty->isInteger()) {
if (isSigned) {
// Calculate 011111111111111...
unsigned TypeBits = Ty->getPrimitiveSize()*8;
int64_t Val = INT64_MAX; // All ones
Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
return ConstantInt::get(Ty, Val);
}
return ConstantInt::getAllOnesValue(Ty);
}
return 0;
}
// Static constructor to create the minimum constant for an integral type...
static ConstantIntegral *getMinValue(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::BoolTyID: return ConstantBool::getFalse();
case Type::SByteTyID:
case Type::ShortTyID:
case Type::IntTyID:
case Type::LongTyID: {
// Calculate 1111111111000000000000
unsigned TypeBits = Ty->getPrimitiveSize()*8;
int64_t Val = -1; // All ones
Val <<= TypeBits-1; // Shift over to the right spot
return ConstantInt::get(Ty, Val);
}
case Type::UByteTyID:
case Type::UShortTyID:
case Type::UIntTyID:
case Type::ULongTyID: return ConstantInt::get(Ty, 0);
default: return 0;
static ConstantIntegral *getMinValue(const Type *Ty, bool isSigned = false) {
if (Ty == Type::BoolTy)
return ConstantBool::getFalse();
if (Ty->isInteger()) {
if (isSigned) {
// Calculate 1111111111000000000000
unsigned TypeBits = Ty->getPrimitiveSize()*8;
int64_t Val = -1; // All ones
Val <<= TypeBits-1; // Shift over to the right spot
return ConstantInt::get(Ty, Val);
}
return ConstantInt::get(Ty, 0);
}
return 0;
}
static ConstantIntegral *Next(ConstantIntegral *CI) {
if (ConstantBool *CB = dyn_cast<ConstantBool>(CI))
@ -84,25 +71,30 @@ static ConstantIntegral *Next(ConstantIntegral *CI) {
return cast<ConstantIntegral>(Result);
}
static bool LT(ConstantIntegral *A, ConstantIntegral *B) {
Constant *C = ConstantExpr::getSetLT(A, B);
static bool LT(ConstantIntegral *A, ConstantIntegral *B, bool isSigned) {
Constant *C = ConstantExpr::getICmp(
(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT), A, B);
assert(isa<ConstantBool>(C) && "Constant folding of integrals not impl??");
return cast<ConstantBool>(C)->getValue();
}
static bool LTE(ConstantIntegral *A, ConstantIntegral *B) {
Constant *C = ConstantExpr::getSetLE(A, B);
static bool LTE(ConstantIntegral *A, ConstantIntegral *B, bool isSigned) {
Constant *C = ConstantExpr::getICmp(
(isSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE), A, B);
assert(isa<ConstantBool>(C) && "Constant folding of integrals not impl??");
return cast<ConstantBool>(C)->getValue();
}
static bool GT(ConstantIntegral *A, ConstantIntegral *B) { return LT(B, A); }
static bool GT(ConstantIntegral *A, ConstantIntegral *B, bool isSigned) {
return LT(B, A, isSigned); }
static ConstantIntegral *Min(ConstantIntegral *A, ConstantIntegral *B) {
return LT(A, B) ? A : B;
static ConstantIntegral *Min(ConstantIntegral *A, ConstantIntegral *B,
bool isSigned) {
return LT(A, B, isSigned) ? A : B;
}
static ConstantIntegral *Max(ConstantIntegral *A, ConstantIntegral *B) {
return GT(A, B) ? A : B;
static ConstantIntegral *Max(ConstantIntegral *A, ConstantIntegral *B,
bool isSigned) {
return GT(A, B, isSigned) ? A : B;
}
/// Initialize a full (the default) or empty set for the specified type.
@ -118,47 +110,62 @@ ConstantRange::ConstantRange(const Type *Ty, bool Full) {
/// Initialize a range to hold the single specified value.
///
ConstantRange::ConstantRange(Constant *V)
: Lower(cast<ConstantIntegral>(V)), Upper(Next(cast<ConstantIntegral>(V))) {
}
ConstantRange::ConstantRange(Constant *V)
: Lower(cast<ConstantIntegral>(V)), Upper(Next(cast<ConstantIntegral>(V))) { }
/// Initialize a range of values explicitly... this will assert out if
/// Lower==Upper and Lower != Min or Max for its type (or if the two constants
/// have different types)
///
ConstantRange::ConstantRange(Constant *L, Constant *U)
ConstantRange::ConstantRange(Constant *L, Constant *U)
: Lower(cast<ConstantIntegral>(L)), Upper(cast<ConstantIntegral>(U)) {
assert(Lower->getType() == Upper->getType() &&
"Incompatible types for ConstantRange!");
// Make sure that if L & U are equal that they are either Min or Max...
assert((L != U || (L == getMaxValue(L->getType()) ||
L == getMinValue(L->getType()))) &&
"Lower == Upper, but they aren't min or max for type!");
L == getMinValue(L->getType())))
&& "Lower == Upper, but they aren't min or max for type!");
}
/// Initialize a set of values that all satisfy the condition with C.
///
ConstantRange::ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C) {
switch (SetCCOpcode) {
default: assert(0 && "Invalid SetCC opcode to ConstantRange ctor!");
case Instruction::SetEQ: Lower = C; Upper = Next(C); return;
case Instruction::SetNE: Upper = C; Lower = Next(C); return;
case Instruction::SetLT:
ConstantRange::ConstantRange(unsigned short ICmpOpcode, ConstantIntegral *C) {
switch (ICmpOpcode) {
default: assert(0 && "Invalid ICmp opcode to ConstantRange ctor!");
case ICmpInst::ICMP_EQ: Lower = C; Upper = Next(C); return;
case ICmpInst::ICMP_NE: Upper = C; Lower = Next(C); return;
case ICmpInst::ICMP_ULT:
Lower = getMinValue(C->getType());
Upper = C;
return;
case Instruction::SetGT:
Lower = Next(C);
Upper = getMinValue(C->getType()); // Min = Next(Max)
case ICmpInst::ICMP_SLT:
Lower = getMinValue(C->getType(), true);
Upper = C;
return;
case Instruction::SetLE:
case ICmpInst::ICMP_UGT:
Lower = Next(C);
Upper = getMinValue(C->getType()); // Min = Next(Max)
return;
case ICmpInst::ICMP_SGT:
Lower = Next(C);
Upper = getMinValue(C->getType(), true); // Min = Next(Max)
return;
case ICmpInst::ICMP_ULE:
Lower = getMinValue(C->getType());
Upper = Next(C);
return;
case Instruction::SetGE:
case ICmpInst::ICMP_SLE:
Lower = getMinValue(C->getType(), true);
Upper = Next(C);
return;
case ICmpInst::ICMP_UGE:
Lower = C;
Upper = getMinValue(C->getType()); // Min = Next(Max)
Upper = getMinValue(C->getType()); // Min = Next(Max)
return;
case ICmpInst::ICMP_SGE:
Lower = C;
Upper = getMinValue(C->getType(), true); // Min = Next(Max)
return;
}
}
@ -182,11 +189,10 @@ bool ConstantRange::isEmptySet() const {
/// isWrappedSet - Return true if this set wraps around the top of the range,
/// for example: [100, 8)
///
bool ConstantRange::isWrappedSet() const {
return GT(Lower, Upper);
bool ConstantRange::isWrappedSet(bool isSigned) const {
return GT(Lower, Upper, isSigned);
}
/// getSingleElement - If this set contains a single element, return it,
/// otherwise return null.
ConstantIntegral *ConstantRange::getSingleElement() const {
@ -212,19 +218,17 @@ uint64_t ConstantRange::getSetSize() const {
/// contains - Return true if the specified value is in the set.
///
bool ConstantRange::contains(ConstantInt *Val) const {
bool ConstantRange::contains(ConstantInt *Val, bool isSigned) const {
if (Lower == Upper) {
if (isFullSet()) return true;
return false;
}
if (!isWrappedSet())
return LTE(Lower, Val) && LT(Val, Upper);
return LTE(Lower, Val) || LT(Val, Upper);
if (!isWrappedSet(isSigned))
return LTE(Lower, Val, isSigned) && LT(Val, Upper, isSigned);
return LTE(Lower, Val, isSigned) || LT(Val, Upper, isSigned);
}
/// subtract - Subtract the specified constant from the endpoints of this
/// constant range.
ConstantRange ConstantRange::subtract(ConstantInt *CI) const {
@ -241,15 +245,16 @@ ConstantRange ConstantRange::subtract(ConstantInt *CI) const {
// it is known that LHS is wrapped and RHS isn't.
//
static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
const ConstantRange &RHS) {
assert(LHS.isWrappedSet() && !RHS.isWrappedSet());
const ConstantRange &RHS,
bool isSigned) {
assert(LHS.isWrappedSet(isSigned) && !RHS.isWrappedSet(isSigned));
// Check to see if we overlap on the Left side of RHS...
//
if (LT(RHS.getLower(), LHS.getUpper())) {
if (LT(RHS.getLower(), LHS.getUpper(), isSigned)) {
// We do overlap on the left side of RHS, see if we overlap on the right of
// RHS...
if (GT(RHS.getUpper(), LHS.getLower())) {
if (GT(RHS.getUpper(), LHS.getLower(), isSigned)) {
// Ok, the result overlaps on both the left and right sides. See if the
// resultant interval will be smaller if we wrap or not...
//
@ -262,11 +267,10 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
// No overlap on the right, just on the left.
return ConstantRange(RHS.getLower(), LHS.getUpper());
}
} else {
// We don't overlap on the left side of RHS, see if we overlap on the right
// of RHS...
if (GT(RHS.getUpper(), LHS.getLower())) {
if (GT(RHS.getUpper(), LHS.getLower(), isSigned)) {
// Simple overlap...
return ConstantRange(LHS.getLower(), RHS.getUpper());
} else {
@ -279,30 +283,31 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
/// intersect - Return the range that results from the intersection of this
/// range with another range.
///
ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
bool isSigned) const {
assert(getType() == CR.getType() && "ConstantRange types don't agree!");
// Handle common special cases
if (isEmptySet() || CR.isFullSet()) return *this;
if (isFullSet() || CR.isEmptySet()) return CR;
if (!isWrappedSet()) {
if (!CR.isWrappedSet()) {
ConstantIntegral *L = Max(Lower, CR.Lower);
ConstantIntegral *U = Min(Upper, CR.Upper);
if (!isWrappedSet(isSigned)) {
if (!CR.isWrappedSet(isSigned)) {
ConstantIntegral *L = Max(Lower, CR.Lower, isSigned);
ConstantIntegral *U = Min(Upper, CR.Upper, isSigned);
if (LT(L, U)) // If range isn't empty...
if (LT(L, U, isSigned)) // If range isn't empty...
return ConstantRange(L, U);
else
return ConstantRange(getType(), false); // Otherwise, return empty set
} else
return intersect1Wrapped(CR, *this);
return intersect1Wrapped(CR, *this, isSigned);
} else { // We know "this" is wrapped...
if (!CR.isWrappedSet())
return intersect1Wrapped(*this, CR);
if (!CR.isWrappedSet(isSigned))
return intersect1Wrapped(*this, CR, isSigned);
else {
// Both ranges are wrapped...
ConstantIntegral *L = Max(Lower, CR.Lower);
ConstantIntegral *U = Min(Upper, CR.Upper);
ConstantIntegral *L = Max(Lower, CR.Lower, isSigned);
ConstantIntegral *U = Min(Upper, CR.Upper, isSigned);
return ConstantRange(L, U);
}
}
@ -315,7 +320,8 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
/// 15), which includes 9, 10, and 11, which were not included in either set
/// before.
///
ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
bool isSigned) const {
assert(getType() == CR.getType() && "ConstantRange types don't agree!");
assert(0 && "Range union not implemented yet!");
@ -325,7 +331,7 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
/// zeroExtend - Return a new range in the specified integer type, which must
/// be strictly larger than the current type. The returned range will
/// correspond to the possible range of values if the source range had been
/// correspond to the possible range of values as if the source range had been
/// zero extended.
ConstantRange ConstantRange::zeroExtend(const Type *Ty) const {
assert(getLower()->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() &&
@ -346,7 +352,7 @@ ConstantRange ConstantRange::zeroExtend(const Type *Ty) const {
/// truncate - Return a new range in the specified integer type, which must be
/// strictly smaller than the current type. The returned range will
/// correspond to the possible range of values if the source range had been
/// correspond to the possible range of values as if the source range had been
/// truncated to the specified type.
ConstantRange ConstantRange::truncate(const Type *Ty) const {
assert(getLower()->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() &&
@ -360,7 +366,6 @@ ConstantRange ConstantRange::truncate(const Type *Ty) const {
ConstantExpr::getTrunc(getUpper(), Ty));
}
/// print - Print out the bounds to a stream...
///
void ConstantRange::print(std::ostream &OS) const {

View File

@ -325,7 +325,8 @@ namespace {
void visitGetElementPtrInst(GetElementPtrInst &GEP);
void visitPHINode(PHINode &PN);
void visitCastInst(CastInst &CI);
void visitSetCondInst(SetCondInst &SCI) {} // NOOP!
void visitICmpInst(ICmpInst &ICI) {} // NOOP!
void visitFCmpInst(FCmpInst &ICI) {} // NOOP!
void visitSelectInst(SelectInst &SI);
void visitVAArg(VAArgInst &I);
void visitInstruction(Instruction &I);
@ -778,6 +779,8 @@ void Andersens::visitInstruction(Instruction &I) {
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::ICmp:
case Instruction::FCmp:
return;
default:
// Is this something we aren't handling yet?

View File

@ -251,8 +251,8 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
} else {
return true;
}
} else if (SetCondInst *SCI = dyn_cast<SetCondInst>(*UI)) {
if (!isa<ConstantPointerNull>(SCI->getOperand(1)))
} else if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
return true; // Allow comparison against null.
} else if (FreeInst *F = dyn_cast<FreeInst>(*UI)) {
Writers.push_back(F->getParent()->getParent());

View File

@ -536,7 +536,7 @@ Instruction *Loop::getCanonicalInductionVariableIncrement() const {
/// returns null.
///
Value *Loop::getTripCount() const {
// Canonical loops will end with a 'setne I, V', where I is the incremented
// Canonical loops will end with a 'cmp ne I, V', where I is the incremented
// canonical induction variable and V is the trip count of the loop.
Instruction *Inc = getCanonicalInductionVariableIncrement();
if (Inc == 0) return 0;
@ -546,15 +546,17 @@ Value *Loop::getTripCount() const {
IV->getIncomingBlock(contains(IV->getIncomingBlock(1)));
if (BranchInst *BI = dyn_cast<BranchInst>(BackedgeBlock->getTerminator()))
if (BI->isConditional())
if (SetCondInst *SCI = dyn_cast<SetCondInst>(BI->getCondition()))
if (SCI->getOperand(0) == Inc)
if (BI->isConditional()) {
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) {
if (ICI->getOperand(0) == Inc)
if (BI->getSuccessor(0) == getHeader()) {
if (SCI->getOpcode() == Instruction::SetNE)
return SCI->getOperand(1);
} else if (SCI->getOpcode() == Instruction::SetEQ) {
return SCI->getOperand(1);
if (ICI->getPredicate() == ICmpInst::ICMP_NE)
return ICI->getOperand(1);
} else if (ICI->getPredicate() == ICmpInst::ICMP_EQ) {
return ICI->getOperand(1);
}
}
}
return 0;
}

View File

@ -177,8 +177,7 @@ SCEVHandle SCEVConstant::get(ConstantInt *V) {
// are signless. There won't be a need to bitcast then.
if (V->getType()->isSigned()) {
const Type *NewTy = V->getType()->getUnsignedVersion();
V = cast<ConstantInt>(
ConstantExpr::getBitCast(V, NewTy));
V = cast<ConstantInt>(ConstantExpr::getBitCast(V, NewTy));
}
SCEVConstant *&R = (*SCEVConstants)[V];
@ -461,15 +460,8 @@ SCEVHandle SCEVUnknown::getIntegerSCEV(int Val, const Type *Ty) {
C = Constant::getNullValue(Ty);
else if (Ty->isFloatingPoint())
C = ConstantFP::get(Ty, Val);
/// FIXME:Signless. when integer types are signless, just change this to:
/// else
/// C = ConstantInt::get(Ty, Val);
else if (Ty->isSigned())
else
C = ConstantInt::get(Ty, Val);
else {
C = ConstantInt::get(Ty->getSignedVersion(), Val);
C = ConstantExpr::getBitCast(C, Ty);
}
return SCEVUnknown::get(C);
}
@ -514,8 +506,7 @@ static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps) {
for (; NumSteps; --NumSteps)
Result *= Val-(NumSteps-1);
Constant *Res = ConstantInt::get(Type::ULongTy, Result);
return SCEVUnknown::get(
ConstantExpr::getTruncOrBitCast(Res, V->getType()));
return SCEVUnknown::get(ConstantExpr::getTruncOrBitCast(Res, V->getType()));
}
const Type *Ty = V->getType();
@ -1162,7 +1153,7 @@ namespace {
SCEVHandle ComputeLoadConstantCompareIterationCount(LoadInst *LI,
Constant *RHS,
const Loop *L,
unsigned SetCCOpcode);
ICmpInst::Predicate p);
/// ComputeIterationCountExhaustively - If the trip is known to execute a
/// constant number of times (the condition evolves only from constants),
@ -1521,17 +1512,21 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
if (ExitBr == 0) return UnknownValue;
assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
SetCondInst *ExitCond = dyn_cast<SetCondInst>(ExitBr->getCondition());
if (ExitCond == 0) // Not a setcc
ICmpInst *ExitCond = dyn_cast<ICmpInst>(ExitBr->getCondition());
// If its not an integer comparison then compute it the hard way.
// Note that ICmpInst deals with pointer comparisons too so we must check
// the type of the operand.
if (ExitCond == 0 || !ExitCond->getOperand(0)->getType()->isIntegral())
return ComputeIterationCountExhaustively(L, ExitBr->getCondition(),
ExitBr->getSuccessor(0) == ExitBlock);
// If the condition was exit on true, convert the condition to exit on false.
Instruction::BinaryOps Cond;
// If the condition was exit on true, convert the condition to exit on false
ICmpInst::Predicate Cond;
if (ExitBr->getSuccessor(1) == ExitBlock)
Cond = ExitCond->getOpcode();
Cond = ExitCond->getPredicate();
else
Cond = ExitCond->getInverseCondition();
Cond = ExitCond->getInversePredicate();
// Handle common loops like: for (X = "string"; *X; ++X)
if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
@ -1550,12 +1545,12 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
Tmp = getSCEVAtScope(RHS, L);
if (!isa<SCEVCouldNotCompute>(Tmp)) RHS = Tmp;
// At this point, we would like to compute how many iterations of the loop the
// predicate will return true for these inputs.
// At this point, we would like to compute how many iterations of the
// loop the predicate will return true for these inputs.
if (isa<SCEVConstant>(LHS) && !isa<SCEVConstant>(RHS)) {
// If there is a constant, force it into the RHS.
std::swap(LHS, RHS);
Cond = SetCondInst::getSwappedCondition(Cond);
Cond = ICmpInst::getSwappedPredicate(Cond);
}
// FIXME: think about handling pointer comparisons! i.e.:
@ -1590,53 +1585,48 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
CompRange = ConstantRange(NewL, NewU);
}
SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange);
SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange,
ICmpInst::isSignedPredicate(Cond));
if (!isa<SCEVCouldNotCompute>(Ret)) return Ret;
}
}
switch (Cond) {
case Instruction::SetNE: // while (X != Y)
case ICmpInst::ICMP_NE: { // while (X != Y)
// Convert to: while (X-Y != 0)
if (LHS->getType()->isInteger()) {
SCEVHandle TC = HowFarToZero(SCEV::getMinusSCEV(LHS, RHS), L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
}
SCEVHandle TC = HowFarToZero(SCEV::getMinusSCEV(LHS, RHS), L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
case Instruction::SetEQ:
}
case ICmpInst::ICMP_EQ: {
// Convert to: while (X-Y == 0) // while (X == Y)
if (LHS->getType()->isInteger()) {
SCEVHandle TC = HowFarToNonZero(SCEV::getMinusSCEV(LHS, RHS), L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
}
SCEVHandle TC = HowFarToNonZero(SCEV::getMinusSCEV(LHS, RHS), L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
case Instruction::SetLT:
if (LHS->getType()->isInteger() &&
ExitCond->getOperand(0)->getType()->isSigned()) {
SCEVHandle TC = HowManyLessThans(LHS, RHS, L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
}
}
case ICmpInst::ICMP_SLT: {
SCEVHandle TC = HowManyLessThans(LHS, RHS, L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
case Instruction::SetGT:
if (LHS->getType()->isInteger() &&
ExitCond->getOperand(0)->getType()->isSigned()) {
SCEVHandle TC = HowManyLessThans(RHS, LHS, L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
}
}
case ICmpInst::ICMP_SGT: {
SCEVHandle TC = HowManyLessThans(RHS, LHS, L);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
}
default:
#if 0
cerr << "ComputeIterationCount ";
if (ExitCond->getOperand(0)->getType()->isUnsigned())
cerr << "[unsigned] ";
cerr << *LHS << " "
<< Instruction::getOpcodeName(Cond) << " " << *RHS << "\n";
<< Instruction::getOpcodeName(Instruction::ICmp)
<< " " << *RHS << "\n";
#endif
break;
}
return ComputeIterationCountExhaustively(L, ExitCond,
ExitBr->getSuccessor(0) == ExitBlock);
ExitBr->getSuccessor(0) == ExitBlock);
}
static ConstantInt *
@ -1686,7 +1676,8 @@ GetAddressedElementFromGlobal(GlobalVariable *GV,
/// 'setcc load X, cst', try to se if we can compute the trip count.
SCEVHandle ScalarEvolutionsImpl::
ComputeLoadConstantCompareIterationCount(LoadInst *LI, Constant *RHS,
const Loop *L, unsigned SetCCOpcode) {
const Loop *L,
ICmpInst::Predicate predicate) {
if (LI->isVolatile()) return UnknownValue;
// Check to see if the loaded pointer is a getelementptr of a global.
@ -1742,7 +1733,7 @@ ComputeLoadConstantCompareIterationCount(LoadInst *LI, Constant *RHS,
if (Result == 0) break; // Cannot compute!
// Evaluate the condition for this iteration.
Result = ConstantExpr::get(SetCCOpcode, Result, RHS);
Result = ConstantExpr::getICmp(predicate, Result, RHS);
if (!isa<ConstantBool>(Result)) break; // Couldn't decide for sure
if (cast<ConstantBool>(Result)->getValue() == false) {
#if 0
@ -1761,7 +1752,7 @@ ComputeLoadConstantCompareIterationCount(LoadInst *LI, Constant *RHS,
/// CanConstantFold - Return true if we can constant fold an instruction of the
/// specified type, assuming that all operands were constants.
static bool CanConstantFold(const Instruction *I) {
if (isa<BinaryOperator>(I) || isa<ShiftInst>(I) ||
if (isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CmpInst>(I) ||
isa<SelectInst>(I) || isa<CastInst>(I) || isa<GetElementPtrInst>(I))
return true;
@ -1790,11 +1781,18 @@ static Constant *ConstantFold(const Instruction *I,
return ConstantFoldCall(cast<Function>(GV), Operands);
}
return 0;
case Instruction::GetElementPtr:
case Instruction::GetElementPtr: {
Constant *Base = Operands[0];
Operands.erase(Operands.begin());
return ConstantExpr::getGetElementPtr(Base, Operands);
}
case Instruction::ICmp:
return ConstantExpr::getICmp(
cast<ICmpInst>(I)->getPredicate(), Operands[0], Operands[1]);
case Instruction::FCmp:
return ConstantExpr::getFCmp(
cast<FCmpInst>(I)->getPredicate(), Operands[0], Operands[1]);
}
return 0;
}
@ -2226,8 +2224,8 @@ SCEVHandle ScalarEvolutionsImpl::HowFarToZero(SCEV *V, const Loop *L) {
// Pick the smallest positive root value.
assert(R1->getType()->isUnsigned()&&"Didn't canonicalize to unsigned?");
if (ConstantBool *CB =
dyn_cast<ConstantBool>(ConstantExpr::getSetLT(R1->getValue(),
R2->getValue()))) {
dyn_cast<ConstantBool>(ConstantExpr::getICmp(ICmpInst::ICMP_ULT,
R1->getValue(), R2->getValue()))) {
if (CB->getValue() == false)
std::swap(R1, R2); // R1 is the minimum root now.
@ -2257,7 +2255,8 @@ SCEVHandle ScalarEvolutionsImpl::HowFarToNonZero(SCEV *V, const Loop *L) {
// already. If so, the backedge will execute zero times.
if (SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
Constant *Zero = Constant::getNullValue(C->getValue()->getType());
Constant *NonZero = ConstantExpr::getSetNE(C->getValue(), Zero);
Constant *NonZero =
ConstantExpr::getICmp(ICmpInst::ICMP_NE, C->getValue(), Zero);
if (NonZero == ConstantBool::getTrue())
return getSCEV(Zero);
return UnknownValue; // Otherwise it will loop infinitely.
@ -2318,40 +2317,46 @@ HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
// Now that we found a conditional branch that dominates the loop, check to
// see if it is the comparison we are looking for.
SetCondInst *SCI =dyn_cast<SetCondInst>(LoopEntryPredicate->getCondition());
if (!SCI) return UnknownValue;
Value *PreCondLHS = SCI->getOperand(0);
Value *PreCondRHS = SCI->getOperand(1);
Instruction::BinaryOps Cond;
if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest)
Cond = SCI->getOpcode();
else
Cond = SCI->getInverseCondition();
if (ICmpInst *ICI = dyn_cast<ICmpInst>(LoopEntryPredicate->getCondition())){
Value *PreCondLHS = ICI->getOperand(0);
Value *PreCondRHS = ICI->getOperand(1);
ICmpInst::Predicate Cond;
if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest)
Cond = ICI->getPredicate();
else
Cond = ICI->getInversePredicate();
switch (Cond) {
case Instruction::SetGT:
std::swap(PreCondLHS, PreCondRHS);
Cond = Instruction::SetLT;
// Fall Through.
case Instruction::SetLT:
if (PreCondLHS->getType()->isInteger() &&
PreCondLHS->getType()->isSigned()) {
if (RHS != getSCEV(PreCondRHS))
return UnknownValue; // Not a comparison against 'm'.
if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
!= getSCEV(PreCondLHS))
return UnknownValue; // Not a comparison against 'n-1'.
switch (Cond) {
case ICmpInst::ICMP_UGT:
std::swap(PreCondLHS, PreCondRHS);
Cond = ICmpInst::ICMP_ULT;
break;
} else {
return UnknownValue;
case ICmpInst::ICMP_SGT:
std::swap(PreCondLHS, PreCondRHS);
Cond = ICmpInst::ICMP_SLT;
break;
default: break;
}
default: break;
}
//cerr << "Computed Loop Trip Count as: "
// << *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n";
return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0));
if (Cond == ICmpInst::ICMP_SLT) {
if (PreCondLHS->getType()->isInteger()) {
if (RHS != getSCEV(PreCondRHS))
return UnknownValue; // Not a comparison against 'm'.
if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
!= getSCEV(PreCondLHS))
return UnknownValue; // Not a comparison against 'n-1'.
}
else return UnknownValue;
} else if (Cond == ICmpInst::ICMP_ULT)
return UnknownValue;
// cerr << "Computed Loop Trip Count as: "
// << // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n";
return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0));
}
else
return UnknownValue;
}
return UnknownValue;
@ -2362,7 +2367,8 @@ HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
/// this is that it returns the first iteration number where the value is not in
/// the condition, thus computing the exit count. If the iteration count can't
/// be computed, an instance of SCEVCouldNotCompute is returned.
SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range,
bool isSigned) const {
if (Range.isFullSet()) // Infinite loop.
return new SCEVCouldNotCompute();
@ -2374,7 +2380,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
SCEVHandle Shifted = SCEVAddRecExpr::get(Operands, getLoop());
if (SCEVAddRecExpr *ShiftedAddRec = dyn_cast<SCEVAddRecExpr>(Shifted))
return ShiftedAddRec->getNumIterationsInRange(
Range.subtract(SC->getValue()));
Range.subtract(SC->getValue()),isSigned);
// This is strange and shouldn't happen.
return new SCEVCouldNotCompute();
}
@ -2392,7 +2398,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
// First check to see if the range contains zero. If not, the first
// iteration exits.
ConstantInt *Zero = ConstantInt::get(getType(), 0);
if (!Range.contains(Zero)) return SCEVConstant::get(Zero);
if (!Range.contains(Zero, isSigned)) return SCEVConstant::get(Zero);
if (isAffine()) {
// If this is an affine expression then we have this situation:
@ -2418,12 +2424,12 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
// range, then we computed our trip count, otherwise wrap around or other
// things must have happened.
ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue);
if (Range.contains(Val))
if (Range.contains(Val, isSigned))
return new SCEVCouldNotCompute(); // Something strange happened
// Ensure that the previous value is in the range. This is a sanity check.
assert(Range.contains(EvaluateConstantChrecAtConstant(this,
ConstantExpr::getSub(ExitValue, One))) &&
ConstantExpr::getSub(ExitValue, One)), isSigned) &&
"Linear scev computation is off in a bad way!");
return SCEVConstant::get(cast<ConstantInt>(ExitValue));
} else if (isQuadratic()) {
@ -2444,8 +2450,8 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
// Pick the smallest positive root value.
assert(R1->getType()->isUnsigned() && "Didn't canonicalize to unsigned?");
if (ConstantBool *CB =
dyn_cast<ConstantBool>(ConstantExpr::getSetLT(R1->getValue(),
R2->getValue()))) {
dyn_cast<ConstantBool>(ConstantExpr::getICmp(ICmpInst::ICMP_ULT,
R1->getValue(), R2->getValue()))) {
if (CB->getValue() == false)
std::swap(R1, R2); // R1 is the minimum root now.
@ -2454,14 +2460,14 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
// for "X*X < 5", for example, we should not return a root of 2.
ConstantInt *R1Val = EvaluateConstantChrecAtConstant(this,
R1->getValue());
if (Range.contains(R1Val)) {
if (Range.contains(R1Val, isSigned)) {
// The next iteration must be out of the range...
Constant *NextVal =
ConstantExpr::getAdd(R1->getValue(),
ConstantInt::get(R1->getType(), 1));
R1Val = EvaluateConstantChrecAtConstant(this, NextVal);
if (!Range.contains(R1Val))
if (!Range.contains(R1Val, isSigned))
return SCEVUnknown::get(NextVal);
return new SCEVCouldNotCompute(); // Something strange happened
}
@ -2472,7 +2478,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
ConstantExpr::getSub(R1->getValue(),
ConstantInt::get(R1->getType(), 1));
R1Val = EvaluateConstantChrecAtConstant(this, NextVal);
if (Range.contains(R1Val))
if (Range.contains(R1Val, isSigned))
return R1;
return new SCEVCouldNotCompute(); // Something strange happened
}
@ -2494,7 +2500,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
return new SCEVCouldNotCompute();
// Check to see if we found the value!
if (!Range.contains(cast<SCEVConstant>(Val)->getValue()))
if (!Range.contains(cast<SCEVConstant>(Val)->getValue(), isSigned))
return SCEVConstant::get(TestVal);
// Increment to test the next index.

View File

@ -161,6 +161,11 @@ static inline bool isIdenticalBinaryInst(const Instruction &I1,
I1.getParent()->getParent() != I2->getParent()->getParent())
return false;
// If they are CmpInst instructions, check their predicates
if (CmpInst *CI1 = dyn_cast<CmpInst>(&const_cast<Instruction&>(I1)))
if (CI1->getPredicate() != cast<CmpInst>(I2)->getPredicate())
return false;
// They are identical if both operands are the same!
if (I1.getOperand(0) == I2->getOperand(0) &&
I1.getOperand(1) == I2->getOperand(1))

File diff suppressed because it is too large Load Diff

View File

@ -260,12 +260,6 @@ frem { RET_TOK(BinaryOpVal, FRem, FREM); }
and { RET_TOK(BinaryOpVal, And, AND); }
or { RET_TOK(BinaryOpVal, Or , OR ); }
xor { RET_TOK(BinaryOpVal, Xor, XOR); }
setne { RET_TOK(BinaryOpVal, SetNE, SETNE); }
seteq { RET_TOK(BinaryOpVal, SetEQ, SETEQ); }
setlt { RET_TOK(BinaryOpVal, SetLT, SETLT); }
setgt { RET_TOK(BinaryOpVal, SetGT, SETGT); }
setle { RET_TOK(BinaryOpVal, SetLE, SETLE); }
setge { RET_TOK(BinaryOpVal, SetGE, SETGE); }
icmp { RET_TOK(OtherOpVal, ICmp, ICMP); }
fcmp { RET_TOK(OtherOpVal, FCmp, FCMP); }
eq { return EQ; }

View File

@ -260,12 +260,6 @@ frem { RET_TOK(BinaryOpVal, FRem, FREM); }
and { RET_TOK(BinaryOpVal, And, AND); }
or { RET_TOK(BinaryOpVal, Or , OR ); }
xor { RET_TOK(BinaryOpVal, Xor, XOR); }
setne { RET_TOK(BinaryOpVal, SetNE, SETNE); }
seteq { RET_TOK(BinaryOpVal, SetEQ, SETEQ); }
setlt { RET_TOK(BinaryOpVal, SetLT, SETLT); }
setgt { RET_TOK(BinaryOpVal, SetGT, SETGT); }
setle { RET_TOK(BinaryOpVal, SetLE, SETLE); }
setge { RET_TOK(BinaryOpVal, SetGE, SETGE); }
icmp { RET_TOK(OtherOpVal, ICmp, ICMP); }
fcmp { RET_TOK(OtherOpVal, FCmp, FCMP); }
eq { return EQ; }

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* A Bison parser, made by GNU Bison 1.875c. */
/* A Bison parser, made by GNU Bison 2.1. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -15,8 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
@ -116,63 +116,58 @@
AND = 342,
OR = 343,
XOR = 344,
SETLE = 345,
SETGE = 346,
SETLT = 347,
SETGT = 348,
SETEQ = 349,
SETNE = 350,
ICMP = 351,
FCMP = 352,
EQ = 353,
NE = 354,
SLT = 355,
SGT = 356,
SLE = 357,
SGE = 358,
ULT = 359,
UGT = 360,
ULE = 361,
UGE = 362,
OEQ = 363,
ONE = 364,
OLT = 365,
OGT = 366,
OLE = 367,
OGE = 368,
ORD = 369,
UNO = 370,
UEQ = 371,
UNE = 372,
MALLOC = 373,
ALLOCA = 374,
FREE = 375,
LOAD = 376,
STORE = 377,
GETELEMENTPTR = 378,
TRUNC = 379,
ZEXT = 380,
SEXT = 381,
FPTRUNC = 382,
FPEXT = 383,
BITCAST = 384,
UITOFP = 385,
SITOFP = 386,
FPTOUI = 387,
FPTOSI = 388,
INTTOPTR = 389,
PTRTOINT = 390,
PHI_TOK = 391,
SELECT = 392,
SHL = 393,
LSHR = 394,
ASHR = 395,
VAARG = 396,
EXTRACTELEMENT = 397,
INSERTELEMENT = 398,
SHUFFLEVECTOR = 399
ICMP = 345,
FCMP = 346,
EQ = 347,
NE = 348,
SLT = 349,
SGT = 350,
SLE = 351,
SGE = 352,
ULT = 353,
UGT = 354,
ULE = 355,
UGE = 356,
OEQ = 357,
ONE = 358,
OLT = 359,
OGT = 360,
OLE = 361,
OGE = 362,
ORD = 363,
UNO = 364,
UEQ = 365,
UNE = 366,
MALLOC = 367,
ALLOCA = 368,
FREE = 369,
LOAD = 370,
STORE = 371,
GETELEMENTPTR = 372,
TRUNC = 373,
ZEXT = 374,
SEXT = 375,
FPTRUNC = 376,
FPEXT = 377,
BITCAST = 378,
UITOFP = 379,
SITOFP = 380,
FPTOUI = 381,
FPTOSI = 382,
INTTOPTR = 383,
PTRTOINT = 384,
PHI_TOK = 385,
SELECT = 386,
SHL = 387,
LSHR = 388,
ASHR = 389,
VAARG = 390,
EXTRACTELEMENT = 391,
INSERTELEMENT = 392,
SHUFFLEVECTOR = 393
};
#endif
/* Tokens. */
#define ESINT64VAL 258
#define EUINT64VAL 259
#define SINTVAL 260
@ -260,67 +255,61 @@
#define AND 342
#define OR 343
#define XOR 344
#define SETLE 345
#define SETGE 346
#define SETLT 347
#define SETGT 348
#define SETEQ 349
#define SETNE 350
#define ICMP 351
#define FCMP 352
#define EQ 353
#define NE 354
#define SLT 355
#define SGT 356
#define SLE 357
#define SGE 358
#define ULT 359
#define UGT 360
#define ULE 361
#define UGE 362
#define OEQ 363
#define ONE 364
#define OLT 365
#define OGT 366
#define OLE 367
#define OGE 368
#define ORD 369
#define UNO 370
#define UEQ 371
#define UNE 372
#define MALLOC 373
#define ALLOCA 374
#define FREE 375
#define LOAD 376
#define STORE 377
#define GETELEMENTPTR 378
#define TRUNC 379
#define ZEXT 380
#define SEXT 381
#define FPTRUNC 382
#define FPEXT 383
#define BITCAST 384
#define UITOFP 385
#define SITOFP 386
#define FPTOUI 387
#define FPTOSI 388
#define INTTOPTR 389
#define PTRTOINT 390
#define PHI_TOK 391
#define SELECT 392
#define SHL 393
#define LSHR 394
#define ASHR 395
#define VAARG 396
#define EXTRACTELEMENT 397
#define INSERTELEMENT 398
#define SHUFFLEVECTOR 399
#define ICMP 345
#define FCMP 346
#define EQ 347
#define NE 348
#define SLT 349
#define SGT 350
#define SLE 351
#define SGE 352
#define ULT 353
#define UGT 354
#define ULE 355
#define UGE 356
#define OEQ 357
#define ONE 358
#define OLT 359
#define OGT 360
#define OLE 361
#define OGE 362
#define ORD 363
#define UNO 364
#define UEQ 365
#define UNE 366
#define MALLOC 367
#define ALLOCA 368
#define FREE 369
#define LOAD 370
#define STORE 371
#define GETELEMENTPTR 372
#define TRUNC 373
#define ZEXT 374
#define SEXT 375
#define FPTRUNC 376
#define FPEXT 377
#define BITCAST 378
#define UITOFP 379
#define SITOFP 380
#define FPTOUI 381
#define FPTOSI 382
#define INTTOPTR 383
#define PTRTOINT 384
#define PHI_TOK 385
#define SELECT 386
#define SHL 387
#define LSHR 388
#define ASHR 389
#define VAARG 390
#define EXTRACTELEMENT 391
#define INSERTELEMENT 392
#define SHUFFLEVECTOR 393
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 855 "/home/vadve/alenhar2/llvm.old/lib/AsmParser/llvmAsmParser.y"
#line 855 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y"
typedef union YYSTYPE {
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
@ -363,8 +352,8 @@ typedef union YYSTYPE {
llvm::ICmpInst::Predicate IPredicate;
llvm::FCmpInst::Predicate FPredicate;
} YYSTYPE;
/* Line 1275 of yacc.c. */
#line 368 "llvmAsmParser.tab.h"
/* Line 1447 of yacc.c. */
#line 357 "llvmAsmParser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1

View File

@ -958,9 +958,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
// Binary Operators
%type <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories
%type <BinaryOpVal> ArithmeticOps LogicalOps // Binops Subcatagories
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
%token <OtherOpVal> ICMP FCMP
%type <IPredicate> IPredicates
%type <FPredicate> FPredicates
@ -999,7 +998,6 @@ INTVAL : UINTVAL {
//
ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
LogicalOps : AND | OR | XOR;
SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST |
UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT;
ShiftOps : SHL | LSHR | ASHR;
@ -1574,12 +1572,6 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
$$ = ConstantExpr::get($1, $3, $5);
CHECK_FOR_ERROR
}
| SetCondOps '(' ConstVal ',' ConstVal ')' {
if ($3->getType() != $5->getType())
GEN_ERROR("setcc operand types must match!");
$$ = ConstantExpr::get($1, $3, $5);
CHECK_FOR_ERROR
}
| ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("icmp operand types must match!");
@ -2369,20 +2361,6 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("binary operator returned null!");
delete $2;
}
| SetCondOps Types ValueRef ',' ValueRef {
if(isa<PackedType>((*$2).get())) {
GEN_ERROR(
"PackedTypes currently not supported in setcc instructions!");
}
Value* tmpVal1 = getVal(*$2, $3);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$2, $5);
CHECK_FOR_ERROR
$$ = new SetCondInst($1, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("binary operator returned null!");
delete $2;
}
| ICMP IPredicates Types ValueRef ',' ValueRef {
if (isa<PackedType>((*$3).get()))
GEN_ERROR("Packed types not supported by icmp instruction");

View File

@ -926,7 +926,6 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
// EUINT64VAL - A positive number within uns. long long range
%token <UInt64Val> EUINT64VAL
%type <SInt64Val> EINT64VAL
%token <SIntVal> SINTVAL // Signed 32 bit ints...
%token <UIntVal> UINTVAL // Unsigned 32 bit ints...
@ -959,9 +958,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
// Binary Operators
%type <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories
%type <BinaryOpVal> ArithmeticOps LogicalOps // Binops Subcatagories
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
%token <OtherOpVal> ICMP FCMP
%type <IPredicate> IPredicates
%type <FPredicate> FPredicates
@ -995,21 +993,11 @@ INTVAL : UINTVAL {
CHECK_FOR_ERROR
};
EINT64VAL : ESINT64VAL; // These have same type and can't cause problems...
EINT64VAL : EUINT64VAL {
if ($1 > (uint64_t)INT64_MAX) // Outside of my range!
GEN_ERROR("Value too large for type!");
$$ = (int64_t)$1;
CHECK_FOR_ERROR
};
// Operations that are notably excluded from this list include:
// RET, BR, & SWITCH because they end basic blocks and are treated specially.
//
ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
LogicalOps : AND | OR | XOR;
SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST |
UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT;
ShiftOps : SHL | LSHR | ASHR;
@ -1486,7 +1474,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
delete $1;
CHECK_FOR_ERROR
}
| SIntType EINT64VAL { // integral constants
| SIntType ESINT64VAL { // integral constants
if (!ConstantInt::isValueValidForType($1, $2))
GEN_ERROR("Constant value doesn't fit in type!");
$$ = ConstantInt::get($1, $2);
CHECK_FOR_ERROR
}
| SIntType EUINT64VAL { // integral constants
if (!ConstantInt::isValueValidForType($1, $2))
GEN_ERROR("Constant value doesn't fit in type!");
$$ = ConstantInt::get($1, $2);
@ -1498,6 +1492,12 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
$$ = ConstantInt::get($1, $2);
CHECK_FOR_ERROR
}
| UIntType ESINT64VAL {
if (!ConstantInt::isValueValidForType($1, $2))
GEN_ERROR("Constant value doesn't fit in type!");
$$ = ConstantInt::get($1, $2);
CHECK_FOR_ERROR
}
| BOOL TRUETOK { // Boolean constants
$$ = ConstantBool::getTrue();
CHECK_FOR_ERROR
@ -1572,12 +1572,6 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
$$ = ConstantExpr::get($1, $3, $5);
CHECK_FOR_ERROR
}
| SetCondOps '(' ConstVal ',' ConstVal ')' {
if ($3->getType() != $5->getType())
GEN_ERROR("setcc operand types must match!");
$$ = ConstantExpr::get($1, $3, $5);
CHECK_FOR_ERROR
}
| ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("icmp operand types must match!");
@ -2367,20 +2361,6 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("binary operator returned null!");
delete $2;
}
| SetCondOps Types ValueRef ',' ValueRef {
if(isa<PackedType>((*$2).get())) {
GEN_ERROR(
"PackedTypes currently not supported in setcc instructions!");
}
Value* tmpVal1 = getVal(*$2, $3);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$2, $5);
CHECK_FOR_ERROR
$$ = new SetCondInst($1, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("binary operator returned null!");
delete $2;
}
| ICMP IPredicates Types ValueRef ',' ValueRef {
if (isa<PackedType>((*$3).get()))
GEN_ERROR("Packed types not supported by icmp instruction");

View File

@ -432,8 +432,8 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Value *L = CI->getOperand(1);
Value *R = CI->getOperand(2);
Value *LIsNan = new SetCondInst(Instruction::SetNE, L, L, "LIsNan", CI);
Value *RIsNan = new SetCondInst(Instruction::SetNE, R, R, "RIsNan", CI);
Value *LIsNan = new FCmpInst(FCmpInst::FCMP_ONE, L, L, "LIsNan", CI);
Value *RIsNan = new FCmpInst(FCmpInst::FCMP_ONE, R, R, "RIsNan", CI);
CI->replaceAllUsesWith(
BinaryOperator::create(Instruction::Or, LIsNan, RIsNan,
"isunordered", CI));

View File

@ -541,20 +541,6 @@ public:
void visitAShr(User &I) { visitShift(I, ISD::SRA); }
void visitICmp(User &I);
void visitFCmp(User &I);
void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc,
ISD::CondCode FPOpc);
void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ,
ISD::SETOEQ); }
void visitSetNE(User &I) { visitSetCC(I, ISD::SETNE, ISD::SETNE,
ISD::SETUNE); }
void visitSetLE(User &I) { visitSetCC(I, ISD::SETLE, ISD::SETULE,
ISD::SETOLE); }
void visitSetGE(User &I) { visitSetCC(I, ISD::SETGE, ISD::SETUGE,
ISD::SETOGE); }
void visitSetLT(User &I) { visitSetCC(I, ISD::SETLT, ISD::SETULT,
ISD::SETOLT); }
void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT,
ISD::SETOGT); }
// Visit the conversion instructions
void visitTrunc(User &I);
void visitZExt(User &I);
@ -851,9 +837,10 @@ void SelectionDAGLowering::FindMergedConditions(Value *Cond,
MachineBasicBlock *CurBB,
unsigned Opc) {
// If this node is not part of the or/and tree, emit it as a branch.
BinaryOperator *BOp = dyn_cast<BinaryOperator>(Cond);
Instruction *BOp = dyn_cast<Instruction>(Cond);
if (!BOp || (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
if (!BOp || !(isa<BinaryOperator>(BOp) || isa<CmpInst>(BOp)) ||
(unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
BOp->getParent() != CurBB->getBasicBlock() ||
!InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) ||
!InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) {
@ -875,61 +862,60 @@ void SelectionDAGLowering::FindMergedConditions(Value *Cond,
}
// If the leaf of the tree is a setcond inst, merge the condition into the
// caseblock.
if (BOp && isa<SetCondInst>(BOp) &&
// The operands of the setcc have to be in this block. We don't know
// If the leaf of the tree is a comparison, merge the condition into
// the caseblock.
if ((isa<ICmpInst>(Cond) || isa<FCmpInst>(Cond)) &&
// The operands of the cmp have to be in this block. We don't know
// how to export them from some other block. If this is the first block
// of the sequence, no exporting is needed.
(CurBB == CurMBB ||
(isExportableFromCurrentBlock(BOp->getOperand(0), BB) &&
isExportableFromCurrentBlock(BOp->getOperand(1), BB)))) {
ISD::CondCode SignCond, UnsCond, FPCond, Condition;
switch (BOp->getOpcode()) {
default: assert(0 && "Unknown setcc opcode!");
case Instruction::SetEQ:
SignCond = ISD::SETEQ;
UnsCond = ISD::SETEQ;
FPCond = ISD::SETOEQ;
break;
case Instruction::SetNE:
SignCond = ISD::SETNE;
UnsCond = ISD::SETNE;
FPCond = ISD::SETUNE;
break;
case Instruction::SetLE:
SignCond = ISD::SETLE;
UnsCond = ISD::SETULE;
FPCond = ISD::SETOLE;
break;
case Instruction::SetGE:
SignCond = ISD::SETGE;
UnsCond = ISD::SETUGE;
FPCond = ISD::SETOGE;
break;
case Instruction::SetLT:
SignCond = ISD::SETLT;
UnsCond = ISD::SETULT;
FPCond = ISD::SETOLT;
break;
case Instruction::SetGT:
SignCond = ISD::SETGT;
UnsCond = ISD::SETUGT;
FPCond = ISD::SETOGT;
break;
BOp = cast<Instruction>(Cond);
ISD::CondCode Condition;
if (ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
switch (IC->getPredicate()) {
default: assert(0 && "Unknown icmp predicate opcode!");
case ICmpInst::ICMP_EQ: Condition = ISD::SETEQ; break;
case ICmpInst::ICMP_NE: Condition = ISD::SETNE; break;
case ICmpInst::ICMP_SLE: Condition = ISD::SETLE; break;
case ICmpInst::ICMP_ULE: Condition = ISD::SETULE; break;
case ICmpInst::ICMP_SGE: Condition = ISD::SETGE; break;
case ICmpInst::ICMP_UGE: Condition = ISD::SETUGE; break;
case ICmpInst::ICMP_SLT: Condition = ISD::SETLT; break;
case ICmpInst::ICMP_ULT: Condition = ISD::SETULT; break;
case ICmpInst::ICMP_SGT: Condition = ISD::SETGT; break;
case ICmpInst::ICMP_UGT: Condition = ISD::SETUGT; break;
}
} else if (FCmpInst *FC = dyn_cast<FCmpInst>(Cond)) {
ISD::CondCode FPC, FOC;
switch (FC->getPredicate()) {
default: assert(0 && "Unknown fcmp predicate opcode!");
case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
case FCmpInst::FCMP_OEQ: FOC = ISD::SETEQ; FPC = ISD::SETOEQ; break;
case FCmpInst::FCMP_OGT: FOC = ISD::SETGT; FPC = ISD::SETOGT; break;
case FCmpInst::FCMP_OGE: FOC = ISD::SETGE; FPC = ISD::SETOGE; break;
case FCmpInst::FCMP_OLT: FOC = ISD::SETLT; FPC = ISD::SETOLT; break;
case FCmpInst::FCMP_OLE: FOC = ISD::SETLE; FPC = ISD::SETOLE; break;
case FCmpInst::FCMP_ONE: FOC = ISD::SETNE; FPC = ISD::SETONE; break;
case FCmpInst::FCMP_ORD: FOC = ISD::SETEQ; FPC = ISD::SETO; break;
case FCmpInst::FCMP_UNO: FOC = ISD::SETNE; FPC = ISD::SETUO; break;
case FCmpInst::FCMP_UEQ: FOC = ISD::SETEQ; FPC = ISD::SETUEQ; break;
case FCmpInst::FCMP_UGT: FOC = ISD::SETGT; FPC = ISD::SETUGT; break;
case FCmpInst::FCMP_UGE: FOC = ISD::SETGE; FPC = ISD::SETUGE; break;
case FCmpInst::FCMP_ULT: FOC = ISD::SETLT; FPC = ISD::SETULT; break;
case FCmpInst::FCMP_ULE: FOC = ISD::SETLE; FPC = ISD::SETULE; break;
case FCmpInst::FCMP_UNE: FOC = ISD::SETNE; FPC = ISD::SETUNE; break;
case FCmpInst::FCMP_TRUE: FOC = FPC = ISD::SETTRUE; break;
}
if (FiniteOnlyFPMath())
Condition = FOC;
else
Condition = FPC;
} else {
assert(0 && "Unknown compare instruction");
}
const Type *OpType = BOp->getOperand(0)->getType();
if (const PackedType *PTy = dyn_cast<PackedType>(OpType))
OpType = PTy->getElementType();
if (!FiniteOnlyFPMath() && OpType->isFloatingPoint())
Condition = FPCond;
else if (OpType->isUnsigned())
Condition = UnsCond;
else
Condition = SignCond;
SelectionDAGISel::CaseBlock CB(Condition, BOp->getOperand(0),
BOp->getOperand(1), TBB, FBB, CurBB);
SwitchCases.push_back(CB);
@ -1462,11 +1448,15 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
}
void SelectionDAGLowering::visitICmp(User &I) {
ICmpInst *IC = cast<ICmpInst>(&I);
SDOperand Op1 = getValue(IC->getOperand(0));
SDOperand Op2 = getValue(IC->getOperand(1));
ICmpInst::Predicate predicate = ICmpInst::BAD_ICMP_PREDICATE;
if (ICmpInst *IC = dyn_cast<ICmpInst>(&I))
predicate = IC->getPredicate();
else if (ConstantExpr *IC = dyn_cast<ConstantExpr>(&I))
predicate = ICmpInst::Predicate(IC->getPredicate());
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
ISD::CondCode Opcode;
switch (IC->getPredicate()) {
switch (predicate) {
case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break;
case ICmpInst::ICMP_NE : Opcode = ISD::SETNE; break;
case ICmpInst::ICMP_UGT : Opcode = ISD::SETUGT; break;
@ -1486,46 +1476,41 @@ void SelectionDAGLowering::visitICmp(User &I) {
}
void SelectionDAGLowering::visitFCmp(User &I) {
FCmpInst *FC = cast<FCmpInst>(&I);
SDOperand Op1 = getValue(FC->getOperand(0));
SDOperand Op2 = getValue(FC->getOperand(1));
ISD::CondCode Opcode;
switch (FC->getPredicate()) {
case FCmpInst::FCMP_FALSE : Opcode = ISD::SETFALSE;
case FCmpInst::FCMP_OEQ : Opcode = ISD::SETOEQ;
case FCmpInst::FCMP_OGT : Opcode = ISD::SETOGT;
case FCmpInst::FCMP_OGE : Opcode = ISD::SETOGE;
case FCmpInst::FCMP_OLT : Opcode = ISD::SETOLT;
case FCmpInst::FCMP_OLE : Opcode = ISD::SETOLE;
case FCmpInst::FCMP_ONE : Opcode = ISD::SETONE;
case FCmpInst::FCMP_ORD : Opcode = ISD::SETO;
case FCmpInst::FCMP_UNO : Opcode = ISD::SETUO;
case FCmpInst::FCMP_UEQ : Opcode = ISD::SETUEQ;
case FCmpInst::FCMP_UGT : Opcode = ISD::SETUGT;
case FCmpInst::FCMP_UGE : Opcode = ISD::SETUGE;
case FCmpInst::FCMP_ULT : Opcode = ISD::SETULT;
case FCmpInst::FCMP_ULE : Opcode = ISD::SETULE;
case FCmpInst::FCMP_UNE : Opcode = ISD::SETUNE;
case FCmpInst::FCMP_TRUE : Opcode = ISD::SETTRUE;
default:
assert(!"Invalid FCmp predicate value");
Opcode = ISD::SETFALSE;
break;
}
setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode));
}
void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode,
ISD::CondCode UnsignedOpcode,
ISD::CondCode FPOpcode) {
FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE;
if (FCmpInst *FC = dyn_cast<FCmpInst>(&I))
predicate = FC->getPredicate();
else if (ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
predicate = FCmpInst::Predicate(FC->getPredicate());
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
ISD::CondCode Opcode = SignedOpcode;
if (!FiniteOnlyFPMath() && I.getOperand(0)->getType()->isFloatingPoint())
Opcode = FPOpcode;
else if (I.getOperand(0)->getType()->isUnsigned())
Opcode = UnsignedOpcode;
setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode));
ISD::CondCode Condition, FOC, FPC;
switch (predicate) {
case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
case FCmpInst::FCMP_OEQ: FOC = ISD::SETEQ; FPC = ISD::SETOEQ; break;
case FCmpInst::FCMP_OGT: FOC = ISD::SETGT; FPC = ISD::SETOGT; break;
case FCmpInst::FCMP_OGE: FOC = ISD::SETGE; FPC = ISD::SETOGE; break;
case FCmpInst::FCMP_OLT: FOC = ISD::SETLT; FPC = ISD::SETOLT; break;
case FCmpInst::FCMP_OLE: FOC = ISD::SETLE; FPC = ISD::SETOLE; break;
case FCmpInst::FCMP_ONE: FOC = ISD::SETNE; FPC = ISD::SETONE; break;
case FCmpInst::FCMP_ORD: FOC = ISD::SETEQ; FPC = ISD::SETO; break;
case FCmpInst::FCMP_UNO: FOC = ISD::SETNE; FPC = ISD::SETUO; break;
case FCmpInst::FCMP_UEQ: FOC = ISD::SETEQ; FPC = ISD::SETUEQ; break;
case FCmpInst::FCMP_UGT: FOC = ISD::SETGT; FPC = ISD::SETUGT; break;
case FCmpInst::FCMP_UGE: FOC = ISD::SETGE; FPC = ISD::SETUGE; break;
case FCmpInst::FCMP_ULT: FOC = ISD::SETLT; FPC = ISD::SETULT; break;
case FCmpInst::FCMP_ULE: FOC = ISD::SETLE; FPC = ISD::SETULE; break;
case FCmpInst::FCMP_UNE: FOC = ISD::SETNE; FPC = ISD::SETUNE; break;
case FCmpInst::FCMP_TRUE: FOC = FPC = ISD::SETTRUE; break;
default:
assert(!"Invalid FCmp predicate value");
FOC = FPC = ISD::SETFALSE;
break;
}
if (FiniteOnlyFPMath())
Condition = FOC;
else
Condition = FPC;
setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Condition));
}
void SelectionDAGLowering::visitSelect(User &I) {

View File

@ -55,18 +55,8 @@ static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
GenericValue Src2, const Type *Ty);
static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2,
@ -144,30 +134,12 @@ GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
return executeXorInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetEQ:
return executeSetEQInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetNE:
return executeSetNEInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetLE:
return executeSetLEInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetGE:
return executeSetGEInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetLT:
return executeSetLTInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::SetGT:
return executeSetGTInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::FCmp:
case Instruction::ICmp:
return executeCmpInst(CE->getPredicate(),
getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getOperand(0)->getType());
case Instruction::Shl:
return executeShlInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
@ -434,33 +406,227 @@ static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
#define IMPLEMENT_SETCC(OP, TY) \
case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break
#define IMPLEMENT_CMP(OP, TY1, TY2) \
case Type::TY1##TyID: Dest.BoolVal = Src1.TY2##Val OP Src2.TY2##Val; break
// Handle pointers specially because they must be compared with only as much
// width as the host has. We _do not_ want to be comparing 64 bit values when
// running on a 32-bit target, otherwise the upper 32 bits might mess up
// comparisons if they contain garbage.
#define IMPLEMENT_POINTERSETCC(OP) \
#define IMPLEMENT_POINTERCMP(OP) \
case Type::PointerTyID: \
Dest.BoolVal = (void*)(intptr_t)Src1.PointerVal OP \
(void*)(intptr_t)Src2.PointerVal; break
static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(==, UByte, UByte);
IMPLEMENT_CMP(==, SByte, SByte);
IMPLEMENT_CMP(==, UShort, UShort);
IMPLEMENT_CMP(==, Short, Short);
IMPLEMENT_CMP(==, UInt, UInt);
IMPLEMENT_CMP(==, Int, Int);
IMPLEMENT_CMP(==, ULong, ULong);
IMPLEMENT_CMP(==, Long, Long);
IMPLEMENT_POINTERCMP(==);
default:
cerr << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(!=, UByte, UByte);
IMPLEMENT_CMP(!=, SByte, SByte);
IMPLEMENT_CMP(!=, UShort,UShort);
IMPLEMENT_CMP(!=, Short, Short);
IMPLEMENT_CMP(!=, UInt, UInt);
IMPLEMENT_CMP(!=, Int, Int);
IMPLEMENT_CMP(!=, ULong, ULong);
IMPLEMENT_CMP(!=, Long, Long);
IMPLEMENT_POINTERCMP(!=);
default:
cerr << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(<, SByte, UByte);
IMPLEMENT_CMP(<, Short, UShort);
IMPLEMENT_CMP(<, Int, UInt);
IMPLEMENT_CMP(<, Long, ULong);
IMPLEMENT_CMP(<, UByte, UByte);
IMPLEMENT_CMP(<, UShort, UShort);
IMPLEMENT_CMP(<, UInt, UInt);
IMPLEMENT_CMP(<, ULong, ULong);
IMPLEMENT_POINTERCMP(<);
default:
cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(<, SByte, SByte);
IMPLEMENT_CMP(<, Short, Short);
IMPLEMENT_CMP(<, Int, Int);
IMPLEMENT_CMP(<, Long, Long);
IMPLEMENT_CMP(<, UByte, SByte);
IMPLEMENT_CMP(<, UShort, Short);
IMPLEMENT_CMP(<, UInt, Int);
IMPLEMENT_CMP(<, ULong, Long);
IMPLEMENT_POINTERCMP(<);
default:
cerr << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(>, SByte, UByte);
IMPLEMENT_CMP(>, Short, UShort);
IMPLEMENT_CMP(>, Int, UInt);
IMPLEMENT_CMP(>, Long, ULong);
IMPLEMENT_CMP(>, UByte, UByte);
IMPLEMENT_CMP(>, UShort, UShort);
IMPLEMENT_CMP(>, UInt, UInt);
IMPLEMENT_CMP(>, ULong, ULong);
IMPLEMENT_POINTERCMP(>);
default:
cerr << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(>, SByte, SByte);
IMPLEMENT_CMP(>, Short, Short);
IMPLEMENT_CMP(>, Int, Int);
IMPLEMENT_CMP(>, Long, Long);
IMPLEMENT_CMP(>, UByte, SByte);
IMPLEMENT_CMP(>, UShort, Short);
IMPLEMENT_CMP(>, UInt, Int);
IMPLEMENT_CMP(>, ULong, Long);
IMPLEMENT_POINTERCMP(>);
default:
cerr << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(<=, SByte, UByte);
IMPLEMENT_CMP(<=, Short, UShort);
IMPLEMENT_CMP(<=, Int, UInt);
IMPLEMENT_CMP(<=, Long, ULong);
IMPLEMENT_CMP(<=, UByte, UByte);
IMPLEMENT_CMP(<=, UShort, UShort);
IMPLEMENT_CMP(<=, UInt, UInt);
IMPLEMENT_CMP(<=, ULong, ULong);
IMPLEMENT_POINTERCMP(<=);
default:
cerr << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(<=, SByte, SByte);
IMPLEMENT_CMP(<=, Short, Short);
IMPLEMENT_CMP(<=, Int, Int);
IMPLEMENT_CMP(<=, Long, Long);
IMPLEMENT_CMP(<=, UByte, SByte);
IMPLEMENT_CMP(<=, UShort, Short);
IMPLEMENT_CMP(<=, UInt, Int);
IMPLEMENT_CMP(<=, ULong, Long);
IMPLEMENT_POINTERCMP(<=);
default:
cerr << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(>=, SByte, UByte);
IMPLEMENT_CMP(>=, Short, UShort);
IMPLEMENT_CMP(>=, Int, UInt);
IMPLEMENT_CMP(>=, Long, ULong);
IMPLEMENT_CMP(>=, UByte, UByte);
IMPLEMENT_CMP(>=, UShort, UShort);
IMPLEMENT_CMP(>=, UInt, UInt);
IMPLEMENT_CMP(>=, ULong, ULong);
IMPLEMENT_POINTERCMP(>=);
default:
cerr << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_CMP(>=, SByte, SByte);
IMPLEMENT_CMP(>=, Short, Short);
IMPLEMENT_CMP(>=, Int, Int);
IMPLEMENT_CMP(>=, Long, Long);
IMPLEMENT_CMP(>=, UByte, SByte);
IMPLEMENT_CMP(>=, UShort, Short);
IMPLEMENT_CMP(>=, UInt, Int);
IMPLEMENT_CMP(>=, ULong, Long);
IMPLEMENT_POINTERCMP(>=);
default:
cerr << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
abort();
}
return Dest;
}
#define IMPLEMENT_SETCC(OP, TY) \
case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break
static GenericValue executeFCMP_EQ(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(==, UByte);
IMPLEMENT_SETCC(==, SByte);
IMPLEMENT_SETCC(==, UShort);
IMPLEMENT_SETCC(==, Short);
IMPLEMENT_SETCC(==, UInt);
IMPLEMENT_SETCC(==, Int);
IMPLEMENT_SETCC(==, ULong);
IMPLEMENT_SETCC(==, Long);
IMPLEMENT_SETCC(==, Float);
IMPLEMENT_SETCC(==, Double);
IMPLEMENT_POINTERSETCC(==);
default:
cerr << "Unhandled type for SetEQ instruction: " << *Ty << "\n";
abort();
@ -468,21 +634,12 @@ static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(!=, UByte);
IMPLEMENT_SETCC(!=, SByte);
IMPLEMENT_SETCC(!=, UShort);
IMPLEMENT_SETCC(!=, Short);
IMPLEMENT_SETCC(!=, UInt);
IMPLEMENT_SETCC(!=, Int);
IMPLEMENT_SETCC(!=, ULong);
IMPLEMENT_SETCC(!=, Long);
IMPLEMENT_SETCC(!=, Float);
IMPLEMENT_SETCC(!=, Double);
IMPLEMENT_POINTERSETCC(!=);
default:
cerr << "Unhandled type for SetNE instruction: " << *Ty << "\n";
@ -491,21 +648,12 @@ static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
static GenericValue executeFCMP_LE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(<=, UByte);
IMPLEMENT_SETCC(<=, SByte);
IMPLEMENT_SETCC(<=, UShort);
IMPLEMENT_SETCC(<=, Short);
IMPLEMENT_SETCC(<=, UInt);
IMPLEMENT_SETCC(<=, Int);
IMPLEMENT_SETCC(<=, ULong);
IMPLEMENT_SETCC(<=, Long);
IMPLEMENT_SETCC(<=, Float);
IMPLEMENT_SETCC(<=, Double);
IMPLEMENT_POINTERSETCC(<=);
default:
cerr << "Unhandled type for SetLE instruction: " << *Ty << "\n";
abort();
@ -513,21 +661,12 @@ static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
static GenericValue executeFCMP_GE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(>=, UByte);
IMPLEMENT_SETCC(>=, SByte);
IMPLEMENT_SETCC(>=, UShort);
IMPLEMENT_SETCC(>=, Short);
IMPLEMENT_SETCC(>=, UInt);
IMPLEMENT_SETCC(>=, Int);
IMPLEMENT_SETCC(>=, ULong);
IMPLEMENT_SETCC(>=, Long);
IMPLEMENT_SETCC(>=, Float);
IMPLEMENT_SETCC(>=, Double);
IMPLEMENT_POINTERSETCC(>=);
default:
cerr << "Unhandled type for SetGE instruction: " << *Ty << "\n";
abort();
@ -535,21 +674,12 @@ static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
static GenericValue executeFCMP_LT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(<, UByte);
IMPLEMENT_SETCC(<, SByte);
IMPLEMENT_SETCC(<, UShort);
IMPLEMENT_SETCC(<, Short);
IMPLEMENT_SETCC(<, UInt);
IMPLEMENT_SETCC(<, Int);
IMPLEMENT_SETCC(<, ULong);
IMPLEMENT_SETCC(<, Long);
IMPLEMENT_SETCC(<, Float);
IMPLEMENT_SETCC(<, Double);
IMPLEMENT_POINTERSETCC(<);
default:
cerr << "Unhandled type for SetLT instruction: " << *Ty << "\n";
abort();
@ -557,21 +687,12 @@ static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2,
static GenericValue executeFCMP_GT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_SETCC(>, UByte);
IMPLEMENT_SETCC(>, SByte);
IMPLEMENT_SETCC(>, UShort);
IMPLEMENT_SETCC(>, Short);
IMPLEMENT_SETCC(>, UInt);
IMPLEMENT_SETCC(>, Int);
IMPLEMENT_SETCC(>, ULong);
IMPLEMENT_SETCC(>, Long);
IMPLEMENT_SETCC(>, Float);
IMPLEMENT_SETCC(>, Double);
IMPLEMENT_POINTERSETCC(>);
default:
cerr << "Unhandled type for SetGT instruction: " << *Ty << "\n";
abort();
@ -579,6 +700,108 @@ static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
void Interpreter::visitFCmpInst(FCmpInst &I) {
ExecutionContext &SF = ECStack.back();
const Type *Ty = I.getOperand(0)->getType();
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue R; // Result
switch (I.getPredicate()) {
case FCmpInst::FCMP_FALSE: R.BoolVal = false;
case FCmpInst::FCMP_ORD: R = executeFCMP_EQ(Src1, Src2, Ty); break; ///???
case FCmpInst::FCMP_UNO: R = executeFCMP_NE(Src1, Src2, Ty); break; ///???
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ: R = executeFCMP_EQ(Src1, Src2, Ty); break;
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE: R = executeFCMP_NE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OLT:
case FCmpInst::FCMP_ULT: R = executeFCMP_LT(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_UGT: R = executeFCMP_GT(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_ULE: R = executeFCMP_LE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_UGE: R = executeFCMP_GE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_TRUE: R.BoolVal = true;
default:
cerr << "Don't know how to handle this FCmp predicate!\n-->" << I;
abort();
}
SetValue(&I, R, SF);
}
void Interpreter::visitICmpInst(ICmpInst &I) {
ExecutionContext &SF = ECStack.back();
const Type *Ty = I.getOperand(0)->getType();
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue R; // Result
switch (I.getPredicate()) {
case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_SGT: R = executeICMP_SGT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_ULE: R = executeICMP_ULE(Src1, Src2, Ty); break;
case ICmpInst::ICMP_SLE: R = executeICMP_SLE(Src1, Src2, Ty); break;
case ICmpInst::ICMP_UGE: R = executeICMP_UGE(Src1, Src2, Ty); break;
case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
default:
cerr << "Don't know how to handle this ICmp predicate!\n-->" << I;
abort();
}
SetValue(&I, R, SF);
}
static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
GenericValue Src2, const Type *Ty) {
GenericValue Result;
switch (predicate) {
case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty);
case ICmpInst::ICMP_NE: return executeICMP_NE(Src1, Src2, Ty);
case ICmpInst::ICMP_UGT: return executeICMP_UGT(Src1, Src2, Ty);
case ICmpInst::ICMP_SGT: return executeICMP_SGT(Src1, Src2, Ty);
case ICmpInst::ICMP_ULT: return executeICMP_ULT(Src1, Src2, Ty);
case ICmpInst::ICMP_SLT: return executeICMP_SLT(Src1, Src2, Ty);
case ICmpInst::ICMP_UGE: return executeICMP_UGE(Src1, Src2, Ty);
case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty);
case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty);
case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty);
case FCmpInst::FCMP_ORD: return executeFCMP_EQ(Src1, Src2, Ty); break;
case FCmpInst::FCMP_UNO: return executeFCMP_NE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ: return executeFCMP_EQ(Src1, Src2, Ty); break;
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE: return executeFCMP_NE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OLT:
case FCmpInst::FCMP_ULT: return executeFCMP_LT(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_UGT: return executeFCMP_GT(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_ULE: return executeFCMP_LE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_UGE: return executeFCMP_GE(Src1, Src2, Ty); break;
case FCmpInst::FCMP_FALSE: {
GenericValue Result;
Result.BoolVal = false;
return Result;
}
case FCmpInst::FCMP_TRUE: {
GenericValue Result;
Result.BoolVal = true;
return Result;
}
default:
cerr << "Unhandled Cmp predicate\n";
abort();
}
}
void Interpreter::visitBinaryOperator(BinaryOperator &I) {
ExecutionContext &SF = ECStack.back();
const Type *Ty = I.getOperand(0)->getType();
@ -599,12 +822,6 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
case Instruction::And: R = executeAndInst (Src1, Src2, Ty); break;
case Instruction::Or: R = executeOrInst (Src1, Src2, Ty); break;
case Instruction::Xor: R = executeXorInst (Src1, Src2, Ty); break;
case Instruction::SetEQ: R = executeSetEQInst(Src1, Src2, Ty); break;
case Instruction::SetNE: R = executeSetNEInst(Src1, Src2, Ty); break;
case Instruction::SetLE: R = executeSetLEInst(Src1, Src2, Ty); break;
case Instruction::SetGE: R = executeSetGEInst(Src1, Src2, Ty); break;
case Instruction::SetLT: R = executeSetLTInst(Src1, Src2, Ty); break;
case Instruction::SetGT: R = executeSetGTInst(Src1, Src2, Ty); break;
default:
cerr << "Don't know how to handle this binary operator!\n-->" << I;
abort();
@ -732,8 +949,8 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
// Check to see if any of the cases match...
BasicBlock *Dest = 0;
for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2)
if (executeSetEQInst(CondVal,
getOperandValue(I.getOperand(i), SF), ElTy).BoolVal) {
if (executeICMP_EQ(CondVal,
getOperandValue(I.getOperand(i), SF), ElTy).BoolVal) {
Dest = cast<BasicBlock>(I.getOperand(i+1));
break;
}

View File

@ -136,6 +136,8 @@ public:
void visitSwitchInst(SwitchInst &I);
void visitBinaryOperator(BinaryOperator &I);
void visitICmpInst(ICmpInst &I);
void visitFCmpInst(FCmpInst &I);
void visitAllocationInst(AllocationInst &I);
void visitFreeInst(FreeInst &I);
void visitLoadInst(LoadInst &I);

View File

@ -11,4 +11,4 @@ LEVEL = ../../..
LIBRARYNAME = LLVMCBackend
include $(LEVEL)/Makefile.common
CompileCommonOpts := $(CompileCommonOpts) -Wno-format
CompileCommonOpts += -Wno-format

View File

@ -116,6 +116,9 @@ namespace {
std::ostream &printType(std::ostream &Out, const Type *Ty,
const std::string &VariableName = "",
bool IgnoreName = false);
std::ostream &printPrimitiveType(std::ostream &Out, const Type *Ty,
bool isSigned,
const std::string &NameSoFar = "");
void printStructReturnPointerFunctionType(std::ostream &Out,
const PointerType *Ty);
@ -124,6 +127,7 @@ namespace {
void writeOperandRaw(Value *Operand);
void writeOperandInternal(Value *Operand);
void writeOperandWithCast(Value* Operand, unsigned Opcode);
void writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate);
bool writeInstructionCast(const Instruction &I);
private :
@ -154,9 +158,10 @@ namespace {
// printed and an extra copy of the expr is not emitted.
//
static bool isInlinableInst(const Instruction &I) {
// Always inline setcc instructions, even if they are shared by multiple
// Always inline cmp instructions, even if they are shared by multiple
// expressions. GCC generates horrible code if we don't.
if (isa<SetCondInst>(I)) return true;
if (isa<CmpInst>(I))
return true;
// Must be an expression, must be used exactly once. If it is dead, we
// emit it inline where it would go.
@ -211,6 +216,8 @@ namespace {
void visitPHINode(PHINode &I);
void visitBinaryOperator(Instruction &I);
void visitICmpInst(ICmpInst &I);
void visitFCmpInst(FCmpInst &I);
void visitCastInst (CastInst &I);
void visitSelectInst(SelectInst &I);
@ -351,6 +358,32 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
printType(Out, RetTy, tstr);
}
std::ostream &
CWriter::printPrimitiveType(std::ostream &Out, const Type *Ty, bool isSigned,
const std::string &NameSoFar) {
assert(Ty->isPrimitiveType() && "Invalid type for printPrimitiveType");
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
case Type::BoolTyID: return Out << "bool " << NameSoFar;
case Type::UByteTyID:
case Type::SByteTyID:
return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar;
case Type::UShortTyID:
case Type::ShortTyID:
return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar;
case Type::UIntTyID:
case Type::IntTyID:
return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar;
case Type::ULongTyID:
case Type::LongTyID:
return Out << (isSigned?"signed":"unsigned") << " long long " << NameSoFar;
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
default :
cerr << "Unknown primitive type: " << *Ty << "\n";
abort();
}
}
// Pass the Type* and the variable name and this prints out the variable
// declaration.
@ -358,24 +391,13 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
const std::string &NameSoFar,
bool IgnoreName) {
if (Ty->isPrimitiveType())
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
case Type::BoolTyID: return Out << "bool " << NameSoFar;
case Type::UByteTyID: return Out << "unsigned char " << NameSoFar;
case Type::SByteTyID: return Out << "signed char " << NameSoFar;
case Type::UShortTyID: return Out << "unsigned short " << NameSoFar;
case Type::ShortTyID: return Out << "short " << NameSoFar;
case Type::UIntTyID: return Out << "unsigned " << NameSoFar;
case Type::IntTyID: return Out << "int " << NameSoFar;
case Type::ULongTyID: return Out << "unsigned long long " << NameSoFar;
case Type::LongTyID: return Out << "signed long long " << NameSoFar;
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
default :
cerr << "Unknown primitive type: " << *Ty << "\n";
abort();
}
if (Ty->isPrimitiveType()) {
// FIXME:Signedness. When integer types are signless, this should just
// always pass "false" for the sign of the primitive type. The instructions
// will figure out how the value is to be interpreted.
printPrimitiveType(Out, Ty, true, NameSoFar);
return Out;
}
// Check to see if the type is named.
if (!IgnoreName || isa<OpaqueType>(Ty)) {
@ -578,41 +600,66 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) {
/// Print out the casting for a cast operation. This does the double casting
/// necessary for conversion to the destination type, if necessary.
/// @returns true if a closing paren is necessary
/// @brief Print a cast
void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) {
Out << '(';
printType(Out, DstTy);
Out << ')';
// Print the destination type cast
switch (opc) {
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::IntToPtr:
case Instruction::Trunc:
case Instruction::BitCast:
case Instruction::FPExt:
case Instruction::FPTrunc: // For these the DstTy sign doesn't matter
Out << '(';
printType(Out, DstTy);
Out << ')';
break;
case Instruction::ZExt:
case Instruction::PtrToInt:
case Instruction::FPToUI: // For these, make sure we get an unsigned dest
Out << '(';
printPrimitiveType(Out, DstTy, false);
Out << ')';
break;
case Instruction::SExt:
case Instruction::FPToSI: // For these, make sure we get a signed dest
Out << '(';
printPrimitiveType(Out, DstTy, true);
Out << ')';
break;
default:
assert(0 && "Invalid cast opcode");
}
// Print the source type cast
switch (opc) {
case Instruction::UIToFP:
case Instruction::ZExt:
if (SrcTy->isSigned()) {
Out << '(';
printType(Out, SrcTy->getUnsignedVersion());
Out << ')';
}
Out << '(';
printPrimitiveType(Out, SrcTy, false);
Out << ')';
break;
case Instruction::SIToFP:
case Instruction::SExt:
if (SrcTy->isUnsigned()) {
Out << '(';
printType(Out, SrcTy->getSignedVersion());
Out << ')';
}
Out << '(';
printPrimitiveType(Out, SrcTy, true);
Out << ')';
break;
case Instruction::IntToPtr:
case Instruction::PtrToInt:
// Avoid "cast to pointer from integer of different size" warnings
Out << "(unsigned long)";
break;
// Avoid "cast to pointer from integer of different size" warnings
Out << "(unsigned long)";
break;
case Instruction::Trunc:
case Instruction::BitCast:
case Instruction::FPExt:
case Instruction::FPTrunc:
case Instruction::FPToSI:
case Instruction::FPToUI:
break; // These don't need a source cast.
default:
assert(0 && "Invalid cast opcode");
break;
}
}
@ -679,12 +726,8 @@ void CWriter::printConstant(Constant *CPV) {
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::SetEQ:
case Instruction::SetNE:
case Instruction::SetLT:
case Instruction::SetLE:
case Instruction::SetGT:
case Instruction::SetGE:
case Instruction::ICmp:
case Instruction::FCmp:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@ -705,15 +748,43 @@ void CWriter::printConstant(Constant *CPV) {
case Instruction::And: Out << " & "; break;
case Instruction::Or: Out << " | "; break;
case Instruction::Xor: Out << " ^ "; break;
case Instruction::SetEQ: Out << " == "; break;
case Instruction::SetNE: Out << " != "; break;
case Instruction::SetLT: Out << " < "; break;
case Instruction::SetLE: Out << " <= "; break;
case Instruction::SetGT: Out << " > "; break;
case Instruction::SetGE: Out << " >= "; break;
case Instruction::Shl: Out << " << "; break;
case Instruction::LShr:
case Instruction::AShr: Out << " >> "; break;
case Instruction::ICmp:
switch (CE->getPredicate()) {
case ICmpInst::ICMP_EQ: Out << " == "; break;
case ICmpInst::ICMP_NE: Out << " != "; break;
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_ULT: Out << " < "; break;
case ICmpInst::ICMP_SLE:
case ICmpInst::ICMP_ULE: Out << " <= "; break;
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_UGT: Out << " > "; break;
case ICmpInst::ICMP_SGE:
case ICmpInst::ICMP_UGE: Out << " >= "; break;
default: assert(0 && "Illegal ICmp predicate");
}
break;
case Instruction::FCmp:
switch (CE->getPredicate()) {
case FCmpInst::FCMP_ORD:
case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_OEQ: Out << " == "; break;
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_UNE:
case FCmpInst::FCMP_ONE: Out << " != "; break;
case FCmpInst::FCMP_OLT:
case FCmpInst::FCMP_ULT: Out << " < "; break;
case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_ULE: Out << " <= "; break;
case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_UGT: Out << " > "; break;
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_UGE: Out << " >= "; break;
default: assert(0 && "Illegal FCmp predicate");
}
break;
default: assert(0 && "Illegal opcode here!");
}
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
@ -730,7 +801,7 @@ void CWriter::printConstant(Constant *CPV) {
}
} else if (isa<UndefValue>(CPV) && CPV->getType()->isFirstClassType()) {
Out << "((";
printType(Out, CPV->getType());
printType(Out, CPV->getType()); // sign doesn't matter
Out << ")/*UNDEF*/0)";
return;
}
@ -740,9 +811,23 @@ void CWriter::printConstant(Constant *CPV) {
Out << (cast<ConstantBool>(CPV)->getValue() ? '1' : '0');
break;
case Type::SByteTyID:
case Type::ShortTyID:
Out << cast<ConstantInt>(CPV)->getSExtValue();
case Type::UByteTyID:
Out << "((char)" << cast<ConstantInt>(CPV)->getSExtValue() << ")";
break;
case Type::ShortTyID:
case Type::UShortTyID:
Out << "((short)" << cast<ConstantInt>(CPV)->getSExtValue() << ")";
break;
case Type::IntTyID:
case Type::UIntTyID:
Out << "((int)" << cast<ConstantInt>(CPV)->getSExtValue() << ")";
break;
case Type::LongTyID:
case Type::ULongTyID:
Out << "((long long)" << cast<ConstantInt>(CPV)->getSExtValue() << "ll)";
break;
#if 0
case Type::IntTyID:
if ((int)cast<ConstantInt>(CPV)->getSExtValue() == (int)0x80000000)
Out << "((int)0x80000000U)"; // Handle MININT specially to avoid warning
@ -767,6 +852,7 @@ void CWriter::printConstant(Constant *CPV) {
case Type::ULongTyID:
Out << cast<ConstantInt>(CPV)->getZExtValue() << "ull";
break;
#endif
case Type::FloatTyID:
case Type::DoubleTyID: {
@ -890,7 +976,7 @@ void CWriter::printConstant(Constant *CPV) {
case Type::PointerTyID:
if (isa<ConstantPointerNull>(CPV)) {
Out << "((";
printType(Out, CPV->getType());
printType(Out, CPV->getType()); // sign doesn't matter
Out << ")/*NULL*/0)";
break;
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(CPV)) {
@ -910,17 +996,20 @@ void CWriter::printConstant(Constant *CPV) {
bool CWriter::printConstExprCast(const ConstantExpr* CE) {
bool NeedsExplicitCast = false;
const Type *Ty = CE->getOperand(0)->getType();
bool TypeIsSigned = false;
switch (CE->getOpcode()) {
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv:
NeedsExplicitCast = Ty->isSigned(); break;
case Instruction::UDiv: NeedsExplicitCast = true; break;
case Instruction::AShr:
case Instruction::SRem:
case Instruction::SDiv:
NeedsExplicitCast = Ty->isUnsigned(); break;
case Instruction::ZExt:
case Instruction::SDiv: NeedsExplicitCast = true; TypeIsSigned = true; break;
case Instruction::SExt:
Ty = CE->getType();
NeedsExplicitCast = true;
TypeIsSigned = true;
break;
case Instruction::ZExt:
case Instruction::Trunc:
case Instruction::FPTrunc:
case Instruction::FPExt:
@ -938,7 +1027,10 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE) {
}
if (NeedsExplicitCast) {
Out << "((";
printType(Out, Ty);
if (Ty->isPrimitiveType())
printPrimitiveType(Out, Ty, TypeIsSigned);
else
printType(Out, Ty);
Out << ")(";
}
return NeedsExplicitCast;
@ -954,6 +1046,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
// Indicate whether to do the cast or not.
bool shouldCast = false;
bool typeIsSigned = false;
// Based on the Opcode for which this Constant is being written, determine
// the new type to which the operand should be casted by setting the value
@ -966,20 +1059,13 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem:
// For UDiv/URem get correct type
if (OpTy->isSigned()) {
OpTy = OpTy->getUnsignedVersion();
shouldCast = true;
}
shouldCast = true;
break;
case Instruction::AShr:
case Instruction::SDiv:
case Instruction::SRem:
// For SDiv/SRem get correct type
if (OpTy->isUnsigned()) {
OpTy = OpTy->getSignedVersion();
shouldCast = true;
}
shouldCast = true;
typeIsSigned = true;
break;
}
@ -987,13 +1073,12 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
// operand.
if (shouldCast) {
Out << "((";
printType(Out, OpTy);
printPrimitiveType(Out, OpTy, typeIsSigned);
Out << ")";
printConstant(CPV);
Out << ")";
} else
writeOperand(CPV);
printConstant(CPV);
}
void CWriter::writeOperandInternal(Value *Operand) {
@ -1038,40 +1123,25 @@ void CWriter::writeOperand(Value *Operand) {
// This function takes care of detecting that case and printing the cast
// for the Instruction.
bool CWriter::writeInstructionCast(const Instruction &I) {
bool NeedsExplicitCast = false;
const Type *Ty = I.getOperand(0)->getType();
switch (I.getOpcode()) {
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv:
NeedsExplicitCast = Ty->isSigned(); break;
Out << "((";
printPrimitiveType(Out, Ty, false);
Out << ")(";
return true;
case Instruction::AShr:
case Instruction::SRem:
case Instruction::SDiv:
NeedsExplicitCast = Ty->isUnsigned(); break;
case Instruction::ZExt:
case Instruction::SExt:
case Instruction::Trunc:
case Instruction::FPTrunc:
case Instruction::FPExt:
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
Ty = I.getType();
NeedsExplicitCast = true;
break;
Out << "((";
printPrimitiveType(Out, Ty, true);
Out << ")(";
return true;
default: break;
}
if (NeedsExplicitCast) {
Out << "((";
printType(Out, Ty);
Out << ")(";
}
return NeedsExplicitCast;
return false;
}
// Write the operand with a cast to another type based on the Opcode being used.
@ -1085,6 +1155,9 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
// Indicate whether to do the cast or not.
bool shouldCast = false;
// Indicate whether the cast should be to a signed type or not.
bool castIsSigned = false;
// Based on the Opcode for which this Operand is being written, determine
// the new type to which the operand should be casted by setting the value
// of OpTy. If we change OpTy, also set shouldCast to true.
@ -1094,20 +1167,15 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
break;
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem:
// For UDiv to have unsigned operands
if (OpTy->isSigned()) {
OpTy = OpTy->getUnsignedVersion();
shouldCast = true;
}
case Instruction::URem: // Cast to unsigned first
shouldCast = true;
castIsSigned = false;
break;
case Instruction::AShr:
case Instruction::SDiv:
case Instruction::SRem:
if (OpTy->isUnsigned()) {
OpTy = OpTy->getSignedVersion();
shouldCast = true;
}
case Instruction::SRem: // Cast to signed first
shouldCast = true;
castIsSigned = true;
break;
}
@ -1115,13 +1183,62 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
// operand.
if (shouldCast) {
Out << "((";
printType(Out, OpTy);
printPrimitiveType(Out, OpTy, castIsSigned);
Out << ")";
writeOperand(Operand);
Out << ")";
} else
writeOperand(Operand);
}
// Write the operand with a cast to another type based on the icmp predicate
// being used.
void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate) {
// Extract the operand's type, we'll need it.
const Type* OpTy = Operand->getType();
// Indicate whether to do the cast or not.
bool shouldCast = false;
// Indicate whether the cast should be to a signed type or not.
bool castIsSigned = false;
// Based on the Opcode for which this Operand is being written, determine
// the new type to which the operand should be casted by setting the value
// of OpTy. If we change OpTy, also set shouldCast to true.
switch (predicate) {
default:
// for eq and ne, it doesn't matter
break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_ULE:
shouldCast = true;
break;
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_SGE:
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_SLE:
shouldCast = true;
castIsSigned = true;
break;
}
// Write out the casted operand if we should, otherwise just write the
// operand.
if (shouldCast) {
Out << "((";
if (OpTy->isPrimitiveType())
printPrimitiveType(Out, OpTy, castIsSigned);
else
printType(Out, OpTy);
Out << ")";
writeOperand(Operand);
Out << ")";
} else
writeOperand(Operand);
}
// generateCompilerSpecificCode - This is where we add conditional compilation
@ -1725,7 +1842,7 @@ void CWriter::printFunction(Function &F) {
PrintedVar = true;
}
// We need a temporary for the BitCast to use so it can pluck a value out
// of a uniont to do the BitCast. This is separate from the need for a
// of a union to do the BitCast. This is separate from the need for a
// variable to hold the result of the BitCast.
if (isFPIntBitCast(*I)) {
Out << " llvmBitCastUnion " << Mang->getValueName(&*I)
@ -1992,12 +2109,6 @@ void CWriter::visitBinaryOperator(Instruction &I) {
case Instruction::And: Out << " & "; break;
case Instruction::Or: Out << " | "; break;
case Instruction::Xor: Out << " ^ "; break;
case Instruction::SetEQ: Out << " == "; break;
case Instruction::SetNE: Out << " != "; break;
case Instruction::SetLE: Out << " <= "; break;
case Instruction::SetGE: Out << " >= "; break;
case Instruction::SetLT: Out << " < "; break;
case Instruction::SetGT: Out << " > "; break;
case Instruction::Shl : Out << " << "; break;
case Instruction::LShr:
case Instruction::AShr: Out << " >> "; break;
@ -2014,6 +2125,70 @@ void CWriter::visitBinaryOperator(Instruction &I) {
}
}
void CWriter::visitICmpInst(ICmpInst &I) {
// We must cast the results of icmp which might be promoted.
bool needsCast = false;
// Write out the cast of the instruction's value back to the proper type
// if necessary.
bool NeedsClosingParens = writeInstructionCast(I);
// Certain icmp predicate require the operand to be forced to a specific type
// so we use writeOperandWithCast here instead of writeOperand. Similarly
// below for operand 1
writeOperandWithCast(I.getOperand(0), I.getPredicate());
switch (I.getPredicate()) {
case ICmpInst::ICMP_EQ: Out << " == "; break;
case ICmpInst::ICMP_NE: Out << " != "; break;
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE: Out << " <= "; break;
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE: Out << " >= "; break;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT: Out << " < "; break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT: Out << " > "; break;
default: cerr << "Invalid icmp predicate!" << I; abort();
}
writeOperandWithCast(I.getOperand(1), I.getPredicate());
if (NeedsClosingParens)
Out << "))";
if (needsCast) {
Out << "))";
}
}
void CWriter::visitFCmpInst(FCmpInst &I) {
// Write the first operand
writeOperand(I.getOperand(0));
// Write the predicate
switch (I.getPredicate()) {
case FCmpInst::FCMP_FALSE: Out << " 0 "; break;
case FCmpInst::FCMP_ORD:
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ: Out << " == "; break;
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE: Out << " != "; break;
case FCmpInst::FCMP_ULE:
case FCmpInst::FCMP_OLE: Out << " <= "; break;
case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_OGE: Out << " >= "; break;
case FCmpInst::FCMP_ULT:
case FCmpInst::FCMP_OLT: Out << " < "; break;
case FCmpInst::FCMP_UGT:
case FCmpInst::FCMP_OGT: Out << " > "; break;
case FCmpInst::FCMP_TRUE: Out << " 1 "; break;
default: cerr << "Invalid fcmp predicate!" << I; abort();
}
// Write the second operand
writeOperand(I.getOperand(1));
}
static const char * getFloatBitCastField(const Type *Ty) {
switch (Ty->getTypeID()) {
default: assert(0 && "Invalid Type");

View File

@ -324,7 +324,7 @@ unsigned short read_16_be(const unsigned char *adr) {
//===---------------------------------------------------------------------===//
-instcombine should handle this transform:
setcc (sdiv X / C1 ), C2
icmp pred (sdiv X / C1 ), C2
when X, C1, and C2 are unsigned. Similarly for udiv and signed operands.
Currently InstCombine avoids this transform but will do it when the signs of

View File

@ -463,10 +463,13 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
return ValueConvertibleToType(I, Ty, CTMap, TD) &&
ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
}
case Instruction::SetEQ:
case Instruction::SetNE: {
Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
case Instruction::ICmp: {
if (cast<ICmpInst>(I)->getPredicate() == ICmpInst::ICMP_EQ ||
cast<ICmpInst>(I)->getPredicate() == ICmpInst::ICMP_NE) {
Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
}
return false;
}
case Instruction::LShr:
case Instruction::AShr:
@ -717,9 +720,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
}
case Instruction::Add:
case Instruction::Sub:
case Instruction::SetEQ:
case Instruction::SetNE: {
case Instruction::Sub: {
Res = BinaryOperator::create(cast<BinaryOperator>(I)->getOpcode(),
Dummy, Dummy, Name);
VMC.ExprMap[I] = Res; // Add node to expression eagerly
@ -731,6 +732,19 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
Res->setOperand(OtherIdx, NewOther);
break;
}
case Instruction::ICmp: {
ICmpInst::Predicate pred = cast<ICmpInst>(I)->getPredicate();
if (pred == ICmpInst::ICMP_EQ || pred == ICmpInst::ICMP_NE) {
Res = new ICmpInst(pred, Dummy, Dummy, Name);
VMC.ExprMap[I] = Res; // Add node to expression eagerly
unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0;
Value *OtherOp = I->getOperand(OtherIdx);
Res->setOperand(!OtherIdx, NewVal);
Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC, TD);
Res->setOperand(OtherIdx, NewOther);
}
break;
}
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:

View File

@ -238,7 +238,7 @@ static bool AnalyzeGlobal(Value *V, GlobalStatus &GS,
if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
GS.isNotSuitableForSRA = true;
GS.HasPHIUser = true;
} else if (isa<SetCondInst>(I)) {
} else if (isa<CmpInst>(I)) {
GS.isNotSuitableForSRA = true;
} else if (isa<MemCpyInst>(I) || isa<MemMoveInst>(I)) {
if (I->getOperand(1) == V)
@ -507,7 +507,7 @@ static bool AllUsesOfValueWillTrapIfNull(Value *V) {
if (!AllUsesOfValueWillTrapIfNull(CI)) return false;
} else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI)) {
if (!AllUsesOfValueWillTrapIfNull(GEPI)) return false;
} else if (isa<SetCondInst>(*UI) &&
} else if (isa<ICmpInst>(*UI) &&
isa<ConstantPointerNull>(UI->getOperand(1))) {
// Ignore setcc X, null
} else {
@ -720,29 +720,33 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
while (!LI->use_empty()) {
Use &LoadUse = LI->use_begin().getUse();
if (!isa<SetCondInst>(LoadUse.getUser()))
if (!isa<ICmpInst>(LoadUse.getUser()))
LoadUse = RepValue;
else {
// Replace the setcc X, 0 with a use of the bool value.
SetCondInst *SCI = cast<SetCondInst>(LoadUse.getUser());
Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", SCI);
ICmpInst *CI = cast<ICmpInst>(LoadUse.getUser());
// Replace the cmp X, 0 with a use of the bool value.
Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", CI);
InitBoolUsed = true;
switch (SCI->getOpcode()) {
default: assert(0 && "Unknown opcode!");
case Instruction::SetLT:
switch (CI->getPredicate()) {
default: assert(0 && "Unknown ICmp Predicate!");
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
LV = ConstantBool::getFalse(); // X < null -> always false
break;
case Instruction::SetEQ:
case Instruction::SetLE:
LV = BinaryOperator::createNot(LV, "notinit", SCI);
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
case ICmpInst::ICMP_EQ:
LV = BinaryOperator::createNot(LV, "notinit", CI);
break;
case Instruction::SetNE:
case Instruction::SetGE:
case Instruction::SetGT:
case ICmpInst::ICMP_NE:
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
break; // no change.
}
SCI->replaceAllUsesWith(LV);
SCI->eraseFromParent();
CI->replaceAllUsesWith(LV);
CI->eraseFromParent();
}
}
LI->eraseFromParent();
@ -783,7 +787,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V,
GlobalVariable *GV) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI)
if (isa<LoadInst>(*UI) || isa<SetCondInst>(*UI)) {
if (isa<LoadInst>(*UI) || isa<CmpInst>(*UI)) {
// Fine, ignore.
} else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
if (SI->getOperand(0) == V && SI->getOperand(1) != GV)
@ -832,8 +836,8 @@ static bool GlobalLoadUsesSimpleEnoughForHeapSRA(GlobalVariable *GV) {
for (Value::use_iterator UI = LI->use_begin(), E = LI->use_end(); UI != E;
++UI) {
// Comparison against null is ok.
if (SetCondInst *SCI = dyn_cast<SetCondInst>(*UI)) {
if (!isa<ConstantPointerNull>(SCI->getOperand(1)))
if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
return false;
continue;
}
@ -865,7 +869,7 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
Instruction *User = Ptr->use_back();
// If this is a comparison against null, handle it.
if (SetCondInst *SCI = dyn_cast<SetCondInst>(User)) {
if (ICmpInst *SCI = dyn_cast<ICmpInst>(User)) {
assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
// If we have a setcc of the loaded pointer, we can use a setcc of any
// field.
@ -877,9 +881,9 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
NPtr = InsertedLoadsForPtr.back();
}
Value *New = new SetCondInst(SCI->getOpcode(), NPtr,
Constant::getNullValue(NPtr->getType()),
SCI->getName(), SCI);
Value *New = new ICmpInst(SCI->getPredicate(), NPtr,
Constant::getNullValue(NPtr->getType()),
SCI->getName(), SCI);
SCI->replaceAllUsesWith(New);
SCI->eraseFromParent();
continue;
@ -959,7 +963,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
// }
Value *RunningOr = 0;
for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
Value *Cond = new SetCondInst(Instruction::SetEQ, FieldMallocs[i],
Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, FieldMallocs[i],
Constant::getNullValue(FieldMallocs[i]->getType()),
"isnull", MI);
if (!RunningOr)
@ -986,9 +990,9 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
// pointer, because some may be null while others are not.
for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
Value *GVVal = new LoadInst(FieldGlobals[i], "tmp", NullPtrBlock);
Value *Cmp = new SetCondInst(Instruction::SetNE, GVVal,
Constant::getNullValue(GVVal->getType()),
"tmp", NullPtrBlock);
Value *Cmp = new ICmpInst(ICmpInst::ICMP_NE, GVVal,
Constant::getNullValue(GVVal->getType()),
"tmp", NullPtrBlock);
BasicBlock *FreeBlock = new BasicBlock("free_it", OrigBB->getParent());
BasicBlock *NextBlock = new BasicBlock("next", OrigBB->getParent());
new BranchInst(FreeBlock, NextBlock, Cmp, NullPtrBlock);
@ -1710,6 +1714,10 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
InstResult = ConstantExpr::get(SI->getOpcode(),
getVal(Values, SI->getOperand(0)),
getVal(Values, SI->getOperand(1)));
} else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
InstResult = ConstantExpr::getCompare(CI->getPredicate(),
getVal(Values, CI->getOperand(0)),
getVal(Values, CI->getOperand(1)));
} else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
InstResult = ConstantExpr::getCast(CI->getOpcode(),
getVal(Values, CI->getOperand(0)),

View File

@ -887,8 +887,8 @@ struct StrLenOptimization : public LibCallOptimization {
// Does the call to strlen have exactly one use?
if (ci->hasOneUse())
// Is that single use a binary operator?
if (BinaryOperator* bop = dyn_cast<BinaryOperator>(ci->use_back()))
// Is that single use a icmp operator?
if (ICmpInst* bop = dyn_cast<ICmpInst>(ci->use_back()))
// Is it compared against a constant integer?
if (ConstantInt* CI = dyn_cast<ConstantInt>(bop->getOperand(1)))
{
@ -897,15 +897,15 @@ struct StrLenOptimization : public LibCallOptimization {
// If its compared against length 0 with == or !=
if (val == 0 &&
(bop->getOpcode() == Instruction::SetEQ ||
bop->getOpcode() == Instruction::SetNE))
(bop->getPredicate() == ICmpInst::ICMP_EQ ||
bop->getPredicate() == ICmpInst::ICMP_NE))
{
// strlen(x) != 0 -> *x != 0
// strlen(x) == 0 -> *x == 0
LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
BinaryOperator* rbop = BinaryOperator::create(bop->getOpcode(),
load, ConstantInt::get(Type::SByteTy,0),
bop->getName()+".strlen", ci);
ICmpInst* rbop = new ICmpInst(bop->getPredicate(), load,
ConstantInt::get(Type::SByteTy,0),
bop->getName()+".strlen", ci);
bop->replaceAllUsesWith(rbop);
bop->eraseFromParent();
ci->eraseFromParent();
@ -933,10 +933,11 @@ static bool IsOnlyUsedInEqualsZeroComparison(Instruction *I) {
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI) {
Instruction *User = cast<Instruction>(*UI);
if (User->getOpcode() == Instruction::SetNE ||
User->getOpcode() == Instruction::SetEQ) {
if (isa<Constant>(User->getOperand(1)) &&
cast<Constant>(User->getOperand(1))->isNullValue())
if (ICmpInst *IC = dyn_cast<ICmpInst>(User)) {
if ((IC->getPredicate() == ICmpInst::ICMP_NE ||
IC->getPredicate() == ICmpInst::ICMP_EQ) &&
isa<Constant>(IC->getOperand(1)) &&
cast<Constant>(IC->getOperand(1))->isNullValue())
continue;
} else if (CastInst *CI = dyn_cast<CastInst>(User))
if (CI->getType() == Type::BoolTy)
@ -1739,7 +1740,7 @@ public:
BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
ConstantInt::get(Type::UIntTy,0x30),
ci->getOperand(1)->getName()+".sub",ci);
SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
ICmpInst* setcond_inst = new ICmpInst(ICmpInst::ICMP_ULE,sub_inst,
ConstantInt::get(Type::UIntTy,9),
ci->getOperand(1)->getName()+".cmp",ci);
CastInst* c2 = new ZExtInst(setcond_inst, Type::IntTy,
@ -1764,12 +1765,9 @@ public:
virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
// isascii(c) -> (unsigned)c < 128
Value *V = CI->getOperand(1);
if (V->getType()->isSigned())
V = new BitCastInst(V, V->getType()->getUnsignedVersion(), V->getName(),
CI);
Value *Cmp = BinaryOperator::createSetLT(V, ConstantInt::get(V->getType(),
128),
V->getName()+".isascii", CI);
Value *Cmp = new ICmpInst(ICmpInst::ICMP_ULT, V,
ConstantInt::get(V->getType(), 128),
V->getName()+".isascii", CI);
if (Cmp->getType() != CI->getType())
Cmp = new BitCastInst(Cmp, CI->getType(), Cmp->getName(), CI);
CI->replaceAllUsesWith(Cmp);
@ -1872,9 +1870,9 @@ public:
"tmp", TheCall);
V2 = BinaryOperator::createAdd(V2, ConstantInt::get(Type::IntTy, 1),
"tmp", TheCall);
Value *Cond =
BinaryOperator::createSetEQ(V, Constant::getNullValue(V->getType()),
"tmp", TheCall);
Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, V,
Constant::getNullValue(V->getType()), "tmp",
TheCall);
V2 = new SelectInst(Cond, ConstantInt::get(Type::IntTy, 0), V2,
TheCall->getName(), TheCall);
TheCall->replaceAllUsesWith(V2);

View File

@ -197,9 +197,9 @@ void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) {
//decrement counter
LoadInst* l = new LoadInst(Counter, "counter", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, l,
ConstantInt::get(T, 0),
"countercc", t);
ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0),
"countercc", t);
Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
"counternew", t);
new StoreInst(nv, Counter, t);
@ -270,9 +270,9 @@ void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) {
//decrement counter
LoadInst* l = new LoadInst(AI, "counter", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, l,
ConstantInt::get(T, 0),
"countercc", t);
ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0),
"countercc", t);
Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
"counternew", t);
new StoreInst(nv, AI, t);
@ -305,9 +305,10 @@ void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
BinaryOperator::createAnd(c, ConstantInt::get(Type::ULongTy, rm),
"mrdcc", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, b,
ConstantInt::get(Type::ULongTy, 0),
"mrdccc", t);
ICmpInst *s = new ICmpInst(ICmpInst::ICMP_EQ, b,
ConstantInt::get(Type::ULongTy, 0),
"mrdccc", t);
t->setCondition(s);
}

View File

@ -393,9 +393,6 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
return false;
}
bool RPR::DoRaisePass(Function &F) {
bool Changed = false;
for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB)

View File

@ -45,36 +45,36 @@
#include <algorithm>
using namespace llvm;
STATISTIC(NumSetCCRemoved, "Number of setcc instruction eliminated");
STATISTIC(NumCmpRemoved, "Number of cmp instruction eliminated");
STATISTIC(NumOperandsCann, "Number of operands canonicalized");
STATISTIC(BranchRevectors, "Number of branches revectored");
namespace {
class ValueInfo;
class Relation {
Value *Val; // Relation to what value?
Instruction::BinaryOps Rel; // SetCC relation, or Add if no information
Value *Val; // Relation to what value?
unsigned Rel; // SetCC or ICmp relation, or Add if no information
public:
Relation(Value *V) : Val(V), Rel(Instruction::Add) {}
bool operator<(const Relation &R) const { return Val < R.Val; }
Value *getValue() const { return Val; }
Instruction::BinaryOps getRelation() const { return Rel; }
unsigned getRelation() const { return Rel; }
// contradicts - Return true if the relationship specified by the operand
// contradicts already known information.
//
bool contradicts(Instruction::BinaryOps Rel, const ValueInfo &VI) const;
bool contradicts(unsigned Rel, const ValueInfo &VI) const;
// incorporate - Incorporate information in the argument into this relation
// entry. This assumes that the information doesn't contradict itself. If
// any new information is gained, true is returned, otherwise false is
// returned to indicate that nothing was updated.
//
bool incorporate(Instruction::BinaryOps Rel, ValueInfo &VI);
bool incorporate(unsigned Rel, ValueInfo &VI);
// KnownResult - Whether or not this condition determines the result of a
// setcc in the program. False & True are intentionally 0 & 1 so we can
// convert to bool by casting after checking for unknown.
// setcc or icmp in the program. False & True are intentionally 0 & 1
// so we can convert to bool by casting after checking for unknown.
//
enum KnownResult { KnownFalse = 0, KnownTrue = 1, Unknown = 2 };
@ -82,7 +82,7 @@ namespace {
// the specified relationship is true or false, return that. If we cannot
// determine the result required, return Unknown.
//
KnownResult getImpliedResult(Instruction::BinaryOps Rel) const;
KnownResult getImpliedResult(unsigned Rel) const;
// print - Output this relation to the specified stream
void print(std::ostream &OS) const;
@ -269,19 +269,16 @@ namespace {
void PropagateBranchInfo(BranchInst *BI);
void PropagateSwitchInfo(SwitchInst *SI);
void PropagateEquality(Value *Op0, Value *Op1, RegionInfo &RI);
void PropagateRelation(Instruction::BinaryOps Opcode, Value *Op0,
void PropagateRelation(unsigned Opcode, Value *Op0,
Value *Op1, RegionInfo &RI);
void UpdateUsersOfValue(Value *V, RegionInfo &RI);
void IncorporateInstruction(Instruction *Inst, RegionInfo &RI);
void ComputeReplacements(RegionInfo &RI);
// getSetCCResult - Given a setcc instruction, determine if the result is
// getCmpResult - Given a icmp instruction, determine if the result is
// determined by facts we already know about the region under analysis.
// Return KnownTrue, KnownFalse, or Unknown based on what we can determine.
//
Relation::KnownResult getSetCCResult(SetCondInst *SC, const RegionInfo &RI);
// Return KnownTrue, KnownFalse, or UnKnown based on what we can determine.
Relation::KnownResult getCmpResult(CmpInst *ICI, const RegionInfo &RI);
bool SimplifyBasicBlock(BasicBlock &BB, const RegionInfo &RI);
bool SimplifyInstruction(Instruction *Inst, const RegionInfo &RI);
@ -448,12 +445,12 @@ bool CEE::ForwardCorrelatedEdgeDestination(TerminatorInst *TI, unsigned SuccNo,
return false;
// We can only forward the branch over the block if the block ends with a
// setcc we can determine the outcome for.
// cmp we can determine the outcome for.
//
// FIXME: we can make this more generic. Code below already handles more
// generic case.
SetCondInst *SCI = dyn_cast<SetCondInst>(BI->getCondition());
if (SCI == 0) return false;
if (!isa<CmpInst>(BI->getCondition()))
return false;
// Make a new RegionInfo structure so that we can simulate the effect of the
// PHI nodes in the block we are skipping over...
@ -472,10 +469,10 @@ bool CEE::ForwardCorrelatedEdgeDestination(TerminatorInst *TI, unsigned SuccNo,
int OpNum = PN->getBasicBlockIndex(BB);
assert(OpNum != -1 && "PHI doesn't have incoming edge for predecessor!?");
PropagateEquality(PN, PN->getIncomingValue(OpNum), NewRI);
} else if (SetCondInst *SCI = dyn_cast<SetCondInst>(I)) {
Relation::KnownResult Res = getSetCCResult(SCI, NewRI);
} else if (CmpInst *CI = dyn_cast<CmpInst>(I)) {
Relation::KnownResult Res = getCmpResult(CI, NewRI);
if (Res == Relation::Unknown) return false;
PropagateEquality(SCI, ConstantBool::get(Res), NewRI);
PropagateEquality(CI, ConstantBool::get(Res), NewRI);
} else {
assert(isa<BranchInst>(*I) && "Unexpected instruction type!");
}
@ -827,7 +824,8 @@ void CEE::PropagateEquality(Value *Op0, Value *Op1, RegionInfo &RI) {
Relation &KnownRelation = VI.getRelation(Op1);
// If we already know they're equal, don't reprocess...
if (KnownRelation.getRelation() == Instruction::SetEQ)
if (KnownRelation.getRelation() == FCmpInst::FCMP_OEQ ||
KnownRelation.getRelation() == ICmpInst::ICMP_EQ)
return;
// If this is boolean, check to see if one of the operands is a constant. If
@ -863,32 +861,55 @@ void CEE::PropagateEquality(Value *Op0, Value *Op1, RegionInfo &RI) {
PropagateEquality(BinaryOperator::getNotArgument(BOp),
ConstantBool::get(!CB->getValue()), RI);
// If we know the value of a SetCC instruction, propagate the information
// If we know the value of a FCmp instruction, propagate the information
// about the relation into this region as well.
//
if (SetCondInst *SCI = dyn_cast<SetCondInst>(Inst)) {
if (FCmpInst *FCI = dyn_cast<FCmpInst>(Inst)) {
if (CB->getValue()) { // If we know the condition is true...
// Propagate info about the LHS to the RHS & RHS to LHS
PropagateRelation(SCI->getOpcode(), SCI->getOperand(0),
SCI->getOperand(1), RI);
PropagateRelation(SCI->getSwappedCondition(),
SCI->getOperand(1), SCI->getOperand(0), RI);
PropagateRelation(FCI->getPredicate(), FCI->getOperand(0),
FCI->getOperand(1), RI);
PropagateRelation(FCI->getSwappedPredicate(),
FCI->getOperand(1), FCI->getOperand(0), RI);
} else { // If we know the condition is false...
// We know the opposite of the condition is true...
Instruction::BinaryOps C = SCI->getInverseCondition();
FCmpInst::Predicate C = FCI->getInversePredicate();
PropagateRelation(C, SCI->getOperand(0), SCI->getOperand(1), RI);
PropagateRelation(SetCondInst::getSwappedCondition(C),
SCI->getOperand(1), SCI->getOperand(0), RI);
PropagateRelation(C, FCI->getOperand(0), FCI->getOperand(1), RI);
PropagateRelation(FCmpInst::getSwappedPredicate(C),
FCI->getOperand(1), FCI->getOperand(0), RI);
}
}
// If we know the value of a ICmp instruction, propagate the information
// about the relation into this region as well.
//
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Inst)) {
if (CB->getValue()) { // If we know the condition is true...
// Propagate info about the LHS to the RHS & RHS to LHS
PropagateRelation(ICI->getPredicate(), ICI->getOperand(0),
ICI->getOperand(1), RI);
PropagateRelation(ICI->getSwappedPredicate(), ICI->getOperand(1),
ICI->getOperand(1), RI);
} else { // If we know the condition is false ...
// We know the opposite of the condition is true...
ICmpInst::Predicate C = ICI->getInversePredicate();
PropagateRelation(C, ICI->getOperand(0), ICI->getOperand(1), RI);
PropagateRelation(ICmpInst::getSwappedPredicate(C),
ICI->getOperand(1), ICI->getOperand(0), RI);
}
}
}
}
// Propagate information about Op0 to Op1 & visa versa
PropagateRelation(Instruction::SetEQ, Op0, Op1, RI);
PropagateRelation(Instruction::SetEQ, Op1, Op0, RI);
PropagateRelation(ICmpInst::ICMP_EQ, Op0, Op1, RI);
PropagateRelation(ICmpInst::ICMP_EQ, Op1, Op0, RI);
PropagateRelation(FCmpInst::FCMP_OEQ, Op0, Op1, RI);
PropagateRelation(FCmpInst::FCMP_OEQ, Op1, Op0, RI);
}
@ -896,7 +917,7 @@ void CEE::PropagateEquality(Value *Op0, Value *Op1, RegionInfo &RI) {
// blocks in the specified region. Propagate the information about Op0 and
// anything derived from it into this region.
//
void CEE::PropagateRelation(Instruction::BinaryOps Opcode, Value *Op0,
void CEE::PropagateRelation(unsigned Opcode, Value *Op0,
Value *Op1, RegionInfo &RI) {
assert(Op0->getType() == Op1->getType() && "Equal types expected!");
@ -921,7 +942,10 @@ void CEE::PropagateRelation(Instruction::BinaryOps Opcode, Value *Op0,
if (Op1R.contradicts(Opcode, VI)) {
Op1R.contradicts(Opcode, VI);
cerr << "Contradiction found for opcode: "
<< Instruction::getOpcodeName(Opcode) << "\n";
<< ((isa<ICmpInst>(Op0)||isa<ICmpInst>(Op1)) ?
Instruction::getOpcodeName(Instruction::ICmp) :
Instruction::getOpcodeName(Opcode))
<< "\n";
Op1R.print(*cerr.stream());
return;
}
@ -964,11 +988,11 @@ void CEE::UpdateUsersOfValue(Value *V, RegionInfo &RI) {
// value produced by this instruction
//
void CEE::IncorporateInstruction(Instruction *Inst, RegionInfo &RI) {
if (SetCondInst *SCI = dyn_cast<SetCondInst>(Inst)) {
if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
// See if we can figure out a result for this instruction...
Relation::KnownResult Result = getSetCCResult(SCI, RI);
Relation::KnownResult Result = getCmpResult(CI, RI);
if (Result != Relation::Unknown) {
PropagateEquality(SCI, ConstantBool::get(Result != 0), RI);
PropagateEquality(CI, ConstantBool::get(Result != 0), RI);
}
}
}
@ -1002,7 +1026,14 @@ void CEE::ComputeReplacements(RegionInfo &RI) {
// Loop over the relationships known about Op0.
const std::vector<Relation> &Relationships = VI.getRelationships();
for (unsigned i = 0, e = Relationships.size(); i != e; ++i)
if (Relationships[i].getRelation() == Instruction::SetEQ) {
if (Relationships[i].getRelation() == FCmpInst::FCMP_OEQ) {
unsigned R = getRank(Relationships[i].getValue());
if (R < MinRank) {
MinRank = R;
Replacement = Relationships[i].getValue();
}
}
else if (Relationships[i].getRelation() == ICmpInst::ICMP_EQ) {
unsigned R = getRank(Relationships[i].getValue());
if (R < MinRank) {
MinRank = R;
@ -1028,16 +1059,17 @@ bool CEE::SimplifyBasicBlock(BasicBlock &BB, const RegionInfo &RI) {
// Convert instruction arguments to canonical forms...
Changed |= SimplifyInstruction(Inst, RI);
if (SetCondInst *SCI = dyn_cast<SetCondInst>(Inst)) {
if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
// Try to simplify a setcc instruction based on inherited information
Relation::KnownResult Result = getSetCCResult(SCI, RI);
Relation::KnownResult Result = getCmpResult(CI, RI);
if (Result != Relation::Unknown) {
DOUT << "Replacing setcc with " << Result << " constant: " << *SCI;
DEBUG(cerr << "Replacing icmp with " << Result
<< " constant: " << *CI);
SCI->replaceAllUsesWith(ConstantBool::get((bool)Result));
CI->replaceAllUsesWith(ConstantBool::get((bool)Result));
// The instruction is now dead, remove it from the program.
SCI->getParent()->getInstList().erase(SCI);
++NumSetCCRemoved;
CI->getParent()->getInstList().erase(CI);
++NumCmpRemoved;
Changed = true;
}
}
@ -1069,33 +1101,35 @@ bool CEE::SimplifyInstruction(Instruction *I, const RegionInfo &RI) {
return Changed;
}
// getSetCCResult - Try to simplify a setcc instruction based on information
// inherited from a dominating setcc instruction. V is one of the operands to
// the setcc instruction, and VI is the set of information known about it. We
// getCmpResult - Try to simplify a cmp instruction based on information
// inherited from a dominating icmp instruction. V is one of the operands to
// the icmp instruction, and VI is the set of information known about it. We
// take two cases into consideration here. If the comparison is against a
// constant value, we can use the constant range to see if the comparison is
// possible to succeed. If it is not a comparison against a constant, we check
// to see if there is a known relationship between the two values. If so, we
// may be able to eliminate the check.
//
Relation::KnownResult CEE::getSetCCResult(SetCondInst *SCI,
const RegionInfo &RI) {
Value *Op0 = SCI->getOperand(0), *Op1 = SCI->getOperand(1);
Instruction::BinaryOps Opcode = SCI->getOpcode();
Relation::KnownResult CEE::getCmpResult(CmpInst *CI,
const RegionInfo &RI) {
Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
unsigned short predicate = CI->getPredicate();
if (isa<Constant>(Op0)) {
if (isa<Constant>(Op1)) {
if (Constant *Result = ConstantFoldInstruction(SCI)) {
// Wow, this is easy, directly eliminate the SetCondInst.
DOUT << "Replacing setcc with constant fold: " << *SCI;
if (Constant *Result = ConstantFoldInstruction(CI)) {
// Wow, this is easy, directly eliminate the ICmpInst.
DEBUG(cerr << "Replacing cmp with constant fold: " << *CI);
return cast<ConstantBool>(Result)->getValue()
? Relation::KnownTrue : Relation::KnownFalse;
}
} else {
// We want to swap this instruction so that operand #0 is the constant.
std::swap(Op0, Op1);
Opcode = SCI->getSwappedCondition();
if (isa<ICmpInst>(CI))
predicate = cast<ICmpInst>(CI)->getSwappedPredicate();
else
predicate = cast<FCmpInst>(CI)->getSwappedPredicate();
}
}
@ -1107,12 +1141,13 @@ Relation::KnownResult CEE::getSetCCResult(SetCondInst *SCI,
// At this point, we know that if we have a constant argument that it is in
// Op1. Check to see if we know anything about comparing value with a
// constant, and if we can use this info to fold the setcc.
// constant, and if we can use this info to fold the icmp.
//
if (ConstantIntegral *C = dyn_cast<ConstantIntegral>(Op1)) {
// Check to see if we already know the result of this comparison...
ConstantRange R = ConstantRange(Opcode, C);
ConstantRange Int = R.intersectWith(Op0VI->getBounds());
ConstantRange R = ConstantRange(predicate, C);
ConstantRange Int = R.intersectWith(Op0VI->getBounds(),
ICmpInst::isSignedPredicate(ICmpInst::Predicate(predicate)));
// If the intersection of the two ranges is empty, then the condition
// could never be true!
@ -1134,7 +1169,7 @@ Relation::KnownResult CEE::getSetCCResult(SetCondInst *SCI,
//
// Do we have value information about Op0 and a relation to Op1?
if (const Relation *Op2R = Op0VI->requestRelation(Op1))
Result = Op2R->getImpliedResult(Opcode);
Result = Op2R->getImpliedResult(predicate);
}
}
return Result;
@ -1147,7 +1182,7 @@ Relation::KnownResult CEE::getSetCCResult(SetCondInst *SCI,
// contradicts - Return true if the relationship specified by the operand
// contradicts already known information.
//
bool Relation::contradicts(Instruction::BinaryOps Op,
bool Relation::contradicts(unsigned Op,
const ValueInfo &VI) const {
assert (Op != Instruction::Add && "Invalid relation argument!");
@ -1155,24 +1190,48 @@ bool Relation::contradicts(Instruction::BinaryOps Op,
// does not contradict properties known about the bounds of the constant.
//
if (ConstantIntegral *C = dyn_cast<ConstantIntegral>(Val))
if (ConstantRange(Op, C).intersectWith(VI.getBounds()).isEmptySet())
return true;
if (Op >= ICmpInst::FIRST_ICMP_PREDICATE &&
Op <= ICmpInst::LAST_ICMP_PREDICATE)
if (ConstantRange(Op, C).intersectWith(VI.getBounds(),
ICmpInst::isSignedPredicate(ICmpInst::Predicate(Op))).isEmptySet())
return true;
switch (Rel) {
default: assert(0 && "Unknown Relationship code!");
case Instruction::Add: return false; // Nothing known, nothing contradicts
case Instruction::SetEQ:
return Op == Instruction::SetLT || Op == Instruction::SetGT ||
Op == Instruction::SetNE;
case Instruction::SetNE: return Op == Instruction::SetEQ;
case Instruction::SetLE: return Op == Instruction::SetGT;
case Instruction::SetGE: return Op == Instruction::SetLT;
case Instruction::SetLT:
return Op == Instruction::SetEQ || Op == Instruction::SetGT ||
Op == Instruction::SetGE;
case Instruction::SetGT:
return Op == Instruction::SetEQ || Op == Instruction::SetLT ||
Op == Instruction::SetLE;
case ICmpInst::ICMP_EQ:
return Op == ICmpInst::ICMP_ULT || Op == ICmpInst::ICMP_SLT ||
Op == ICmpInst::ICMP_UGT || Op == ICmpInst::ICMP_SGT ||
Op == ICmpInst::ICMP_NE;
case ICmpInst::ICMP_NE: return Op == ICmpInst::ICMP_EQ;
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE: return Op == ICmpInst::ICMP_UGT ||
Op == ICmpInst::ICMP_SGT;
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE: return Op == ICmpInst::ICMP_ULT ||
Op == ICmpInst::ICMP_SLT;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
return Op == ICmpInst::ICMP_EQ || Op == ICmpInst::ICMP_UGT ||
Op == ICmpInst::ICMP_SGT || Op == ICmpInst::ICMP_UGE ||
Op == ICmpInst::ICMP_SGE;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
return Op == ICmpInst::ICMP_EQ || Op == ICmpInst::ICMP_ULT ||
Op == ICmpInst::ICMP_SLT || Op == ICmpInst::ICMP_ULE ||
Op == ICmpInst::ICMP_SLE;
case FCmpInst::FCMP_OEQ:
return Op == FCmpInst::FCMP_OLT || Op == FCmpInst::FCMP_OGT ||
Op == FCmpInst::FCMP_ONE;
case FCmpInst::FCMP_ONE: return Op == FCmpInst::FCMP_OEQ;
case FCmpInst::FCMP_OLE: return Op == FCmpInst::FCMP_OGT;
case FCmpInst::FCMP_OGE: return Op == FCmpInst::FCMP_OLT;
case FCmpInst::FCMP_OLT:
return Op == FCmpInst::FCMP_OEQ || Op == FCmpInst::FCMP_OGT ||
Op == FCmpInst::FCMP_OGE;
case FCmpInst::FCMP_OGT:
return Op == FCmpInst::FCMP_OEQ || Op == FCmpInst::FCMP_OLT ||
Op == FCmpInst::FCMP_OLE;
}
}
@ -1181,7 +1240,7 @@ bool Relation::contradicts(Instruction::BinaryOps Op,
// new information is gained, true is returned, otherwise false is returned to
// indicate that nothing was updated.
//
bool Relation::incorporate(Instruction::BinaryOps Op, ValueInfo &VI) {
bool Relation::incorporate(unsigned Op, ValueInfo &VI) {
assert(!contradicts(Op, VI) &&
"Cannot incorporate contradictory information!");
@ -1189,30 +1248,64 @@ bool Relation::incorporate(Instruction::BinaryOps Op, ValueInfo &VI) {
// range that is possible for the value to have...
//
if (ConstantIntegral *C = dyn_cast<ConstantIntegral>(Val))
VI.getBounds() = ConstantRange(Op, C).intersectWith(VI.getBounds());
if (Op >= ICmpInst::FIRST_ICMP_PREDICATE &&
Op <= ICmpInst::LAST_ICMP_PREDICATE)
VI.getBounds() = ConstantRange(Op, C).intersectWith(VI.getBounds(),
ICmpInst::isSignedPredicate(ICmpInst::Predicate(Op)));
switch (Rel) {
default: assert(0 && "Unknown prior value!");
case Instruction::Add: Rel = Op; return true;
case Instruction::SetEQ: return false; // Nothing is more precise
case Instruction::SetNE: return false; // Nothing is more precise
case Instruction::SetLT: return false; // Nothing is more precise
case Instruction::SetGT: return false; // Nothing is more precise
case Instruction::SetLE:
if (Op == Instruction::SetEQ || Op == Instruction::SetLT) {
case ICmpInst::ICMP_EQ:
case ICmpInst::ICMP_NE:
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT: return false; // Nothing is more precise
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
if (Op == ICmpInst::ICMP_EQ || Op == ICmpInst::ICMP_ULT ||
Op == ICmpInst::ICMP_SLT) {
Rel = Op;
return true;
} else if (Op == Instruction::SetNE) {
Rel = Instruction::SetLT;
} else if (Op == ICmpInst::ICMP_NE) {
Rel = Rel == ICmpInst::ICMP_ULE ? ICmpInst::ICMP_ULT :
ICmpInst::ICMP_SLT;
return true;
}
return false;
case Instruction::SetGE: return Op == Instruction::SetLT;
if (Op == Instruction::SetEQ || Op == Instruction::SetGT) {
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
if (Op == ICmpInst::ICMP_EQ || ICmpInst::ICMP_UGT ||
Op == ICmpInst::ICMP_SGT) {
Rel = Op;
return true;
} else if (Op == Instruction::SetNE) {
Rel = Instruction::SetGT;
} else if (Op == ICmpInst::ICMP_NE) {
Rel = Rel == ICmpInst::ICMP_UGE ? ICmpInst::ICMP_UGT :
ICmpInst::ICMP_SGT;
return true;
}
return false;
case FCmpInst::FCMP_OEQ: return false; // Nothing is more precise
case FCmpInst::FCMP_ONE: return false; // Nothing is more precise
case FCmpInst::FCMP_OLT: return false; // Nothing is more precise
case FCmpInst::FCMP_OGT: return false; // Nothing is more precise
case FCmpInst::FCMP_OLE:
if (Op == FCmpInst::FCMP_OEQ || Op == FCmpInst::FCMP_OLT) {
Rel = Op;
return true;
} else if (Op == FCmpInst::FCMP_ONE) {
Rel = FCmpInst::FCMP_OLT;
return true;
}
return false;
case FCmpInst::FCMP_OGE:
return Op == FCmpInst::FCMP_OLT;
if (Op == FCmpInst::FCMP_OEQ || Op == FCmpInst::FCMP_OGT) {
Rel = Op;
return true;
} else if (Op == FCmpInst::FCMP_ONE) {
Rel = FCmpInst::FCMP_OGT;
return true;
}
return false;
@ -1224,28 +1317,67 @@ bool Relation::incorporate(Instruction::BinaryOps Op, ValueInfo &VI) {
// determine the result required, return Unknown.
//
Relation::KnownResult
Relation::getImpliedResult(Instruction::BinaryOps Op) const {
Relation::getImpliedResult(unsigned Op) const {
if (Rel == Op) return KnownTrue;
if (Rel == SetCondInst::getInverseCondition(Op)) return KnownFalse;
if (Op >= ICmpInst::FIRST_ICMP_PREDICATE &&
Op <= ICmpInst::LAST_ICMP_PREDICATE) {
if (Rel == unsigned(ICmpInst::getInversePredicate(ICmpInst::Predicate(Op))))
return KnownFalse;
} else if (Op <= FCmpInst::LAST_FCMP_PREDICATE) {
if (Rel == unsigned(FCmpInst::getInversePredicate(FCmpInst::Predicate(Op))))
return KnownFalse;
}
switch (Rel) {
default: assert(0 && "Unknown prior value!");
case Instruction::SetEQ:
if (Op == Instruction::SetLE || Op == Instruction::SetGE) return KnownTrue;
if (Op == Instruction::SetLT || Op == Instruction::SetGT) return KnownFalse;
case ICmpInst::ICMP_EQ:
if (Op == ICmpInst::ICMP_ULE || Op == ICmpInst::ICMP_SLE ||
Op == ICmpInst::ICMP_UGE || Op == ICmpInst::ICMP_SGE) return KnownTrue;
if (Op == ICmpInst::ICMP_ULT || Op == ICmpInst::ICMP_SLT ||
Op == ICmpInst::ICMP_UGT || Op == ICmpInst::ICMP_SGT) return KnownFalse;
break;
case Instruction::SetLT:
if (Op == Instruction::SetNE || Op == Instruction::SetLE) return KnownTrue;
if (Op == Instruction::SetEQ) return KnownFalse;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
if (Op == ICmpInst::ICMP_ULE || Op == ICmpInst::ICMP_SLE ||
Op == ICmpInst::ICMP_NE) return KnownTrue;
if (Op == ICmpInst::ICMP_EQ) return KnownFalse;
break;
case Instruction::SetGT:
if (Op == Instruction::SetNE || Op == Instruction::SetGE) return KnownTrue;
if (Op == Instruction::SetEQ) return KnownFalse;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
if (Op == ICmpInst::ICMP_UGE || Op == ICmpInst::ICMP_SGE ||
Op == ICmpInst::ICMP_NE) return KnownTrue;
if (Op == ICmpInst::ICMP_EQ) return KnownFalse;
break;
case Instruction::SetNE:
case Instruction::SetLE:
case Instruction::SetGE:
case Instruction::Add:
case FCmpInst::FCMP_OEQ:
if (Op == FCmpInst::FCMP_OLE || Op == FCmpInst::FCMP_OGE) return KnownTrue;
if (Op == FCmpInst::FCMP_OLT || Op == FCmpInst::FCMP_OGT) return KnownFalse;
break;
case FCmpInst::FCMP_OLT:
if (Op == FCmpInst::FCMP_ONE || Op == FCmpInst::FCMP_OLE) return KnownTrue;
if (Op == FCmpInst::FCMP_OEQ) return KnownFalse;
break;
case FCmpInst::FCMP_OGT:
if (Op == FCmpInst::FCMP_ONE || Op == FCmpInst::FCMP_OGE) return KnownTrue;
if (Op == FCmpInst::FCMP_OEQ) return KnownFalse;
break;
case ICmpInst::ICMP_NE:
case ICmpInst::ICMP_SLE:
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_FALSE:
case FCmpInst::FCMP_ORD:
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_UGT:
case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_ULT:
case FCmpInst::FCMP_ULE:
case FCmpInst::FCMP_UNE:
case FCmpInst::FCMP_TRUE:
break;
}
return Unknown;
@ -1298,12 +1430,30 @@ void Relation::print(std::ostream &OS) const {
OS << " is ";
switch (Rel) {
default: OS << "*UNKNOWN*"; break;
case Instruction::SetEQ: OS << "== "; break;
case Instruction::SetNE: OS << "!= "; break;
case Instruction::SetLT: OS << "< "; break;
case Instruction::SetGT: OS << "> "; break;
case Instruction::SetLE: OS << "<= "; break;
case Instruction::SetGE: OS << ">= "; break;
case ICmpInst::ICMP_EQ:
case FCmpInst::FCMP_ORD:
case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_OEQ: OS << "== "; break;
case ICmpInst::ICMP_NE:
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_UNE:
case FCmpInst::FCMP_ONE: OS << "!= "; break;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
case FCmpInst::FCMP_ULT:
case FCmpInst::FCMP_OLT: OS << "< "; break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
case FCmpInst::FCMP_UGT:
case FCmpInst::FCMP_OGT: OS << "> "; break;
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
case FCmpInst::FCMP_ULE:
case FCmpInst::FCMP_OLE: OS << "<= "; break;
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_OGE: OS << ">= "; break;
}
WriteAsOperand(OS, Val);

View File

@ -271,14 +271,14 @@ Instruction *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
Value *ExitCnt = RW.expandCodeFor(TripCount, Preheader->getTerminator(),
IndVar->getType());
// Insert a new setne or seteq instruction before the branch.
Instruction::BinaryOps Opcode;
// Insert a new icmp_ne or icmp_eq instruction before the branch.
ICmpInst::Predicate Opcode;
if (L->contains(BI->getSuccessor(0)))
Opcode = Instruction::SetNE;
Opcode = ICmpInst::ICMP_NE;
else
Opcode = Instruction::SetEQ;
Opcode = ICmpInst::ICMP_EQ;
Value *Cond = new SetCondInst(Opcode, IndVar, ExitCnt, "exitcond", BI);
Value *Cond = new ICmpInst(Opcode, IndVar, ExitCnt, "exitcond", BI);
BI->setCondition(Cond);
++NumLFTR;
Changed = true;

File diff suppressed because it is too large Load Diff

View File

@ -385,7 +385,7 @@ bool LICM::canSinkOrHoistInst(Instruction &I) {
// Otherwise these instructions are hoistable/sinkable
return isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CastInst>(I) ||
isa<SelectInst>(I) || isa<GetElementPtrInst>(I);
isa<SelectInst>(I) || isa<GetElementPtrInst>(I) || isa<CmpInst>(I);
}
/// isNotUsedInLoop - Return true if the only users of this instruction are

View File

@ -1191,9 +1191,6 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
// TODO: implement optzns here.
// Finally, get the terminating condition for the loop if possible. If we
// can, we want to change it to use a post-incremented version of its
// induction variable, to allow coalescing the live ranges for the IV into
@ -1203,10 +1200,10 @@ void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
BasicBlock *LatchBlock =
SomePHI->getIncomingBlock(SomePHI->getIncomingBlock(0) == Preheader);
BranchInst *TermBr = dyn_cast<BranchInst>(LatchBlock->getTerminator());
if (!TermBr || TermBr->isUnconditional() ||
!isa<SetCondInst>(TermBr->getCondition()))
if (!TermBr || TermBr->isUnconditional() ||
!isa<ICmpInst>(TermBr->getCondition()))
return;
SetCondInst *Cond = cast<SetCondInst>(TermBr->getCondition());
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
// Search IVUsesByStride to find Cond's IVUse if there is one.
IVStrideUse *CondUse = 0;
@ -1239,7 +1236,7 @@ void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
Cond->moveBefore(TermBr);
} else {
// Otherwise, clone the terminating condition and insert into the loopend.
Cond = cast<SetCondInst>(Cond->clone());
Cond = cast<ICmpInst>(Cond->clone());
Cond->setName(L->getHeader()->getName() + ".termcond");
LatchBlock->getInstList().insert(TermBr, Cond);
@ -1360,9 +1357,9 @@ void LoopStrengthReduce::runOnLoop(Loop *L) {
// FIXME: this needs to eliminate an induction variable even if it's being
// compared against some value to decide loop termination.
if (PN->hasOneUse()) {
BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN->use_begin()));
if (BO && BO->hasOneUse()) {
if (PN == *(BO->use_begin())) {
Instruction *BO = dyn_cast<Instruction>(*PN->use_begin());
if (BO && (isa<BinaryOperator>(BO) || isa<CmpInst>(BO))) {
if (BO->hasOneUse() && PN == *(BO->use_begin())) {
DeadInsts.insert(BO);
// Break the cycle, then delete the PHI.
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));

View File

@ -486,12 +486,11 @@ static void EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
// Insert a conditional branch on LIC to the two preheaders. The original
// code is the true version and the new code is the false version.
Value *BranchVal = LIC;
if (!isa<ConstantBool>(Val)) {
BranchVal = BinaryOperator::createSetEQ(LIC, Val, "tmp", InsertPt);
} else if (Val != ConstantBool::getTrue()) {
if (!isa<ConstantBool>(Val))
BranchVal = new ICmpInst(ICmpInst::ICMP_EQ, LIC, Val, "tmp", InsertPt);
else if (Val != ConstantBool::getTrue())
// We want to enter the new loop when the condition is true.
std::swap(TrueDest, FalseDest);
}
// Insert the new branch.
new BranchInst(TrueDest, FalseDest, BranchVal, InsertPt);

View File

@ -54,6 +54,10 @@ public:
/// @param BO the binary operator to convert
void visitBinaryOperator(BinaryOperator& BO);
/// @brief Lowers packed icmp operations.
/// @param CI the icmp operator to convert
void visitICmpInst(ICmpInst& IC);
/// @brief Lowers packed select instructions.
/// @param SELI the select operator to convert
void visitSelectInst(SelectInst& SELI);
@ -269,6 +273,35 @@ void LowerPacked::visitBinaryOperator(BinaryOperator& BO)
}
}
void LowerPacked::visitICmpInst(ICmpInst& IC)
{
// Make sure both operands are PackedTypes
if (isa<PackedType>(IC.getOperand(0)->getType())) {
std::vector<Value*>& op0Vals = getValues(IC.getOperand(0));
std::vector<Value*>& op1Vals = getValues(IC.getOperand(1));
std::vector<Value*> result;
assert((op0Vals.size() == op1Vals.size()) &&
"The two packed operand to scalar maps must be equal in size.");
result.reserve(op0Vals.size());
// generate the new binary op and save the result
for (unsigned i = 0; i != op0Vals.size(); ++i) {
result.push_back(CmpInst::create(IC.getOpcode(),
IC.getPredicate(),
op0Vals[i],
op1Vals[i],
IC.getName() +
"." + utostr(i),
&IC));
}
setValues(&IC,result);
Changed = true;
instrsToRemove.push_back(&IC);
}
}
void LowerPacked::visitStoreInst(StoreInst& SI)
{
if (const PackedType* PKT =
@ -376,12 +409,12 @@ void LowerPacked::visitInsertElementInst(InsertElementInst& IE)
}
} else {
for (unsigned i = 0; i != Vals.size(); ++i) {
SetCondInst *setcc =
new SetCondInst(Instruction::SetEQ, Idx,
ConstantInt::get(Type::UIntTy, i),
"setcc", &IE);
ICmpInst *icmp =
new ICmpInst(ICmpInst::ICMP_EQ, Idx,
ConstantInt::get(Type::UIntTy, i),
"icmp", &IE);
SelectInst *select =
new SelectInst(setcc, Elt, Vals[i], "select", &IE);
new SelectInst(icmp, Elt, Vals[i], "select", &IE);
result.push_back(select);
}
}

View File

@ -559,7 +559,8 @@ namespace {
void addToWorklist(Instruction *I) {
//DOUT << "addToWorklist: " << *I << "\n";
if (!isa<BinaryOperator>(I) && !isa<SelectInst>(I)) return;
if (!isa<BinaryOperator>(I) && !isa<SelectInst>(I) && !isa<CmpInst>(I))
return;
const Type *Ty = I->getType();
if (Ty == Type::VoidTy || Ty->isFPOrFPVector()) return;
@ -855,102 +856,6 @@ namespace {
addEqual(BO, ConstantExpr::get(BO->getOpcode(), CI1, CI2));
switch (BO->getOpcode()) {
case Instruction::SetEQ:
// "seteq int %a, %b" EQ true then %a EQ %b
// "seteq int %a, %b" EQ false then %a NE %b
if (Canonical == ConstantBool::getTrue())
addEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addNotEqual(Op0, Op1);
// %a EQ %b then "seteq int %a, %b" EQ true
// %a NE %b then "seteq int %a, %b" EQ false
if (isEqual(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
else if (isNotEqual(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
break;
case Instruction::SetNE:
// "setne int %a, %b" EQ true then %a NE %b
// "setne int %a, %b" EQ false then %a EQ %b
if (Canonical == ConstantBool::getTrue())
addNotEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addEqual(Op0, Op1);
// %a EQ %b then "setne int %a, %b" EQ false
// %a NE %b then "setne int %a, %b" EQ true
if (isEqual(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
else if (isNotEqual(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
break;
case Instruction::SetLT:
// "setlt int %a, %b" EQ true then %a LT %b
// "setlt int %a, %b" EQ false then %b LE %a
if (Canonical == ConstantBool::getTrue())
addLess(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op1, Op0);
// %a LT %b then "setlt int %a, %b" EQ true
// %a GE %b then "setlt int %a, %b" EQ false
if (isLess(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
else if (isGreaterEqual(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
break;
case Instruction::SetLE:
// "setle int %a, %b" EQ true then %a LE %b
// "setle int %a, %b" EQ false then %b LT %a
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLess(Op1, Op0);
// %a LE %b then "setle int %a, %b" EQ true
// %a GT %b then "setle int %a, %b" EQ false
if (isLessEqual(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
else if (isGreater(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
break;
case Instruction::SetGT:
// "setgt int %a, %b" EQ true then %b LT %a
// "setgt int %a, %b" EQ false then %a LE %b
if (Canonical == ConstantBool::getTrue())
addLess(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op0, Op1);
// %a GT %b then "setgt int %a, %b" EQ true
// %a LE %b then "setgt int %a, %b" EQ false
if (isGreater(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
else if (isLessEqual(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
break;
case Instruction::SetGE:
// "setge int %a, %b" EQ true then %b LE %a
// "setge int %a, %b" EQ false then %a LT %b
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLess(Op0, Op1);
// %a GE %b then "setge int %a, %b" EQ true
// %a LT %b then "setlt int %a, %b" EQ false
if (isGreaterEqual(Op0, Op1))
addEqual(BO, ConstantBool::getTrue());
else if (isLess(Op0, Op1))
addEqual(BO, ConstantBool::getFalse());
break;
case Instruction::And: {
// "and int %a, %b" EQ -1 then %a EQ -1 and %b EQ -1
// "and bool %a, %b" EQ true then %a EQ true and %b EQ true
@ -1030,6 +935,250 @@ namespace {
break;
}
}
} else if (FCmpInst *CI = dyn_cast<FCmpInst>(I)) {
Value *Op0 = cIG.canonicalize(CI->getOperand(0)),
*Op1 = cIG.canonicalize(CI->getOperand(1));
ConstantFP *CI1 = dyn_cast<ConstantFP>(Op0),
*CI2 = dyn_cast<ConstantFP>(Op1);
if (CI1 && CI2)
addEqual(CI, ConstantExpr::getFCmp(CI->getPredicate(), CI1, CI2));
switch (CI->getPredicate()) {
case FCmpInst::FCMP_OEQ:
case FCmpInst::FCMP_UEQ:
// "eq int %a, %b" EQ true then %a EQ %b
// "eq int %a, %b" EQ false then %a NE %b
if (Canonical == ConstantBool::getTrue())
addEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addNotEqual(Op0, Op1);
// %a EQ %b then "eq int %a, %b" EQ true
// %a NE %b then "eq int %a, %b" EQ false
if (isEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isNotEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case FCmpInst::FCMP_ONE:
case FCmpInst::FCMP_UNE:
// "ne int %a, %b" EQ true then %a NE %b
// "ne int %a, %b" EQ false then %a EQ %b
if (Canonical == ConstantBool::getTrue())
addNotEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addEqual(Op0, Op1);
// %a EQ %b then "ne int %a, %b" EQ false
// %a NE %b then "ne int %a, %b" EQ true
if (isEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
else if (isNotEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
break;
case FCmpInst::FCMP_ULT:
case FCmpInst::FCMP_OLT:
// "lt int %a, %b" EQ true then %a LT %b
// "lt int %a, %b" EQ false then %b LE %a
if (Canonical == ConstantBool::getTrue())
addLess(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op1, Op0);
// %a LT %b then "lt int %a, %b" EQ true
// %a GE %b then "lt int %a, %b" EQ false
if (isLess(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isGreaterEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case FCmpInst::FCMP_ULE:
case FCmpInst::FCMP_OLE:
// "le int %a, %b" EQ true then %a LE %b
// "le int %a, %b" EQ false then %b LT %a
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLess(Op1, Op0);
// %a LE %b then "le int %a, %b" EQ true
// %a GT %b then "le int %a, %b" EQ false
if (isLessEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isGreater(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case FCmpInst::FCMP_UGT:
case FCmpInst::FCMP_OGT:
// "gt int %a, %b" EQ true then %b LT %a
// "gt int %a, %b" EQ false then %a LE %b
if (Canonical == ConstantBool::getTrue())
addLess(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op0, Op1);
// %a GT %b then "gt int %a, %b" EQ true
// %a LE %b then "gt int %a, %b" EQ false
if (isGreater(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isLessEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_OGE:
// "ge int %a, %b" EQ true then %b LE %a
// "ge int %a, %b" EQ false then %a LT %b
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLess(Op0, Op1);
// %a GE %b then "ge int %a, %b" EQ true
// %a LT %b then "lt int %a, %b" EQ false
if (isGreaterEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isLess(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
default:
break;
}
// "%x = add int %y, %z" and %x EQ %y then %z EQ 0
// "%x = mul int %y, %z" and %x EQ %y then %z EQ 1
// 1. Repeat all of the above, with order of operands reversed.
// "%x = fdiv float %y, %z" and %x EQ %y then %z EQ 1
Value *Known = Op0, *Unknown = Op1;
if (Known != BO) std::swap(Known, Unknown);
} else if (ICmpInst *CI = dyn_cast<ICmpInst>(I)) {
Value *Op0 = cIG.canonicalize(CI->getOperand(0)),
*Op1 = cIG.canonicalize(CI->getOperand(1));
ConstantIntegral *CI1 = dyn_cast<ConstantIntegral>(Op0),
*CI2 = dyn_cast<ConstantIntegral>(Op1);
if (CI1 && CI2)
addEqual(CI, ConstantExpr::getICmp(CI->getPredicate(), CI1, CI2));
switch (CI->getPredicate()) {
case ICmpInst::ICMP_EQ:
// "eq int %a, %b" EQ true then %a EQ %b
// "eq int %a, %b" EQ false then %a NE %b
if (Canonical == ConstantBool::getTrue())
addEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addNotEqual(Op0, Op1);
// %a EQ %b then "eq int %a, %b" EQ true
// %a NE %b then "eq int %a, %b" EQ false
if (isEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isNotEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case ICmpInst::ICMP_NE:
// "ne int %a, %b" EQ true then %a NE %b
// "ne int %a, %b" EQ false then %a EQ %b
if (Canonical == ConstantBool::getTrue())
addNotEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addEqual(Op0, Op1);
// %a EQ %b then "ne int %a, %b" EQ false
// %a NE %b then "ne int %a, %b" EQ true
if (isEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
else if (isNotEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
break;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
// "lt int %a, %b" EQ true then %a LT %b
// "lt int %a, %b" EQ false then %b LE %a
if (Canonical == ConstantBool::getTrue())
addLess(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op1, Op0);
// %a LT %b then "lt int %a, %b" EQ true
// %a GE %b then "lt int %a, %b" EQ false
if (isLess(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isGreaterEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
// "le int %a, %b" EQ true then %a LE %b
// "le int %a, %b" EQ false then %b LT %a
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op0, Op1);
else if (Canonical == ConstantBool::getFalse())
addLess(Op1, Op0);
// %a LE %b then "le int %a, %b" EQ true
// %a GT %b then "le int %a, %b" EQ false
if (isLessEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isGreater(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
// "gt int %a, %b" EQ true then %b LT %a
// "gt int %a, %b" EQ false then %a LE %b
if (Canonical == ConstantBool::getTrue())
addLess(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLessEqual(Op0, Op1);
// %a GT %b then "gt int %a, %b" EQ true
// %a LE %b then "gt int %a, %b" EQ false
if (isGreater(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isLessEqual(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
// "ge int %a, %b" EQ true then %b LE %a
// "ge int %a, %b" EQ false then %a LT %b
if (Canonical == ConstantBool::getTrue())
addLessEqual(Op1, Op0);
else if (Canonical == ConstantBool::getFalse())
addLess(Op0, Op1);
// %a GE %b then "ge int %a, %b" EQ true
// %a LT %b then "lt int %a, %b" EQ false
if (isGreaterEqual(Op0, Op1))
addEqual(CI, ConstantBool::getTrue());
else if (isLess(Op0, Op1))
addEqual(CI, ConstantBool::getFalse());
break;
default:
break;
}
// "%x = add int %y, %z" and %x EQ %y then %z EQ 0
// "%x = mul int %y, %z" and %x EQ %y then %z EQ 1
// 1. Repeat all of the above, with order of operands reversed.
// "%x = fdiv float %y, %z" and %x EQ %y then %z EQ 1
Value *Known = Op0, *Unknown = Op1;
if (Known != BO) std::swap(Known, Unknown);
} else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
// Given: "%a = select bool %x, int %b, int %c"
// %a EQ %b then %x EQ true
@ -1108,6 +1257,7 @@ namespace {
void visitStoreInst(StoreInst &SI);
void visitBinaryOperator(BinaryOperator &BO);
void visitCmpInst(CmpInst &CI) {}
};
// Used by terminator instructions to proceed from the current basic

View File

@ -95,10 +95,11 @@ namespace {
FunctionPass *llvm::createReassociatePass() { return new Reassociate(); }
void Reassociate::RemoveDeadBinaryOp(Value *V) {
BinaryOperator *BOp = dyn_cast<BinaryOperator>(V);
if (!BOp || !BOp->use_empty()) return;
Instruction *Op = dyn_cast<Instruction>(V);
if (!Op || !isa<BinaryOperator>(Op) || !isa<CmpInst>(Op) || !Op->use_empty())
return;
Value *LHS = BOp->getOperand(0), *RHS = BOp->getOperand(1);
Value *LHS = Op->getOperand(0), *RHS = Op->getOperand(1);
RemoveDeadBinaryOp(LHS);
RemoveDeadBinaryOp(RHS);
}
@ -755,7 +756,7 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
}
// Reject cases where it is pointless to do this.
if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
isa<PackedType>(BI->getType()))
continue; // Floating point ops are not associative.

View File

@ -373,6 +373,7 @@ private:
void visitCastInst(CastInst &I);
void visitSelectInst(SelectInst &I);
void visitBinaryOperator(Instruction &I);
void visitCmpInst(CmpInst &I);
void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
void visitExtractElementInst(ExtractElementInst &I);
void visitInsertElementInst(InsertElementInst &I);
@ -796,6 +797,93 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
}
}
// Handle ICmpInst instruction...
void SCCPSolver::visitCmpInst(CmpInst &I) {
LatticeVal &IV = ValueState[&I];
if (IV.isOverdefined()) return;
LatticeVal &V1State = getValueState(I.getOperand(0));
LatticeVal &V2State = getValueState(I.getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
// If both operands are PHI nodes, it is possible that this instruction has
// a constant value, despite the fact that the PHI node doesn't. Check for
// this condition now.
if (PHINode *PN1 = dyn_cast<PHINode>(I.getOperand(0)))
if (PHINode *PN2 = dyn_cast<PHINode>(I.getOperand(1)))
if (PN1->getParent() == PN2->getParent()) {
// Since the two PHI nodes are in the same basic block, they must have
// entries for the same predecessors. Walk the predecessor list, and
// if all of the incoming values are constants, and the result of
// evaluating this expression with all incoming value pairs is the
// same, then this expression is a constant even though the PHI node
// is not a constant!
LatticeVal Result;
for (unsigned i = 0, e = PN1->getNumIncomingValues(); i != e; ++i) {
LatticeVal &In1 = getValueState(PN1->getIncomingValue(i));
BasicBlock *InBlock = PN1->getIncomingBlock(i);
LatticeVal &In2 =
getValueState(PN2->getIncomingValueForBlock(InBlock));
if (In1.isOverdefined() || In2.isOverdefined()) {
Result.markOverdefined();
break; // Cannot fold this operation over the PHI nodes!
} else if (In1.isConstant() && In2.isConstant()) {
Constant *V = ConstantExpr::getCompare(I.getPredicate(),
In1.getConstant(),
In2.getConstant());
if (Result.isUndefined())
Result.markConstant(V);
else if (Result.isConstant() && Result.getConstant() != V) {
Result.markOverdefined();
break;
}
}
}
// If we found a constant value here, then we know the instruction is
// constant despite the fact that the PHI nodes are overdefined.
if (Result.isConstant()) {
markConstant(IV, &I, Result.getConstant());
// Remember that this instruction is virtually using the PHI node
// operands.
UsersOfOverdefinedPHIs.insert(std::make_pair(PN1, &I));
UsersOfOverdefinedPHIs.insert(std::make_pair(PN2, &I));
return;
} else if (Result.isUndefined()) {
return;
}
// Okay, this really is overdefined now. Since we might have
// speculatively thought that this was not overdefined before, and
// added ourselves to the UsersOfOverdefinedPHIs list for the PHIs,
// make sure to clean out any entries that we put there, for
// efficiency.
std::multimap<PHINode*, Instruction*>::iterator It, E;
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN1);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
tie(It, E) = UsersOfOverdefinedPHIs.equal_range(PN2);
while (It != E) {
if (It->second == &I) {
UsersOfOverdefinedPHIs.erase(It++);
} else
++It;
}
}
markOverdefined(IV, &I);
} else if (V1State.isConstant() && V2State.isConstant()) {
markConstant(IV, &I, ConstantExpr::getCompare(I.getPredicate(),
V1State.getConstant(),
V2State.getConstant()));
}
}
void SCCPSolver::visitExtractElementInst(ExtractElementInst &I) {
// FIXME : SCCP does not handle vectors properly.
markOverdefined(&I);

View File

@ -394,9 +394,9 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) {
assert(NumElements == 2 && "Unhandled case!");
// All users of the GEP must be loads. At each use of the GEP, insert
// two loads of the appropriate indexed GEP and select between them.
Value *IsOne = BinaryOperator::createSetNE(I.getOperand(),
Value *IsOne = new ICmpInst(ICmpInst::ICMP_NE, I.getOperand(),
Constant::getNullValue(I.getOperand()->getType()),
"isone", GEPI);
"isone", GEPI);
// Insert the new GEP instructions, which are properly indexed.
std::vector<Value*> Indices(GEPI->op_begin()+1, GEPI->op_end());
Indices[1] = Constant::getNullValue(Type::IntTy);

View File

@ -278,7 +278,15 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB) {
/// mapping its operands through ValueMap if they are available.
Constant *PruningFunctionCloner::
ConstantFoldMappedInstruction(const Instruction *I) {
if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
if (isa<CmpInst>(I)) {
if (Constant *Op0 = dyn_cast_or_null<Constant>(MapValue(I->getOperand(0),
ValueMap)))
if (Constant *Op1 = dyn_cast_or_null<Constant>(MapValue(I->getOperand(1),
ValueMap)))
return ConstantExpr::getCompare(cast<CmpInst>(I)->getPredicate(), Op0,
Op1);
return 0;
} else if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
if (Constant *Op0 = dyn_cast_or_null<Constant>(MapValue(I->getOperand(0),
ValueMap)))
if (Constant *Op1 = dyn_cast_or_null<Constant>(MapValue(I->getOperand(1),
@ -295,7 +303,7 @@ ConstantFoldMappedInstruction(const Instruction *I) {
else
return 0; // All operands not constant!
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops);
return ConstantFoldInstOperands(I, Ops);
}
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,

View File

@ -71,6 +71,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
case 2:
Op1 = dyn_cast<Constant>(I->getOperand(1));
if (Op1 == 0) return 0; // Not a constant?, can't fold
/* FALL THROUGH */
case 1:
Op0 = dyn_cast<Constant>(I->getOperand(0));
if (Op0 == 0) return 0; // Not a constant?, can't fold
@ -79,13 +80,14 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
}
if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
if (Constant *Op0 = dyn_cast<Constant>(I->getOperand(0)))
if (Constant *Op1 = dyn_cast<Constant>(I->getOperand(1)))
return ConstantExpr::get(I->getOpcode(), Op0, Op1);
return 0; // Operands not constants.
return ConstantExpr::get(I->getOpcode(), Op0, Op1);
} else if (isa<ICmpInst>(I)) {
return ConstantExpr::getICmp(cast<ICmpInst>(I)->getPredicate(), Op0, Op1);
} else if (isa<FCmpInst>(I)) {
return ConstantExpr::getFCmp(cast<FCmpInst>(I)->getPredicate(), Op0, Op1);
}
// Scan the operand list, checking to see if the are all constants, if so,
// Scan the operand list, checking to see if they are all constants, if so,
// hand off to ConstantFoldInstOperands.
std::vector<Constant*> Ops;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
@ -94,7 +96,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
else
return 0; // All operands not constant!
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops);
return ConstantFoldInstOperands(I, Ops);
}
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@ -103,9 +105,13 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
/// attempting to fold instructions like loads and stores, which have no
/// constant expression form.
///
Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
Constant *llvm::ConstantFoldInstOperands(const Instruction* I,
const std::vector<Constant*> &Ops) {
if (Opc >= Instruction::BinaryOpsBegin && Opc < Instruction::BinaryOpsEnd)
unsigned Opc = I->getOpcode();
const Type *DestTy = I->getType();
// Handle easy binops first
if (isa<BinaryOperator>(I))
return ConstantExpr::get(Opc, Ops[0], Ops[1]);
switch (Opc) {
@ -118,6 +124,10 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
}
}
return 0;
case Instruction::ICmp:
case Instruction::FCmp:
return ConstantExpr::getCompare(cast<CmpInst>(I)->getPredicate(), Ops[0],
Ops[1]);
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@ -257,8 +267,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
} else if (SI->getNumSuccessors() == 2) {
// Otherwise, we can fold this switch into a conditional branch
// instruction if it has only one non-default destination.
Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
SI->getSuccessorValue(1), "cond", SI);
Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, SI->getCondition(),
SI->getSuccessorValue(1), "cond", SI);
// Insert the new branch...
new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

View File

@ -517,9 +517,9 @@ bool LowerInvoke::insertExpensiveEHSupport(Function &F) {
EntryBB->getTerminator());
// Compare the return value to zero.
Value *IsNormal = BinaryOperator::createSetEQ(SJRet,
Constant::getNullValue(SJRet->getType()),
"notunwind", EntryBB->getTerminator());
Value *IsNormal = new ICmpInst(ICmpInst::ICMP_EQ, SJRet,
Constant::getNullValue(SJRet->getType()),
"notunwind", EntryBB->getTerminator());
// Nuke the uncond branch.
EntryBB->getTerminator()->eraseFromParent();
@ -551,9 +551,9 @@ bool LowerInvoke::insertExpensiveEHSupport(Function &F) {
}
// Load the JBList, if it's null, then there was no catch!
Value *NotNull = BinaryOperator::createSetNE(BufPtr,
Constant::getNullValue(BufPtr->getType()),
"notnull", UnwindHandler);
Value *NotNull = new ICmpInst(ICmpInst::ICMP_NE, BufPtr,
Constant::getNullValue(BufPtr->getType()),
"notnull", UnwindHandler);
new BranchInst(UnwindBlock, TermBlock, NotNull, UnwindHandler);
// Create the block to do the longjmp.

View File

@ -143,8 +143,7 @@ BasicBlock* LowerSwitch::switchConvert(CaseItr Begin, CaseItr End,
BasicBlock* NewNode = new BasicBlock("NodeBlock");
F->getBasicBlockList().insert(OrigBlock->getNext(), NewNode);
SetCondInst* Comp = new SetCondInst(Instruction::SetLT, Val, Pivot.first,
"Pivot");
ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_ULT, Val, Pivot.first, "Pivot");
NewNode->getInstList().push_back(Comp);
new BranchInst(LBranch, RBranch, Comp, NewNode);
return NewNode;
@ -165,8 +164,8 @@ BasicBlock* LowerSwitch::newLeafBlock(Case& Leaf, Value* Val,
F->getBasicBlockList().insert(OrigBlock->getNext(), NewLeaf);
// Make the seteq instruction...
SetCondInst* Comp = new SetCondInst(Instruction::SetEQ, Val,
Leaf.first, "SwitchLeaf");
ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_EQ, Val,
Leaf.first, "SwitchLeaf");
NewLeaf->getInstList().push_back(Comp);
// Make the conditional branch...

View File

@ -369,12 +369,8 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::SetEQ:
case Instruction::SetNE:
case Instruction::SetLT:
case Instruction::SetGT:
case Instruction::SetLE:
case Instruction::SetGE:
case Instruction::ICmp:
case Instruction::FCmp:
break; // These are all cheap and non-trapping instructions.
}
@ -390,12 +386,13 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
return true;
}
// GatherConstantSetEQs - Given a potentially 'or'd together collection of seteq
// instructions that compare a value against a constant, return the value being
// compared, and stick the constant into the Values vector.
// GatherConstantSetEQs - Given a potentially 'or'd together collection of
// icmp_eq instructions that compare a value against a constant, return the
// value being compared, and stick the constant into the Values vector.
static Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values){
if (Instruction *Inst = dyn_cast<Instruction>(V))
if (Inst->getOpcode() == Instruction::SetEQ) {
if (Inst->getOpcode() == Instruction::ICmp &&
cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_EQ) {
if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
Values.push_back(C);
return Inst->getOperand(0);
@ -417,7 +414,8 @@ static Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values){
// being compared, and stick the constant into the Values vector.
static Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values){
if (Instruction *Inst = dyn_cast<Instruction>(V))
if (Inst->getOpcode() == Instruction::SetNE) {
if (Inst->getOpcode() == Instruction::ICmp &&
cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_NE) {
if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
Values.push_back(C);
return Inst->getOperand(0);
@ -503,11 +501,11 @@ static Value *isValueEqualityComparison(TerminatorInst *TI) {
}
if (BranchInst *BI = dyn_cast<BranchInst>(TI))
if (BI->isConditional() && BI->getCondition()->hasOneUse())
if (SetCondInst *SCI = dyn_cast<SetCondInst>(BI->getCondition()))
if ((SCI->getOpcode() == Instruction::SetEQ ||
SCI->getOpcode() == Instruction::SetNE) &&
isa<ConstantInt>(SCI->getOperand(1)))
return SCI->getOperand(0);
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()))
if ((ICI->getPredicate() == ICmpInst::ICMP_EQ ||
ICI->getPredicate() == ICmpInst::ICMP_NE) &&
isa<ConstantInt>(ICI->getOperand(1)))
return ICI->getOperand(0);
return 0;
}
@ -525,11 +523,11 @@ GetValueEqualityComparisonCases(TerminatorInst *TI,
}
BranchInst *BI = cast<BranchInst>(TI);
SetCondInst *SCI = cast<SetCondInst>(BI->getCondition());
Cases.push_back(std::make_pair(cast<ConstantInt>(SCI->getOperand(1)),
BI->getSuccessor(SCI->getOpcode() ==
Instruction::SetNE)));
return BI->getSuccessor(SCI->getOpcode() == Instruction::SetEQ);
ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
Cases.push_back(std::make_pair(cast<ConstantInt>(ICI->getOperand(1)),
BI->getSuccessor(ICI->getPredicate() ==
ICmpInst::ICMP_NE)));
return BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_EQ);
}
@ -847,8 +845,8 @@ static bool HoistThenElseCodeToIf(BranchInst *BI) {
BasicBlock *BB2 = BI->getSuccessor(1); // The false destination
Instruction *I1 = BB1->begin(), *I2 = BB2->begin();
if (I1->getOpcode() != I2->getOpcode() || !I1->isIdenticalTo(I2) ||
isa<PHINode>(I1) || isa<InvokeInst>(I1))
if (I1->getOpcode() != I2->getOpcode() || isa<PHINode>(I1) ||
isa<InvokeInst>(I1) || !I1->isIdenticalTo(I2))
return false;
// If we get here, we can hoist at least one instruction.
@ -1443,8 +1441,9 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
// predecessor and use logical operations to pick the right destination.
BasicBlock *TrueDest = BI->getSuccessor(0);
BasicBlock *FalseDest = BI->getSuccessor(1);
if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(BI->getCondition()))
if (Cond->getParent() == BB && &BB->front() == Cond &&
if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition()))
if ((isa<CmpInst>(Cond) || isa<BinaryOperator>(Cond)) &&
Cond->getParent() == BB && &BB->front() == Cond &&
Cond->getNext() == BI && Cond->hasOneUse() &&
TrueDest != BB && FalseDest != BB)
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI!=E; ++PI)

File diff suppressed because it is too large Load Diff

View File

@ -45,8 +45,8 @@ namespace llvm {
const Constant *Mask);
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
const Constant *V2);
Constant *ConstantFoldCompare(unsigned opcode, Constant *C1, Constant *C2,
unsigned short predicate);
Constant *ConstantFoldCompareInstruction(unsigned short predicate,
Constant *C1, Constant *C2);
Constant *ConstantFoldGetElementPtr(const Constant *C,
const std::vector<Value*> &IdxList);
} // End llvm namespace

View File

@ -265,12 +265,6 @@ ConstantPacked::~ConstantPacked() {
delete [] OperandList;
}
static bool isSetCC(unsigned Opcode) {
return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
Opcode == Instruction::SetLT || Opcode == Instruction::SetGT ||
Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
}
// We declare several classes private to this file, so use an anonymous
// namespace
namespace {
@ -290,8 +284,7 @@ class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr {
Use Ops[2];
public:
BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
: ConstantExpr(isSetCC(Opcode) ? Type::BoolTy : C1->getType(),
Opcode, Ops, 2) {
: ConstantExpr(C1->getType(), Opcode, Ops, 2) {
Ops[0].init(C1, this);
Ops[1].init(C2, this);
}
@ -448,24 +441,6 @@ Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) {
Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
return get(Instruction::Xor, C1, C2);
}
Constant *ConstantExpr::getSetEQ(Constant *C1, Constant *C2) {
return get(Instruction::SetEQ, C1, C2);
}
Constant *ConstantExpr::getSetNE(Constant *C1, Constant *C2) {
return get(Instruction::SetNE, C1, C2);
}
Constant *ConstantExpr::getSetLT(Constant *C1, Constant *C2) {
return get(Instruction::SetLT, C1, C2);
}
Constant *ConstantExpr::getSetGT(Constant *C1, Constant *C2) {
return get(Instruction::SetGT, C1, C2);
}
Constant *ConstantExpr::getSetLE(Constant *C1, Constant *C2) {
return get(Instruction::SetLE, C1, C2);
}
Constant *ConstantExpr::getSetGE(Constant *C1, Constant *C2) {
return get(Instruction::SetGE, C1, C2);
}
unsigned ConstantExpr::getPredicate() const {
assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
return dynamic_cast<const CompareConstantExpr*>(this)->predicate;
@ -582,6 +557,9 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
std::vector<Constant*> ActualOps(Ops.begin()+1, Ops.end());
return ConstantExpr::getGetElementPtr(Ops[0], ActualOps);
}
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]);
@ -1657,8 +1635,7 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
assert(C1->getType() == C2->getType() &&
"Operand types in binary constant expression should match");
if (ReqTy == C1->getType() || (Instruction::isComparison(Opcode) &&
ReqTy == Type::BoolTy))
if (ReqTy == C1->getType() || ReqTy == Type::BoolTy)
if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases...
@ -1667,11 +1644,23 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
return ExprConstants->getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getCompareTy(unsigned Opcode, unsigned short predicate,
Constant *ConstantExpr::getCompareTy(unsigned short predicate,
Constant *C1, Constant *C2) {
if (Opcode == Instruction::ICmp)
return getICmp(predicate, C1, C2);
return getFCmp(predicate, C1, C2);
switch (predicate) {
default: assert(0 && "Invalid CmpInst predicate");
case FCmpInst::FCMP_FALSE: case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_ORD: case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UGT: case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_ULE: case FCmpInst::FCMP_UNE:
case FCmpInst::FCMP_TRUE:
return getFCmp(predicate, C1, C2);
case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_SLE:
return getICmp(predicate, C1, C2);
}
}
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
@ -1718,10 +1707,6 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
assert((C1->getType()->isIntegral() || isa<PackedType>(C1->getType())) &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::SetLT: case Instruction::SetGT: case Instruction::SetLE:
case Instruction::SetGE: case Instruction::SetEQ: case Instruction::SetNE:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
break;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@ -1737,10 +1722,10 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
return getTy(C1->getType(), Opcode, C1, C2);
}
Constant *ConstantExpr::getCompare(unsigned Opcode, unsigned short pred,
Constant *ConstantExpr::getCompare(unsigned short pred,
Constant *C1, Constant *C2) {
assert(C1->getType() == C2->getType() && "Op types should be identical!");
return getCompareTy(Opcode, pred, C1, C2);
return getCompareTy(pred, C1, C2);
}
Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
@ -1826,7 +1811,7 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
if (Constant *FC = ConstantFoldCompare(Instruction::ICmp, LHS, RHS, pred))
if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
@ -1843,7 +1828,7 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
if (Constant *FC = ConstantFoldCompare(Instruction::FCmp, LHS, RHS, pred))
if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness

View File

@ -106,14 +106,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Or : return "or";
case Xor: return "xor";
// SetCC operators...
case SetLE: return "setle";
case SetGE: return "setge";
case SetLT: return "setlt";
case SetGT: return "setgt";
case SetEQ: return "seteq";
case SetNE: return "setne";
// Memory instructions...
case Malloc: return "malloc";
case Free: return "free";
@ -176,11 +168,38 @@ bool Instruction::isIdenticalTo(Instruction *I) const {
return LI->isVolatile() == cast<LoadInst>(I)->isVolatile();
if (const StoreInst *SI = dyn_cast<StoreInst>(this))
return SI->isVolatile() == cast<StoreInst>(I)->isVolatile();
if (const CmpInst *CI = dyn_cast<CmpInst>(this))
return CI->getPredicate() == cast<CmpInst>(I)->getPredicate();
if (const CallInst *CI = dyn_cast<CallInst>(this))
return CI->isTailCall() == cast<CallInst>(I)->isTailCall();
return true;
}
// isSameOperationAs
bool Instruction::isSameOperationAs(Instruction *I) const {
if (getOpcode() != I->getOpcode() || getType() != I->getType() ||
getNumOperands() != I->getNumOperands())
return false;
// We have two instructions of identical opcode and #operands. Check to see
// if all operands are the same type
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (getOperand(i)->getType() != I->getOperand(i)->getType())
return false;
// Check special state that is a part of some instructions.
if (const LoadInst *LI = dyn_cast<LoadInst>(this))
return LI->isVolatile() == cast<LoadInst>(I)->isVolatile();
if (const StoreInst *SI = dyn_cast<StoreInst>(this))
return SI->isVolatile() == cast<StoreInst>(I)->isVolatile();
if (const CmpInst *CI = dyn_cast<CmpInst>(this))
return CI->getPredicate() == cast<CmpInst>(I)->getPredicate();
if (const CallInst *CI = dyn_cast<CallInst>(this))
return CI->isTailCall() == cast<CallInst>(I)->isTailCall();
return true;
}
/// isAssociative - Return true if the instruction is associative:
///
@ -213,31 +232,12 @@ bool Instruction::isCommutative(unsigned op) {
case And:
case Or:
case Xor:
case SetEQ:
case SetNE:
return true;
default:
return false;
}
}
/// isComparison - Return true if the instruction is a Set* instruction:
///
bool Instruction::isComparison(unsigned op) {
switch (op) {
case SetEQ:
case SetNE:
case SetLT:
case SetGT:
case SetLE:
case SetGE:
return true;
}
return false;
}
/// isTrappingInstruction - Return true if the instruction may trap.
///
bool Instruction::isTrapping(unsigned op) {

View File

@ -1068,9 +1068,6 @@ void BinaryOperator::init(BinaryOps iType)
cast<PackedType>(getType())->getElementType()->isIntegral())) &&
"Tried to create a logical operation on a non-integral type!");
break;
case SetLT: case SetGT: case SetLE:
case SetGE: case SetEQ: case SetNE:
assert(getType() == Type::BoolTy && "Setcc must return bool!");
default:
break;
}
@ -1082,15 +1079,7 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
Instruction *InsertBefore) {
assert(S1->getType() == S2->getType() &&
"Cannot create binary operator with two operands of differing type!");
switch (Op) {
// Binary comparison operators...
case SetLT: case SetGT: case SetLE:
case SetGE: case SetEQ: case SetNE:
return new SetCondInst(Op, S1, S2, Name, InsertBefore);
default:
return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
}
return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
}
BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
@ -1210,14 +1199,8 @@ const Value *BinaryOperator::getNotArgument(const Value *BinOp) {
// order dependent (SetLT f.e.) the opcode is changed.
//
bool BinaryOperator::swapOperands() {
if (isCommutative())
; // If the instruction is commutative, it is safe to swap the operands
else if (SetCondInst *SCI = dyn_cast<SetCondInst>(this))
/// FIXME: SetCC instructions shouldn't all have different opcodes.
setOpcode(SCI->getSwappedCondition());
else
return true; // Can't commute operands
if (!isCommutative())
return true; // Can't commute operands
std::swap(Ops[0], Ops[1]);
return false;
}
@ -1925,58 +1908,6 @@ BitCastInst::BitCastInst(
assert(checkCast(getOpcode(), S, Ty) && "Illegal BitCast");
}
//===----------------------------------------------------------------------===//
// SetCondInst Class
//===----------------------------------------------------------------------===//
SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2,
const std::string &Name, Instruction *InsertBefore)
: BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) {
// Make sure it's a valid type... getInverseCondition will assert out if not.
assert(getInverseCondition(Opcode));
}
SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2,
const std::string &Name, BasicBlock *InsertAtEnd)
: BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) {
// Make sure it's a valid type... getInverseCondition will assert out if not.
assert(getInverseCondition(Opcode));
}
// getInverseCondition - Return the inverse of the current condition opcode.
// For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
//
Instruction::BinaryOps SetCondInst::getInverseCondition(BinaryOps Opcode) {
switch (Opcode) {
default:
assert(0 && "Unknown setcc opcode!");
case SetEQ: return SetNE;
case SetNE: return SetEQ;
case SetGT: return SetLE;
case SetLT: return SetGE;
case SetGE: return SetLT;
case SetLE: return SetGT;
}
}
// getSwappedCondition - Return the condition opcode that would be the result
// of exchanging the two operands of the setcc instruction without changing
// the result produced. Thus, seteq->seteq, setle->setge, setlt->setgt, etc.
//
Instruction::BinaryOps SetCondInst::getSwappedCondition(BinaryOps Opcode) {
switch (Opcode) {
default: assert(0 && "Unknown setcc instruction!");
case SetEQ: case SetNE: return Opcode;
case SetGT: return SetLT;
case SetLT: return SetGT;
case SetGE: return SetLE;
case SetLE: return SetGE;
}
}
//===----------------------------------------------------------------------===//
// CmpInst Classes
//===----------------------------------------------------------------------===//
@ -2111,7 +2042,7 @@ ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) {
ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) {
switch (pred) {
default: assert(! "Unknown setcc instruction!");
default: assert(! "Unknown icmp predicate!");
case ICMP_EQ: case ICMP_NE:
return pred;
case ICMP_SGT: return ICMP_SLT;
@ -2125,6 +2056,30 @@ ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) {
}
}
ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) {
switch (pred) {
default: assert(! "Unknown icmp predicate!");
case ICMP_EQ: case ICMP_NE:
case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE:
return pred;
case ICMP_UGT: return ICMP_SGT;
case ICMP_ULT: return ICMP_SLT;
case ICMP_UGE: return ICMP_SGE;
case ICMP_ULE: return ICMP_SLE;
}
}
bool ICmpInst::isSignedPredicate(Predicate pred) {
switch (pred) {
default: assert(! "Unknown icmp predicate!");
case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE:
return true;
case ICMP_EQ: case ICMP_NE: case ICMP_UGT: case ICMP_ULT:
case ICMP_UGE: case ICMP_ULE:
return false;
}
}
FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) {
switch (pred) {
default:
@ -2150,7 +2105,7 @@ FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) {
FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) {
switch (pred) {
default: assert(!"Unknown setcc instruction!");
default: assert(!"Unknown fcmp predicate!");
case FCMP_FALSE: case FCMP_TRUE:
case FCMP_OEQ: case FCMP_ONE:
case FCMP_UEQ: case FCMP_UNE:
@ -2167,6 +2122,40 @@ FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) {
}
}
bool CmpInst::isUnsigned(unsigned short predicate) {
switch (predicate) {
default: return false;
case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_UGE: return true;
}
}
bool CmpInst::isSigned(unsigned short predicate){
switch (predicate) {
default: return false;
case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_SGE: return true;
}
}
bool CmpInst::isOrdered(unsigned short predicate) {
switch (predicate) {
default: return false;
case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLE:
case FCmpInst::FCMP_ORD: return true;
}
}
bool CmpInst::isUnordered(unsigned short predicate) {
switch (predicate) {
default: return false;
case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_UGT:
case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_ULE:
case FCmpInst::FCMP_UNO: return true;
}
}
//===----------------------------------------------------------------------===//
// SwitchInst Implementation
//===----------------------------------------------------------------------===//

View File

@ -230,7 +230,7 @@ void SymbolTable::insertEntry(const std::string &Name, const Type *VTy,
}
// insertEntry - Insert a value into the symbol table with the specified
// insertEntry - Insert a type into the symbol table with the specified
// name...
//
void SymbolTable::insert(const std::string& Name, const Type* T) {

View File

@ -719,10 +719,6 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
Assert1(B.getType() == B.getOperand(0)->getType(),
"Logical operators must have same type for operands and result!",
&B);
} else if (isa<SetCondInst>(B)) {
// Check that setcc instructions return bool
Assert1(B.getType() == Type::BoolTy,
"setcc instructions must return boolean values!", &B);
} else {
// Arithmetic operators only work on integer or fp values
Assert1(B.getType() == B.getOperand(0)->getType(),

View File

@ -721,7 +721,7 @@ StackerCompiler::handle_if( char* ifTrue, char* ifFalse )
LoadInst* cond = cast<LoadInst>( pop_integer(bb) );
// Compare the condition against 0
SetCondInst* cond_inst = new SetCondInst( Instruction::SetNE, cond,
ICmpInst* cond_inst = new ICmpInst( ICmpInst::ICMP_NE, cond,
ConstantInt::get( Type::LongTy, 0) );
bb->getInstList().push_back( cond_inst );
@ -735,7 +735,7 @@ StackerCompiler::handle_if( char* ifTrue, char* ifFalse )
BasicBlock* false_bb = 0;
if ( ifFalse ) false_bb = new BasicBlock((echo?"else":""));
// Create a branch on the SetCond
// Create a branch on the ICmp
BranchInst* br_inst = new BranchInst( true_bb,
( ifFalse ? false_bb : exit_bb ), cond_inst );
bb->getInstList().push_back( br_inst );
@ -805,8 +805,8 @@ StackerCompiler::handle_while( char* todo )
LoadInst* cond = cast<LoadInst>( stack_top(test) );
// Compare the condition against 0
SetCondInst* cond_inst = new SetCondInst(
Instruction::SetNE, cond, ConstantInt::get( Type::LongTy, 0));
ICmpInst* cond_inst = new ICmpInst(
ICmpInst::ICMP_NE, cond, ConstantInt::get( Type::LongTy, 0));
test->getInstList().push_back( cond_inst );
// Add the branch instruction
@ -920,8 +920,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("LESS");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetLT, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SLT, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -931,8 +931,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("MORE");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetGT, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SGT, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -942,8 +942,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("LE");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetLE, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SLE, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -953,8 +953,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("GE");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetGE, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SGE, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -964,8 +964,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("NE");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetNE, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_NE, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -975,8 +975,8 @@ StackerCompiler::handle_word( int tkn )
if (echo) bb->setName("EQ");
LoadInst* op1 = cast<LoadInst>(pop_integer(bb));
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetEQ, op1, op2 );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_EQ, op1, op2 );
bb->getInstList().push_back( cond_inst );
push_value( bb, cond_inst );
break;
@ -1102,8 +1102,8 @@ StackerCompiler::handle_word( int tkn )
LoadInst* op1 = cast<LoadInst>(stack_top(bb));
// Determine if its negative
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetLT, op1, Zero );
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SLT, op1, Zero );
bb->getInstList().push_back( cond_inst );
// Create a block for storing the result
@ -1112,7 +1112,7 @@ StackerCompiler::handle_word( int tkn )
// Create a block for making it a positive value
BasicBlock* pos_bb = new BasicBlock((echo?"neg":""));
// Create the branch on the SetCond
// Create the branch on the ICmp
BranchInst* br_inst = new BranchInst( pos_bb, exit_bb, cond_inst );
bb->getInstList().push_back( br_inst );
@ -1143,11 +1143,11 @@ StackerCompiler::handle_word( int tkn )
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
// Compare them
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetLT, op1, op2);
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SLT, op1, op2);
bb->getInstList().push_back( cond_inst );
// Create a branch on the SetCond
// Create a branch on the ICmp
BranchInst* br_inst =
new BranchInst( op1_block, op2_block, cond_inst );
bb->getInstList().push_back( br_inst );
@ -1175,8 +1175,8 @@ StackerCompiler::handle_word( int tkn )
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
// Compare them
SetCondInst* cond_inst =
new SetCondInst( Instruction::SetGT, op1, op2);
ICmpInst* cond_inst =
new ICmpInst( ICmpInst::ICMP_SGT, op1, op2);
bb->getInstList().push_back( cond_inst );
// Create an exit block
@ -1192,7 +1192,7 @@ StackerCompiler::handle_word( int tkn )
push_value(op2_block, op2);
op2_block->getInstList().push_back( new BranchInst( exit_bb ) );
// Create a banch on the SetCond
// Create a banch on the ICmp
BranchInst* br_inst =
new BranchInst( op1_block, op2_block, cond_inst );
bb->getInstList().push_back( br_inst );

View File

@ -1,5 +1,4 @@
// RUN: %llvmgcc -O3 -S %s -o - | grep llvm.isunordered &&
// RUN: %llvmgcc -O3 -S %s -o - | grep xor
// RUN: %llvmgcc -O3 -S %s -o - | grep 'fcmp ord float %X, %Y'
int test2(float X, float Y) {
return !__builtin_isunordered(X, Y);

View File

@ -1,8 +1,8 @@
; These tests have an infinite trip count. We obviously shouldn't remove the
; loops! :)
;
; RUN: llvm-upgrade < %s | llvm-as | opt -indvars -adce -simplifycfg | llvm-dis | grep set | wc -l > %t2
; RUN: llvm-upgrade < %s | llvm-as | llvm-dis | grep set | wc -l > %t1
; RUN: llvm-upgrade < %s | llvm-as | opt -indvars -adce -simplifycfg | llvm-dis | grep icmp | wc -l > %t2
; RUN: llvm-upgrade < %s | llvm-as | llvm-dis | grep icmp | wc -l > %t1
; RUN: diff %t1 %t2
int %infinite_linear() { ;; test for (i = 1; i != 100; i += 2)

View File

@ -1,4 +1,4 @@
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | grep 'setlt'
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis|grep 'icmp slt'
; ModuleID = 'visible.bc'
target datalayout = "e-p:32:32"
target endian = little

View File

@ -0,0 +1,165 @@
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | \
; RUN: grep -v 'icmp ult int'
; ModuleID = 'good.bc'
target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
%struct.edgeBox = type { short, short, short, short, short, short }
%qsz = external global int ; <int*> [#uses=12]
%thresh = external global int ; <int*> [#uses=2]
%mthresh = external global int ; <int*> [#uses=1]
implementation ; Functions:
int %qsorte(sbyte* %base, int %n, int %size) {
entry:
%tmp = setgt int %n, 1 ; <bool> [#uses=1]
br bool %tmp, label %cond_next, label %return
cond_next: ; preds = %entry
store int %size, int* %qsz
%tmp3 = shl int %size, ubyte 2 ; <int> [#uses=1]
store int %tmp3, int* %thresh
%tmp4 = load int* %qsz ; <int> [#uses=1]
%tmp5 = mul int %tmp4, 6 ; <int> [#uses=1]
store int %tmp5, int* %mthresh
%tmp6 = load int* %qsz ; <int> [#uses=1]
%tmp8 = mul int %tmp6, %n ; <int> [#uses=1]
%tmp9 = getelementptr sbyte* %base, int %tmp8 ; <sbyte*> [#uses=3]
%tmp11 = setgt int %n, 3 ; <bool> [#uses=1]
br bool %tmp11, label %cond_true12, label %bb30
cond_true12: ; preds = %cond_next
%tmp156 = call int %qste( sbyte* %base, sbyte* %tmp9 ) ; <int> [#uses=0]
%tmp16 = load int* %thresh ; <int> [#uses=1]
%tmp18 = getelementptr sbyte* %base, int %tmp16 ; <sbyte*> [#uses=2]
%tmp3117 = load int* %qsz ; <int> [#uses=1]
%tmp3318 = getelementptr sbyte* %base, int %tmp3117 ; <sbyte*> [#uses=2]
%tmp3621 = setlt sbyte* %tmp3318, %tmp18 ; <bool> [#uses=1]
br bool %tmp3621, label %bb, label %bb37
bb: ; preds = %bb30, %cond_true12
%hi.0.0 = phi sbyte* [ %tmp18, %cond_true12 ], [ %hi.0, %bb30 ] ; <sbyte*> [#uses=4]
%j.1.0 = phi sbyte* [ %base, %cond_true12 ], [ %j.1, %bb30 ] ; <sbyte*> [#uses=4]
%tmp33.0 = phi sbyte* [ %tmp3318, %cond_true12 ], [ %tmp33, %bb30 ] ; <sbyte*> [#uses=6]
%tmp3 = bitcast sbyte* %j.1.0 to %struct.edgeBox* ; <%struct.edgeBox*> [#uses=1]
%tmp4 = bitcast sbyte* %tmp33.0 to %struct.edgeBox* ; <%struct.edgeBox*> [#uses=1]
%tmp255 = call int %comparee( %struct.edgeBox* %tmp3, %struct.edgeBox* %tmp4 ) ; <int> [#uses=1]
%tmp26 = setgt int %tmp255, 0 ; <bool> [#uses=1]
br bool %tmp26, label %cond_true27, label %bb30
cond_true27: ; preds = %bb
br label %bb30
bb30: ; preds = %cond_true27, %bb, %cond_next
%hi.0.3 = phi sbyte* [ %hi.0.0, %cond_true27 ], [ %hi.0.0, %bb ], [ undef, %cond_next ] ; <sbyte*> [#uses=0]
%j.1.3 = phi sbyte* [ %j.1.0, %cond_true27 ], [ %j.1.0, %bb ], [ undef, %cond_next ] ; <sbyte*> [#uses=0]
%tmp33.3 = phi sbyte* [ %tmp33.0, %cond_true27 ], [ %tmp33.0, %bb ], [ undef, %cond_next ] ; <sbyte*> [#uses=0]
%hi.0 = phi sbyte* [ %tmp9, %cond_next ], [ %hi.0.0, %bb ], [ %hi.0.0, %cond_true27 ] ; <sbyte*> [#uses=2]
%lo.1 = phi sbyte* [ %tmp33.0, %cond_true27 ], [ %tmp33.0, %bb ], [ %base, %cond_next ] ; <sbyte*> [#uses=1]
%j.1 = phi sbyte* [ %tmp33.0, %cond_true27 ], [ %j.1.0, %bb ], [ %base, %cond_next ] ; <sbyte*> [#uses=2]
%tmp31 = load int* %qsz ; <int> [#uses=1]
%tmp33 = getelementptr sbyte* %lo.1, int %tmp31 ; <sbyte*> [#uses=2]
%tmp36 = setlt sbyte* %tmp33, %hi.0 ; <bool> [#uses=1]
br bool %tmp36, label %bb, label %bb37
bb37: ; preds = %bb30, %cond_true12
%j.1.1 = phi sbyte* [ %j.1, %bb30 ], [ %base, %cond_true12 ] ; <sbyte*> [#uses=4]
%tmp40 = seteq sbyte* %j.1.1, %base ; <bool> [#uses=1]
br bool %tmp40, label %bb115, label %cond_true41
cond_true41: ; preds = %bb37
%tmp43 = load int* %qsz ; <int> [#uses=1]
%tmp45 = getelementptr sbyte* %base, int %tmp43 ; <sbyte*> [#uses=2]
%tmp6030 = setlt sbyte* %base, %tmp45 ; <bool> [#uses=1]
br bool %tmp6030, label %bb46, label %bb115
bb46: ; preds = %bb46, %cond_true41
%j.2.0 = phi sbyte* [ %j.1.1, %cond_true41 ], [ %tmp52, %bb46 ] ; <sbyte*> [#uses=3]
%i.2.0 = phi sbyte* [ %base, %cond_true41 ], [ %tmp56, %bb46 ] ; <sbyte*> [#uses=3]
%tmp = load sbyte* %j.2.0 ; <sbyte> [#uses=2]
%tmp49 = load sbyte* %i.2.0 ; <sbyte> [#uses=1]
store sbyte %tmp49, sbyte* %j.2.0
%tmp52 = getelementptr sbyte* %j.2.0, int 1 ; <sbyte*> [#uses=2]
store sbyte %tmp, sbyte* %i.2.0
%tmp56 = getelementptr sbyte* %i.2.0, int 1 ; <sbyte*> [#uses=3]
%tmp60 = setlt sbyte* %tmp56, %tmp45 ; <bool> [#uses=1]
br bool %tmp60, label %bb46, label %bb115
bb66: ; preds = %bb115, %bb66
%hi.3 = phi sbyte* [ %tmp118, %bb115 ], [ %tmp70, %bb66 ] ; <sbyte*> [#uses=2]
%tmp67 = load int* %qsz ; <int> [#uses=2]
%tmp68 = sub int 0, %tmp67 ; <int> [#uses=1]
%tmp70 = getelementptr sbyte* %hi.3, int %tmp68 ; <sbyte*> [#uses=2]
%tmp = bitcast sbyte* %tmp70 to %struct.edgeBox* ; <%struct.edgeBox*> [#uses=1]
%tmp1 = bitcast sbyte* %tmp118 to %struct.edgeBox* ; <%struct.edgeBox*> [#uses=1]
%tmp732 = call int %comparee( %struct.edgeBox* %tmp, %struct.edgeBox* %tmp1 ) ; <int> [#uses=1]
%tmp74 = setgt int %tmp732, 0 ; <bool> [#uses=1]
br bool %tmp74, label %bb66, label %bb75
bb75: ; preds = %bb66
%tmp76 = load int* %qsz ; <int> [#uses=1]
%tmp70.sum = sub int %tmp76, %tmp67 ; <int> [#uses=1]
%tmp78 = getelementptr sbyte* %hi.3, int %tmp70.sum ; <sbyte*> [#uses=3]
%tmp81 = seteq sbyte* %tmp78, %tmp118 ; <bool> [#uses=1]
br bool %tmp81, label %bb115, label %cond_true82
cond_true82: ; preds = %bb75
%tmp83 = load int* %qsz ; <int> [#uses=1]
%tmp118.sum = add int %tmp116, %tmp83 ; <int> [#uses=1]
%tmp85 = getelementptr sbyte* %min.1, int %tmp118.sum ; <sbyte*> [#uses=1]
%tmp10937 = getelementptr sbyte* %tmp85, int -1 ; <sbyte*> [#uses=3]
%tmp11239 = setlt sbyte* %tmp10937, %tmp118 ; <bool> [#uses=1]
br bool %tmp11239, label %bb115, label %bb86
bb86: ; preds = %bb104, %cond_true82
%tmp109.0 = phi sbyte* [ %tmp10937, %cond_true82 ], [ %tmp109, %bb104 ] ; <sbyte*> [#uses=5]
%i.5.2 = phi sbyte* [ %i.5.3, %cond_true82 ], [ %i.5.1, %bb104 ] ; <sbyte*> [#uses=0]
%tmp100.2 = phi sbyte* [ %tmp100.3, %cond_true82 ], [ %tmp100.1, %bb104 ] ; <sbyte*> [#uses=0]
%tmp88 = load sbyte* %tmp109.0 ; <sbyte> [#uses=2]
%tmp9746 = load int* %qsz ; <int> [#uses=1]
%tmp9847 = sub int 0, %tmp9746 ; <int> [#uses=1]
%tmp10048 = getelementptr sbyte* %tmp109.0, int %tmp9847 ; <sbyte*> [#uses=3]
%tmp10350 = setlt sbyte* %tmp10048, %tmp78 ; <bool> [#uses=1]
br bool %tmp10350, label %bb104, label %bb91
bb91: ; preds = %bb91, %bb86
%i.5.0 = phi sbyte* [ %tmp109.0, %bb86 ], [ %tmp100.0, %bb91 ] ; <sbyte*> [#uses=1]
%tmp100.0 = phi sbyte* [ %tmp10048, %bb86 ], [ %tmp100, %bb91 ] ; <sbyte*> [#uses=4]
%tmp93 = load sbyte* %tmp100.0 ; <sbyte> [#uses=1]
store sbyte %tmp93, sbyte* %i.5.0
%tmp97 = load int* %qsz ; <int> [#uses=1]
%tmp98 = sub int 0, %tmp97 ; <int> [#uses=1]
%tmp100 = getelementptr sbyte* %tmp100.0, int %tmp98 ; <sbyte*> [#uses=3]
%tmp103 = setlt sbyte* %tmp100, %tmp78 ; <bool> [#uses=1]
br bool %tmp103, label %bb104, label %bb91
bb104: ; preds = %bb91, %bb86
%i.5.1 = phi sbyte* [ %tmp109.0, %bb86 ], [ %tmp100.0, %bb91 ] ; <sbyte*> [#uses=4]
%tmp100.1 = phi sbyte* [ %tmp10048, %bb86 ], [ %tmp100, %bb91 ] ; <sbyte*> [#uses=3]
store sbyte %tmp88, sbyte* %i.5.1
%tmp109 = getelementptr sbyte* %tmp109.0, int -1 ; <sbyte*> [#uses=3]
%tmp112 = setlt sbyte* %tmp109, %tmp118 ; <bool> [#uses=1]
br bool %tmp112, label %bb115, label %bb86
bb115: ; preds = %bb104, %cond_true82, %bb75, %bb46, %cond_true41, %bb37
%tmp109.1 = phi sbyte* [ undef, %bb37 ], [ %tmp109.1, %bb75 ], [ %tmp10937, %cond_true82 ], [ %tmp109, %bb104 ], [ undef, %bb46 ], [ undef, %cond_true41 ] ; <sbyte*> [#uses=1]
%i.5.3 = phi sbyte* [ undef, %bb37 ], [ %i.5.3, %bb75 ], [ %i.5.3, %cond_true82 ], [ %i.5.1, %bb104 ], [ undef, %bb46 ], [ undef, %cond_true41 ] ; <sbyte*> [#uses=3]
%tmp100.3 = phi sbyte* [ undef, %bb37 ], [ %tmp100.3, %bb75 ], [ %tmp100.3, %cond_true82 ], [ %tmp100.1, %bb104 ], [ undef, %bb46 ], [ undef, %cond_true41 ] ; <sbyte*> [#uses=3]
%min.1 = phi sbyte* [ %tmp118, %bb104 ], [ %tmp118, %bb75 ], [ %base, %bb37 ], [ %base, %bb46 ], [ %base, %cond_true41 ], [ %tmp118, %cond_true82 ] ; <sbyte*> [#uses=2]
%j.5 = phi sbyte* [ %tmp100.1, %bb104 ], [ %j.5, %bb75 ], [ %tmp52, %bb46 ], [ %j.1.1, %bb37 ], [ %j.1.1, %cond_true41 ], [ %j.5, %cond_true82 ] ; <sbyte*> [#uses=2]
%i.4 = phi sbyte* [ %i.5.1, %bb104 ], [ %i.4, %bb75 ], [ %tmp56, %bb46 ], [ undef, %bb37 ], [ %base, %cond_true41 ], [ %i.4, %cond_true82 ] ; <sbyte*> [#uses=2]
%c.4 = phi sbyte [ %tmp88, %bb104 ], [ %c.4, %bb75 ], [ %tmp, %bb46 ], [ undef, %bb37 ], [ undef, %cond_true41 ], [ %c.4, %cond_true82 ] ; <sbyte> [#uses=2]
%tmp116 = load int* %qsz ; <int> [#uses=2]
%tmp118 = getelementptr sbyte* %min.1, int %tmp116 ; <sbyte*> [#uses=9]
%tmp122 = setlt sbyte* %tmp118, %tmp9 ; <bool> [#uses=1]
br bool %tmp122, label %bb66, label %return
return: ; preds = %bb115, %entry
ret int undef
}
declare int %qste(sbyte*, sbyte*)
declare int %comparee(%struct.edgeBox*, %struct.edgeBox*)

View File

@ -0,0 +1,32 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 'icmp' | wc -l | grep 1
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 'icmp ugt' | wc -l | grep 1
; ModuleID = 'bugpoint-tooptimize.bc'
target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
%r = external global [17 x int] ; <[17 x int]*> [#uses=1]
implementation ; Functions:
bool %print_pgm_cond_true(int %tmp12.reload, int* %tmp16.out) {
newFuncRoot:
br label %cond_true
bb27.exitStub: ; preds = %cond_true
store int %tmp16, int* %tmp16.out
ret bool true
cond_next23.exitStub: ; preds = %cond_true
store int %tmp16, int* %tmp16.out
ret bool false
cond_true: ; preds = %newFuncRoot
%tmp15 = getelementptr [17 x int]* %r, int 0, int %tmp12.reload ; <int*> [#uses=1]
%tmp16 = load int* %tmp15 ; <int> [#uses=4]
%tmp18 = icmp slt int %tmp16, -31 ; <bool> [#uses=1]
%tmp21 = icmp sgt int %tmp16, 31 ; <bool> [#uses=1]
%bothcond = or bool %tmp18, %tmp21 ; <bool> [#uses=1]
br bool %bothcond, label %bb27.exitStub, label %cond_next23.exitStub
}

View File

@ -1,7 +1,7 @@
; This is the sequence of stuff that the Java front-end expands for a single
; <= comparison. Check to make sure we turn it into a <= (only)
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | grep -v 'setle'| not grep '#uses'
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | grep -v 'icmp sle'| not grep '#uses'
bool %le(int %A, int %B) {
%c1 = setgt int %A, %B;

View File

@ -93,11 +93,12 @@ bool %test14(sbyte %A) {
ret bool %X
}
bool %test15(ubyte %A) {
%c = cast ubyte %A to sbyte
%X = setlt sbyte %c, 0 ; setgt %A, 127
ret bool %X
}
; This just won't occur when there's no difference between ubyte and sbyte
;bool %test15(ubyte %A) {
; %c = cast ubyte %A to sbyte
; %X = setlt sbyte %c, 0 ; setgt %A, 127
; ret bool %X
;}
bool %test16(int* %P) {
%c = cast int* %P to bool ;; setne P, null

View File

@ -1,7 +1,7 @@
; This test makes sure that these instructions are properly eliminated.
;
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine -disable-output &&
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | not grep set
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | not grep icmp
%X = uninitialized global int

View File

@ -3,7 +3,7 @@
; into equivalent setne,eq instructions.
;
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | grep -v seteq | grep -v setne | not grep set
; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | grep -v 'icmp eq' | grep -v 'icmp ne' | not grep icmp
bool %test1(uint %A) {
%B = setge uint %A, 1 ; setne %A, 0

View File

@ -2,7 +2,7 @@
; having overlapping live ranges that result in copies. We want the setcc instruction
; immediately before the conditional branch.
;
; RUN: llvm-upgrade < %s | llvm-as | opt -loop-reduce | llvm-dis | %prcontext 'br bool' 1 | grep set
; RUN: llvm-upgrade < %s | llvm-as | opt -loop-reduce | llvm-dis | %prcontext 'br bool' 1 | grep icmp
void %foo(float* %D, uint %E) {
entry:

View File

@ -0,0 +1,144 @@
; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis
; ModuleID = 'bugpoint-tooptimize.bc'
target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
%struct.FILE = type { int, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, %struct._IO_marker*, %struct.FILE*, int, int, int, ushort, sbyte, [1 x sbyte], sbyte*, long, sbyte*, sbyte*, sbyte*, sbyte*, uint, int, [40 x sbyte] }
%struct._IO_FILE = type { int, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, %struct._IO_marker*, %struct.FILE*, int, int, int, ushort, sbyte, [1 x sbyte], sbyte*, long, sbyte*, sbyte*, sbyte*, sbyte*, uint, int, [40 x sbyte] }
%struct._IO_marker = type { %struct._IO_marker*, %struct.FILE*, int }
%struct.charsequence = type { sbyte*, uint, uint }
%struct.trie_s = type { [26 x %struct.trie_s*], int }
%str = external global [14 x sbyte] ; <[14 x sbyte]*> [#uses=0]
%str = external global [32 x sbyte] ; <[32 x sbyte]*> [#uses=0]
%str = external global [12 x sbyte] ; <[12 x sbyte]*> [#uses=0]
%C.0.2294 = external global %struct.charsequence ; <%struct.charsequence*> [#uses=3]
%t = external global %struct.trie_s* ; <%struct.trie_s**> [#uses=0]
%str = external global [3 x sbyte] ; <[3 x sbyte]*> [#uses=0]
%str = external global [26 x sbyte] ; <[26 x sbyte]*> [#uses=0]
implementation ; Functions:
declare void %charsequence_reset(%struct.charsequence*)
declare void %free(sbyte*)
declare void %charsequence_push(%struct.charsequence*, sbyte)
declare sbyte* %charsequence_val(%struct.charsequence*)
declare int %_IO_getc(%struct.FILE*)
declare int %tolower(int)
declare %struct.trie_s* %trie_insert(%struct.trie_s*, sbyte*)
declare int %feof(%struct.FILE*)
void %addfile(%struct.trie_s* %t, %struct.FILE* %f) {
entry:
%t_addr = alloca %struct.trie_s* ; <%struct.trie_s**> [#uses=2]
%f_addr = alloca %struct.FILE* ; <%struct.FILE**> [#uses=3]
%c = alloca sbyte, align 1 ; <sbyte*> [#uses=7]
%wstate = alloca int, align 4 ; <int*> [#uses=4]
%cs = alloca %struct.charsequence, align 16 ; <%struct.charsequence*> [#uses=7]
%str = alloca sbyte*, align 4 ; <sbyte**> [#uses=3]
"alloca point" = bitcast int 0 to int ; <int> [#uses=0]
store %struct.trie_s* %t, %struct.trie_s** %t_addr
store %struct.FILE* %f, %struct.FILE** %f_addr
store int 0, int* %wstate
%tmp = getelementptr %struct.charsequence* %cs, uint 0, uint 0 ; <sbyte**> [#uses=1]
%tmp1 = getelementptr %struct.charsequence* %C.0.2294, uint 0, uint 0 ; <sbyte**> [#uses=1]
%tmp = load sbyte** %tmp1 ; <sbyte*> [#uses=1]
store sbyte* %tmp, sbyte** %tmp
%tmp = getelementptr %struct.charsequence* %cs, uint 0, uint 1 ; <uint*> [#uses=1]
%tmp2 = getelementptr %struct.charsequence* %C.0.2294, uint 0, uint 1 ; <uint*> [#uses=1]
%tmp = load uint* %tmp2 ; <uint> [#uses=1]
store uint %tmp, uint* %tmp
%tmp3 = getelementptr %struct.charsequence* %cs, uint 0, uint 2 ; <uint*> [#uses=1]
%tmp4 = getelementptr %struct.charsequence* %C.0.2294, uint 0, uint 2 ; <uint*> [#uses=1]
%tmp5 = load uint* %tmp4 ; <uint> [#uses=1]
store uint %tmp5, uint* %tmp3
br label %bb33
bb: ; preds = %bb33
%tmp = load %struct.FILE** %f_addr ; <%struct.FILE*> [#uses=1]
%tmp = call int %_IO_getc( %struct.FILE* %tmp ) ; <int> [#uses=1]
%tmp6 = call int %tolower( int %tmp ) ; <int> [#uses=1]
%tmp6 = trunc int %tmp6 to sbyte ; <sbyte> [#uses=1]
store sbyte %tmp6, sbyte* %c
%tmp7 = load int* %wstate ; <int> [#uses=1]
%tmp = icmp ne int %tmp7, 0 ; <bool> [#uses=1]
br bool %tmp, label %cond_true, label %cond_false
cond_true: ; preds = %bb
%tmp = load sbyte* %c ; <sbyte> [#uses=1]
%tmp8 = icmp sle sbyte %tmp, 96 ; <bool> [#uses=1]
br bool %tmp8, label %cond_true9, label %cond_next
cond_true9: ; preds = %cond_true
br label %bb16
cond_next: ; preds = %cond_true
%tmp10 = load sbyte* %c ; <sbyte> [#uses=1]
%tmp11 = icmp sgt sbyte %tmp10, 122 ; <bool> [#uses=1]
br bool %tmp11, label %cond_true12, label %cond_next13
cond_true12: ; preds = %cond_next
br label %bb16
cond_next13: ; preds = %cond_next
%tmp14 = load sbyte* %c ; <sbyte> [#uses=1]
%tmp14 = sext sbyte %tmp14 to int ; <int> [#uses=1]
%tmp1415 = trunc int %tmp14 to sbyte ; <sbyte> [#uses=1]
call void %charsequence_push( %struct.charsequence* %cs, sbyte %tmp1415 )
br label %bb21
bb16: ; preds = %cond_true12, %cond_true9
%tmp17 = call sbyte* %charsequence_val( %struct.charsequence* %cs ) ; <sbyte*> [#uses=1]
store sbyte* %tmp17, sbyte** %str
%tmp = load %struct.trie_s** %t_addr ; <%struct.trie_s*> [#uses=1]
%tmp18 = load sbyte** %str ; <sbyte*> [#uses=1]
%tmp19 = call %struct.trie_s* %trie_insert( %struct.trie_s* %tmp, sbyte* %tmp18 ) ; <%struct.trie_s*> [#uses=0]
%tmp20 = load sbyte** %str ; <sbyte*> [#uses=1]
call void %free( sbyte* %tmp20 )
store int 0, int* %wstate
br label %bb21
bb21: ; preds = %bb16, %cond_next13
br label %cond_next32
cond_false: ; preds = %bb
%tmp22 = load sbyte* %c ; <sbyte> [#uses=1]
%tmp23 = icmp sgt sbyte %tmp22, 96 ; <bool> [#uses=1]
br bool %tmp23, label %cond_true24, label %cond_next31
cond_true24: ; preds = %cond_false
%tmp25 = load sbyte* %c ; <sbyte> [#uses=1]
%tmp26 = icmp sle sbyte %tmp25, 122 ; <bool> [#uses=1]
br bool %tmp26, label %cond_true27, label %cond_next30
cond_true27: ; preds = %cond_true24
call void %charsequence_reset( %struct.charsequence* %cs )
%tmp28 = load sbyte* %c ; <sbyte> [#uses=1]
%tmp28 = sext sbyte %tmp28 to int ; <int> [#uses=1]
%tmp2829 = trunc int %tmp28 to sbyte ; <sbyte> [#uses=1]
call void %charsequence_push( %struct.charsequence* %cs, sbyte %tmp2829 )
store int 1, int* %wstate
br label %cond_next30
cond_next30: ; preds = %cond_true27, %cond_true24
br label %cond_next31
cond_next31: ; preds = %cond_next30, %cond_false
br label %cond_next32
cond_next32: ; preds = %cond_next31, %bb21
br label %bb33
bb33: ; preds = %cond_next32, %entry
%tmp34 = load %struct.FILE** %f_addr ; <%struct.FILE*> [#uses=1]
%tmp35 = call int %feof( %struct.FILE* %tmp34 ) ; <int> [#uses=1]
%tmp36 = icmp eq int %tmp35, 0 ; <bool> [#uses=1]
br bool %tmp36, label %bb, label %bb37
bb37: ; preds = %bb33
br label %return
return: ; preds = %bb37
ret void
}

View File

@ -1,4 +1,4 @@
; RUN: llvm-upgrade < %s | llvm-as | opt -simplifycfg | llvm-dis | not grep seteq
; RUN: llvm-upgrade < %s | llvm-as | opt -simplifycfg | llvm-dis | not grep 'icmp eq'
; Check that simplifycfg deletes a dead 'seteq' instruction when it
; folds a conditional branch into a switch instruction.

View File

@ -724,8 +724,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
// Check to see if we already looked up the value.
Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
Value *IsNull = new SetCondInst(Instruction::SetEQ, CachedVal,
NullPtr, "isNull", EntryBB);
Value *IsNull = new ICmpInst(ICmpInst::ICMP_EQ, CachedVal,
NullPtr, "isNull", EntryBB);
new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB);
// Resolve the call to function F via the JIT API:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -333,7 +333,7 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 285 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeParser.y"
#line 275 "/proj/llvm/llvm-3/tools/llvm-upgrade/UpgradeParser.y"
typedef union YYSTYPE {
std::string* String;
TypeInfo Type;

View File

@ -333,7 +333,7 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 285 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeParser.y"
#line 275 "/proj/llvm/llvm-3/tools/llvm-upgrade/UpgradeParser.y"
typedef union YYSTYPE {
std::string* String;
TypeInfo Type;

View File

@ -23,8 +23,6 @@
#define YYERROR_VERBOSE 1
#define YYINCLUDED_STDLIB_H
#define YYDEBUG 1
#define UPGRADE_SETCOND_OPS 0
#define GENERATE_FCMP_INSTS 0
int yylex(); // declaration" of xxx warnings.
int yyparse();
@ -194,11 +192,7 @@ static std::string getCastUpgrade(
// the original intent by replace the cast with a setne
const char* comparator = SrcTy.isPointer() ? ", null" :
(SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
#if UPGRADE_SETCOND_OPS
const char* compareOp = SrcTy.isFloatingPoint() ? "setne " : "icmp ne ";
#else
const char* compareOp = "setne";
#endif
const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne ";
if (isConst) {
Result = "(" + Source + comparator + ")";
Result = compareOp + Result;
@ -254,16 +248,12 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) {
result[6] = cc1;
result[7] = cc2;
if (TI.isFloatingPoint()) {
#if GENERATE_FCMP_INSTS
result[0] = 'f';
result[5] = 'o'; // FIXME: Always map to ordered comparison ?
result[5] = 'o';
if (cc1 == 'n')
result[5] = 'u'; // NE maps to unordered
else
result[5] = 'o'; // everything else maps to ordered
#else
result = setcc;
#endif
} else if (TI.isIntegral() || TI.isPointer()) {
result[0] = 'i';
if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
@ -679,9 +669,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
$$ = $1;
}
| SetCondOps '(' ConstVal ',' ConstVal ')' {
#if UPGRADE_SETCOND_OPS
*$1 = getCompareOp(*$1, $3.type);
#endif
*$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
$3.destroy(); $5.destroy();
$$ = $1;
@ -1205,9 +1193,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
$$ = $1;
}
| SetCondOps Types ValueRef ',' ValueRef {
#if UPGRADE_SETCOND_OPS
*$1 = getCompareOp(*$1, $2);
#endif
*$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
$2.destroy(); $3.destroy(); $5.destroy();
$$ = $1;

View File

@ -23,8 +23,6 @@
#define YYERROR_VERBOSE 1
#define YYINCLUDED_STDLIB_H
#define YYDEBUG 1
#define UPGRADE_SETCOND_OPS 0
#define GENERATE_FCMP_INSTS 0
int yylex(); // declaration" of xxx warnings.
int yyparse();
@ -194,11 +192,7 @@ static std::string getCastUpgrade(
// the original intent by replace the cast with a setne
const char* comparator = SrcTy.isPointer() ? ", null" :
(SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
#if UPGRADE_SETCOND_OPS
const char* compareOp = SrcTy.isFloatingPoint() ? "setne " : "icmp ne ";
#else
const char* compareOp = "setne";
#endif
const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne ";
if (isConst) {
Result = "(" + Source + comparator + ")";
Result = compareOp + Result;
@ -254,16 +248,12 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) {
result[6] = cc1;
result[7] = cc2;
if (TI.isFloatingPoint()) {
#if GENERATE_FCMP_INSTS
result[0] = 'f';
result[5] = 'o'; // FIXME: Always map to ordered comparison ?
result[5] = 'o';
if (cc1 == 'n')
result[5] = 'u'; // NE maps to unordered
else
result[5] = 'o'; // everything else maps to ordered
#else
result = setcc;
#endif
} else if (TI.isIntegral() || TI.isPointer()) {
result[0] = 'i';
if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
@ -679,9 +669,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
$$ = $1;
}
| SetCondOps '(' ConstVal ',' ConstVal ')' {
#if UPGRADE_SETCOND_OPS
*$1 = getCompareOp(*$1, $3.type);
#endif
*$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
$3.destroy(); $5.destroy();
$$ = $1;
@ -1205,9 +1193,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
$$ = $1;
}
| SetCondOps Types ValueRef ',' ValueRef {
#if UPGRADE_SETCOND_OPS
*$1 = getCompareOp(*$1, $2);
#endif
*$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
$2.destroy(); $3.destroy(); $5.destroy();
$$ = $1;

View File

@ -783,31 +783,63 @@ void CppWriter::printConstant(const Constant *CV) {
}
Out << "Constant* " << constName << " = ConstantExpr::";
switch (CE->getOpcode()) {
case Instruction::Add: Out << "getAdd"; break;
case Instruction::Sub: Out << "getSub"; break;
case Instruction::Mul: Out << "getMul"; break;
case Instruction::UDiv: Out << "getUDiv"; break;
case Instruction::SDiv: Out << "getSDiv"; break;
case Instruction::FDiv: Out << "getFDiv"; break;
case Instruction::URem: Out << "getURem"; break;
case Instruction::SRem: Out << "getSRem"; break;
case Instruction::FRem: Out << "getFRem"; break;
case Instruction::And: Out << "getAnd"; break;
case Instruction::Or: Out << "getOr"; break;
case Instruction::Xor: Out << "getXor"; break;
case Instruction::SetEQ: Out << "getSetEQ"; break;
case Instruction::SetNE: Out << "getSetNE"; break;
case Instruction::SetLE: Out << "getSetLE"; break;
case Instruction::SetGE: Out << "getSetGE"; break;
case Instruction::SetLT: Out << "getSetLT"; break;
case Instruction::SetGT: Out << "getSetGT"; break;
case Instruction::Shl: Out << "getShl"; break;
case Instruction::LShr: Out << "getLShr"; break;
case Instruction::AShr: Out << "getAShr"; break;
case Instruction::Select: Out << "getSelect"; break;
case Instruction::ExtractElement: Out << "getExtractElement"; break;
case Instruction::InsertElement: Out << "getInsertElement"; break;
case Instruction::ShuffleVector: Out << "getShuffleVector"; break;
case Instruction::Add: Out << "getAdd("; break;
case Instruction::Sub: Out << "getSub("; break;
case Instruction::Mul: Out << "getMul("; break;
case Instruction::UDiv: Out << "getUDiv("; break;
case Instruction::SDiv: Out << "getSDiv("; break;
case Instruction::FDiv: Out << "getFDiv("; break;
case Instruction::URem: Out << "getURem("; break;
case Instruction::SRem: Out << "getSRem("; break;
case Instruction::FRem: Out << "getFRem("; break;
case Instruction::And: Out << "getAnd("; break;
case Instruction::Or: Out << "getOr("; break;
case Instruction::Xor: Out << "getXor("; break;
case Instruction::ICmp:
Out << "getICmp(ICmpInst::ICMP_";
switch (CE->getPredicate()) {
case ICmpInst::ICMP_EQ: Out << "EQ"; break;
case ICmpInst::ICMP_NE: Out << "NE"; break;
case ICmpInst::ICMP_SLT: Out << "SLT"; break;
case ICmpInst::ICMP_ULT: Out << "ULT"; break;
case ICmpInst::ICMP_SGT: Out << "SGT"; break;
case ICmpInst::ICMP_UGT: Out << "UGT"; break;
case ICmpInst::ICMP_SLE: Out << "SLE"; break;
case ICmpInst::ICMP_ULE: Out << "ULE"; break;
case ICmpInst::ICMP_SGE: Out << "SGE"; break;
case ICmpInst::ICMP_UGE: Out << "UGE"; break;
default: error("Invalid ICmp Predicate");
}
break;
case Instruction::FCmp:
Out << "getFCmp(FCmpInst::FCMP_";
switch (CE->getPredicate()) {
case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
case FCmpInst::FCMP_ORD: Out << "ORD"; break;
case FCmpInst::FCMP_UNO: Out << "UNO"; break;
case FCmpInst::FCMP_OEQ: Out << "OEQ"; break;
case FCmpInst::FCMP_UEQ: Out << "UEQ"; break;
case FCmpInst::FCMP_ONE: Out << "ONE"; break;
case FCmpInst::FCMP_UNE: Out << "UNE"; break;
case FCmpInst::FCMP_OLT: Out << "OLT"; break;
case FCmpInst::FCMP_ULT: Out << "ULT"; break;
case FCmpInst::FCMP_OGT: Out << "OGT"; break;
case FCmpInst::FCMP_UGT: Out << "UGT"; break;
case FCmpInst::FCMP_OLE: Out << "OLE"; break;
case FCmpInst::FCMP_ULE: Out << "ULE"; break;
case FCmpInst::FCMP_OGE: Out << "OGE"; break;
case FCmpInst::FCMP_UGE: Out << "UGE"; break;
case FCmpInst::FCMP_TRUE: Out << "TRUE"; break;
default: error("Invalid FCmp Predicate");
}
break;
case Instruction::Shl: Out << "getShl("; break;
case Instruction::LShr: Out << "getLShr("; break;
case Instruction::AShr: Out << "getAShr("; break;
case Instruction::Select: Out << "getSelect("; break;
case Instruction::ExtractElement: Out << "getExtractElement("; break;
case Instruction::InsertElement: Out << "getInsertElement("; break;
case Instruction::ShuffleVector: Out << "getShuffleVector("; break;
default:
error("Invalid constant expression");
break;
@ -1075,21 +1107,46 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname) {
Out << "\", " << bbname << ");";
break;
}
case Instruction::SetEQ:
case Instruction::SetNE:
case Instruction::SetLE:
case Instruction::SetGE:
case Instruction::SetLT:
case Instruction::SetGT: {
Out << "SetCondInst* " << iName << " = new SetCondInst(";
switch (I->getOpcode()) {
case Instruction::SetEQ: Out << "Instruction::SetEQ"; break;
case Instruction::SetNE: Out << "Instruction::SetNE"; break;
case Instruction::SetLE: Out << "Instruction::SetLE"; break;
case Instruction::SetGE: Out << "Instruction::SetGE"; break;
case Instruction::SetLT: Out << "Instruction::SetLT"; break;
case Instruction::SetGT: Out << "Instruction::SetGT"; break;
default: Out << "Instruction::BadOpCode"; break;
case Instruction::FCmp: {
Out << "FCmpInst* " << iName << " = new FCmpInst(";
switch (cast<FCmpInst>(I)->getPredicate()) {
case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
case FCmpInst::FCMP_OEQ : Out << "FCmpInst::FCMP_OEQ"; break;
case FCmpInst::FCMP_OGT : Out << "FCmpInst::FCMP_OGT"; break;
case FCmpInst::FCMP_OGE : Out << "FCmpInst::FCMP_OGE"; break;
case FCmpInst::FCMP_OLT : Out << "FCmpInst::FCMP_OLT"; break;
case FCmpInst::FCMP_OLE : Out << "FCmpInst::FCMP_OLE"; break;
case FCmpInst::FCMP_ONE : Out << "FCmpInst::FCMP_ONE"; break;
case FCmpInst::FCMP_ORD : Out << "FCmpInst::FCMP_ORD"; break;
case FCmpInst::FCMP_UNO : Out << "FCmpInst::FCMP_UNO"; break;
case FCmpInst::FCMP_UEQ : Out << "FCmpInst::FCMP_UEQ"; break;
case FCmpInst::FCMP_UGT : Out << "FCmpInst::FCMP_UGT"; break;
case FCmpInst::FCMP_UGE : Out << "FCmpInst::FCMP_UGE"; break;
case FCmpInst::FCMP_ULT : Out << "FCmpInst::FCMP_ULT"; break;
case FCmpInst::FCMP_ULE : Out << "FCmpInst::FCMP_ULE"; break;
case FCmpInst::FCMP_UNE : Out << "FCmpInst::FCMP_UNE"; break;
case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
}
Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
printEscapedString(I->getName());
Out << "\", " << bbname << ");";
break;
}
case Instruction::ICmp: {
Out << "ICmpInst* " << iName << " = new ICmpInst(";
switch (cast<ICmpInst>(I)->getPredicate()) {
case ICmpInst::ICMP_EQ: Out << "ICmpInst::ICMP_EQ"; break;
case ICmpInst::ICMP_NE: Out << "ICmpInst::ICMP_NE"; break;
case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
}
Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
printEscapedString(I->getName());