This is the first in a series of patches to split the SETCC instructions
into just two instructions: icmp (integer compare) and fcmp (floating
point compare). This patch is a no-op. It introduces code that will be
used in subsequent patches. The new instruction codes are reserved, the
instruction classes are defined, and the InstVisitor class (and users)
is updated to recognize the new instructions. However, nothing else in
LLVM will produce these instructions (yet). The patch passes all tests.

Reid.
Index: include/llvm/InstrTypes.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/InstrTypes.h,v
retrieving revision 1.47
diff -t -d -u -p -5 -r1.47 InstrTypes.h
--- include/llvm/InstrTypes.h	17 Sep 2006 19:29:56 -0000	1.47
+++ include/llvm/InstrTypes.h	19 Nov 2006 07:32:48 -0000
@@ -241,8 +241,62 @@ public:
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
   }
 };
 
+//===----------------------------------------------------------------------===//
+//                               CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class is the base class for the comparison instructions. 
+/// @brief Abstract base class of comparison instructions.
+class CmpInst: public Instruction {
+  CmpInst(unsigned short pred, Value *LHS, Value *RHS,
+              const std::string &Name = "", Instruction *InsertBefore = 0);
+  CmpInst(unsigned short pred, Value *LHS, Value *RHS,
+              const std::string &Name, BasicBlock *InsertAtEnd);
+  CmpInst(); // do not implement
+protected:
+  Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
+public:
+  /// The predicate for CmpInst is defined by the subclasses but stored in 
+  /// the SubclassData field (see Value.h).  We allow it to be fetched here
+  /// as the predicate but there is no enum type for it, just the raw unsigned 
+  /// short. This facilitates comparison of CmpInst instances without delving
+  /// into the subclasses since predicate values are distinct between the
+  /// CmpInst subclasses.
+  /// @brief Return the predicate for this instruction.
+  unsigned short getPredicate() const {
+    return SubclassData;
+  }
+
+  /// @brief Provide more efficient getOperand methods.
+  Value *getOperand(unsigned i) const {
+    assert(i < 2 && "getOperand() out of range!");
+    return Ops[i];
+  }
+  void setOperand(unsigned i, Value *Val) {
+    assert(i < 2 && "setOperand() out of range!");
+    Ops[i] = Val;
+  }
+
+  /// @brief CmpInst instructions always have 2 operands.
+  unsigned getNumOperands() const { return 2; }
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Swap the operands.
+  void swapOperands();
+
+  /// @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) {
+    return I->getOpcode() == Instruction::ICmp || 
+           I->getOpcode() == Instruction::FCmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
 } // End llvm namespace
 
 #endif
Index: include/llvm/Instruction.def
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Instruction.def,v
retrieving revision 1.24
diff -t -d -u -p -5 -r1.24 Instruction.def
--- include/llvm/Instruction.def	11 Nov 2006 23:06:47 -0000	1.24
+++ include/llvm/Instruction.def	19 Nov 2006 07:32:48 -0000
@@ -124,24 +124,26 @@ HANDLE_MEMORY_INST(29, Store , StoreInst
 HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
   LAST_MEMORY_INST(30)
 
 // Other operators...
  FIRST_OTHER_INST(31)
-HANDLE_OTHER_INST(31, PHI    , PHINode    )  // PHI node instruction
-HANDLE_OTHER_INST(32, Cast   , CastInst   )  // Type cast
-HANDLE_OTHER_INST(33, Call   , CallInst   )  // Call a function
-HANDLE_OTHER_INST(34, Shl    , ShiftInst  )  // Shift Left operations (logical)
-HANDLE_OTHER_INST(35, LShr   , ShiftInst  )  // Logical Shift right (unsigned) 
-HANDLE_OTHER_INST(36, AShr   , ShiftInst  )  // Arithmetic shift right (signed)
-HANDLE_OTHER_INST(37, Select , SelectInst )  // select instruction
-HANDLE_OTHER_INST(38, UserOp1, Instruction)  // May be used internally in a pass
-HANDLE_OTHER_INST(39, UserOp2, Instruction)  // Internal to passes only
-HANDLE_OTHER_INST(40, VAArg  , VAArgInst  )  // vaarg instruction
-HANDLE_OTHER_INST(41, ExtractElement, ExtractElementInst)// extract from vector.
-HANDLE_OTHER_INST(42, InsertElement, InsertElementInst)  // insert into vector
-HANDLE_OTHER_INST(43, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
-  LAST_OTHER_INST(43)
+HANDLE_OTHER_INST(31, ICmp   , ICmpInst   )  // Integer comparison instruction
+HANDLE_OTHER_INST(32, FCmp   , FCmpInst   )  // Floating point comparison instr.
+HANDLE_OTHER_INST(33, PHI    , PHINode    )  // PHI node instruction
+HANDLE_OTHER_INST(34, Cast   , CastInst   )  // Type cast
+HANDLE_OTHER_INST(35, Call   , CallInst   )  // Call a function
+HANDLE_OTHER_INST(36, Shl    , ShiftInst  )  // Shift Left operations (logical)
+HANDLE_OTHER_INST(37, LShr   , ShiftInst  )  // Logical Shift right (unsigned) 
+HANDLE_OTHER_INST(38, AShr   , ShiftInst  )  // Arithmetic shift right (signed)
+HANDLE_OTHER_INST(39, Select , SelectInst )  // select instruction
+HANDLE_OTHER_INST(40, UserOp1, Instruction)  // May be used internally in a pass
+HANDLE_OTHER_INST(41, UserOp2, Instruction)  // Internal to passes only
+HANDLE_OTHER_INST(42, VAArg  , VAArgInst  )  // vaarg instruction
+HANDLE_OTHER_INST(43, ExtractElement, ExtractElementInst)// extract from vector.
+HANDLE_OTHER_INST(44, InsertElement, InsertElementInst)  // insert into vector
+HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
+  LAST_OTHER_INST(45)
 
 #undef  FIRST_TERM_INST
 #undef HANDLE_TERM_INST
 #undef   LAST_TERM_INST
 
Index: include/llvm/Instructions.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Instructions.h,v
retrieving revision 1.45
diff -t -d -u -p -5 -r1.45 Instructions.h
--- include/llvm/Instructions.h	8 Nov 2006 06:47:32 -0000	1.45
+++ include/llvm/Instructions.h	19 Nov 2006 07:32:49 -0000
@@ -413,10 +413,235 @@ public:
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
   }
 };
 
 //===----------------------------------------------------------------------===//
+//                               ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on integers, pointers, or packed 
+/// vectors of integrals. The two operands must be the same type.
+/// @brief Represent an integer comparison operator.
+class ICmpInst: public CmpInst {
+public:
+  /// This enumeration lists the possible predicates for the ICmpInst. The
+  /// values in the range 0-31 are reserved for FCmpInst while values in the
+  /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+  /// predicate values are not overlapping between the classes.
+  enum Predicate {
+    EQ  = 32,    ///< equal
+    NE  = 33,    ///< not equal
+    UGT = 34,    ///< unsigned greater than
+    UGE = 35,    ///< unsigned greater or equal
+    ULT = 36,    ///< unsigned less than
+    ULE = 37,    ///< unsigned less or equal
+    SGT = 38,    ///< signed greater than
+    SGE = 39,    ///< signed greater or equal
+    SLT = 40,    ///< signed less than
+    SLE = 41     ///< signed less or equal
+  };
+
+  /// @brief Constructor with insert-before-instruction semantics.
+  ICmpInst(
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const std::string &Name = "",  ///< Name of the instruction
+    Instruction *InsertBefore = 0  ///< Where to insert
+  );
+
+  /// @brief Constructor with insert-at-block-end semantics.
+  ICmpInst(
+    Predicate pred, ///< The predicate to use for the comparison
+    Value *LHS,     ///< The left-hand-side of the expression
+    Value *RHS,     ///< The right-hand-side of the expression
+    const std::string &Name,  ///< Name of the instruction
+    BasicBlock *InsertAtEnd   ///< Block to insert into.
+  );
+
+  /// @brief Return the predicate for this instruction.
+  Predicate getPredicate() const { return Predicate(SubclassData); }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for the instruction's current predicate. 
+  /// @brief Return the inverse of the instruction's predicate.
+  Predicate getInversePredicate() const {
+    return getInversePredicate(getPredicate());
+  }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for predicate provided in \p pred. 
+  /// @brief Return the inverse of a given predicate
+  static Predicate getInversePredicate(Predicate pred);
+
+  /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
+  /// @returns the predicate that would be the result of exchanging the two 
+  /// operands of the ICmpInst instruction without changing the result 
+  /// produced.  
+  /// @brief Return the predicate as if the operands were swapped
+  Predicate getSwappedPredicate() const {
+    return getSwappedPredicate(getPredicate());
+  }
+
+  /// 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);
+
+  /// This also tests for commutativity. If isEquality() returns true then
+  /// the predicate is also commutative. Only the equality predicates are
+  /// 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 == EQ || SubclassData == NE;
+  }
+  bool isCommutative() const { return isEquality(); }
+
+  /// @returns true if the predicate is relational (not EQ or NE). 
+  /// @brief Determine if this a relational predicate.
+  bool isRelational() const {
+    return !isEquality();
+  }
+
+  /// 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
+  /// (e.g. ult). 
+  /// @brief Swap operands and adjust predicate.
+  void swapOperands() {
+    SubclassData = getSwappedPredicate();
+    std::swap(Ops[0], Ops[1]);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const ICmpInst *) { return true; }
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ICmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                               FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on floating point values or packed     
+/// vectors of floating point values. The operands must be identical types.
+/// @brief Represents a floating point comparison operator.
+class FCmpInst: public CmpInst {
+public:
+  /// This enumeration lists the possible predicates for the FCmpInst. Values
+  /// in the range 0-31 are reserved for FCmpInst.
+  enum Predicate {
+    // Opcode        U L G E    Intuitive operation
+    FALSE = 0, ///<  0 0 0 0    Always false (always folded)
+    OEQ   = 1, ///<  0 0 0 1    True if ordered and equal
+    OGT   = 2, ///<  0 0 1 0    True if ordered and greater than
+    OGE   = 3, ///<  0 0 1 1    True if ordered and greater than or equal
+    OLT   = 4, ///<  0 1 0 0    True if ordered and less than
+    OLE   = 5, ///<  0 1 0 1    True if ordered and less than or equal
+    ONE   = 6, ///<  0 1 1 0    True if ordered and operands are unequal
+    ORD   = 7, ///<  0 1 1 1    True if ordered (no nans)
+    UNO   = 8, ///<  1 0 0 0    True if unordered: isnan(X) | isnan(Y)
+    UEQ   = 9, ///<  1 0 0 1    True if unordered or equal
+    UGT   =10, ///<  1 0 1 0    True if unordered or greater than
+    UGE   =11, ///<  1 0 1 1    True if unordered, greater than, or equal
+    ULT   =12, ///<  1 1 0 0    True if unordered or less than
+    ULE   =13, ///<  1 1 0 1    True if unordered, less than, or equal
+    UNE   =14, ///<  1 1 1 0    True if unordered or not equal
+    TRUE  =15  ///<  1 1 1 1    Always true (always folded)
+  };
+
+  /// @brief Constructor with insert-before-instruction semantics.
+  FCmpInst(
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const std::string &Name = "",  ///< Name of the instruction
+    Instruction *InsertBefore = 0  ///< Where to insert
+  );
+
+  /// @brief Constructor with insert-at-block-end semantics.
+  FCmpInst(
+    Predicate pred, ///< The predicate to use for the comparison
+    Value *LHS,     ///< The left-hand-side of the expression
+    Value *RHS,     ///< The right-hand-side of the expression
+    const std::string &Name,  ///< Name of the instruction
+    BasicBlock *InsertAtEnd   ///< Block to insert into.
+  );
+
+  /// @brief Return the predicate for this instruction.
+  Predicate getPredicate() const { return Predicate(SubclassData); }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for the instructions current predicate. 
+  /// @brief Return the inverse of the predicate
+  Predicate getInversePredicate() const {
+    return getInversePredicate(getPredicate());
+  }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for \p pred.
+  /// @brief Return the inverse of a given predicate
+  static Predicate getInversePredicate(Predicate pred);
+
+  /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
+  /// @returns the predicate that would be the result of exchanging the two 
+  /// operands of the ICmpInst instruction without changing the result 
+  /// produced.  
+  /// @brief Return the predicate as if the operands were swapped
+  Predicate getSwappedPredicate() const {
+    return getSwappedPredicate(getPredicate());
+  }
+
+  /// 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);
+
+  /// This also tests for commutativity. If isEquality() returns true then
+  /// the predicate is also commutative. Only the equality predicates are
+  /// 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 == OEQ || SubclassData == ONE ||
+           SubclassData == UEQ || SubclassData == UNE;
+  }
+  bool isCommutative() const { return isEquality(); }
+
+  /// @returns true if the predicate is relational (not EQ or NE). 
+  /// @brief Determine if this a relational predicate.
+  bool isRelational() const { return !isEquality(); }
+
+  /// 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
+  /// (e.g. ult). 
+  /// @brief Swap operands and adjust predicate.
+  void swapOperands() {
+    SubclassData = getSwappedPredicate();
+    std::swap(Ops[0], Ops[1]);
+  }
+
+  /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const FCmpInst *) { return true; }
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::FCmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
 //                            SetCondInst Class
 //===----------------------------------------------------------------------===//
 
 /// SetCondInst class - Represent a setCC operator, where CC is eq, ne, lt, gt,
 /// le, or ge.
Index: include/llvm/Support/InstVisitor.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Support/InstVisitor.h,v
retrieving revision 1.41
diff -t -d -u -p -5 -r1.41 InstVisitor.h
--- include/llvm/Support/InstVisitor.h	9 Oct 2006 18:33:08 -0000	1.41
+++ include/llvm/Support/InstVisitor.h	19 Nov 2006 07:32:51 -0000
@@ -167,10 +167,12 @@ public:
   RetTy visitSwitchInst(SwitchInst &I)              { DELEGATE(TerminatorInst);}
   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(Instruction);}
+  RetTy visitFCmpInst(FCmpInst &I)                  { DELEGATE(Instruction);}
   RetTy visitMallocInst(MallocInst &I)              { DELEGATE(AllocationInst);}
   RetTy visitAllocaInst(AllocaInst &I)              { DELEGATE(AllocationInst);}
   RetTy visitFreeInst(FreeInst     &I)              { DELEGATE(Instruction); }
   RetTy visitLoadInst(LoadInst     &I)              { DELEGATE(Instruction); }
   RetTy visitStoreInst(StoreInst   &I)              { DELEGATE(Instruction); }
Index: lib/VMCore/Instructions.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/VMCore/Instructions.cpp,v
retrieving revision 1.46
diff -t -d -u -p -5 -r1.46 Instructions.cpp
--- lib/VMCore/Instructions.cpp	8 Nov 2006 06:47:33 -0000	1.46
+++ lib/VMCore/Instructions.cpp	19 Nov 2006 07:32:52 -0000
@@ -1288,10 +1288,97 @@ Instruction::BinaryOps SetCondInst::getS
   case SetGE: return SetLE;
   case SetLE: return SetGE;
   }
 }
 
+
+//===----------------------------------------------------------------------===//
+//                               CmpInst Classes
+//===----------------------------------------------------------------------===//
+
+void CmpInst::swapOperands() {
+  if (ICmpInst* IC = dyn_cast<ICmpInst>(this)) {
+    IC->swapOperands();
+  } else if (FCmpInst* FC = dyn_cast<FCmpInst>(this)) {
+    FC->swapOperands();
+  }
+  assert(!"Unknown CmpInst type");
+}
+
+ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) {
+  switch (pred) {
+    default:
+      assert(!"Unknown icmp predicate!");
+    case EQ: return NE;
+    case NE: return EQ;
+    case UGT: return ULE;
+    case ULT: return UGE;
+    case UGE: return ULT;
+    case ULE: return UGT;
+    case SGT: return SLE;
+    case SLT: return SGE;
+    case SGE: return SLT;
+    case SLE: return SGT;
+  }
+}
+
+ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) {
+  switch (pred) {
+    default: assert(! "Unknown setcc instruction!");
+    case EQ: case NE:
+      return pred;
+    case SGT: return SLT;
+    case SLT: return SGT;
+    case SGE: return SLE;
+    case SLE: return SGE;
+    case UGT: return ULT;
+    case ULT: return UGT;
+    case UGE: return ULE;
+    case ULE: return UGE;
+  }
+}
+
+FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) {
+  switch (pred) {
+    default:
+      assert(!"Unknown icmp predicate!");
+    case OEQ: return ONE;
+    case ONE: return OEQ;
+    case OGT: return OLE;
+    case OLT: return OGE;
+    case OGE: return OLT;
+    case OLE: return OGT;
+    case UEQ: return UNE;
+    case UNE: return UEQ;
+    case UGT: return ULE;
+    case ULT: return UGE;
+    case UGE: return ULT;
+    case ULE: return UGT;
+    case TRUE: return FALSE;
+    case FALSE: return TRUE;
+  }
+}
+
+FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) {
+  switch (pred) {
+    default: assert(!"Unknown setcc instruction!");
+    case FALSE: case TRUE:
+    case OEQ: case ONE:
+    case UEQ: case UNE:
+    case ORD: case UNO:
+      return pred;
+    case OGT: return OLT;
+    case OLT: return OGT;
+    case OGE: return OLE;
+    case OLE: return OGE;
+    case UGT: return ULT;
+    case ULT: return UGT;
+    case UGE: return ULE;
+    case ULE: return UGE;
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //                        SwitchInst Implementation
 //===----------------------------------------------------------------------===//
 
 void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) {
Index: lib/VMCore/Verifier.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/VMCore/Verifier.cpp,v
retrieving revision 1.165
diff -t -d -u -p -5 -r1.165 Verifier.cpp
--- lib/VMCore/Verifier.cpp	20 Oct 2006 07:07:24 -0000	1.165
+++ lib/VMCore/Verifier.cpp	19 Nov 2006 07:32:53 -0000
@@ -177,10 +177,12 @@ namespace {  // Anonymous namespace for 
     void visitGlobalVariable(GlobalVariable &GV);
     void visitFunction(Function &F);
     void visitBasicBlock(BasicBlock &BB);
     void visitPHINode(PHINode &PN);
     void visitBinaryOperator(BinaryOperator &B);
+    void visitICmpInst(ICmpInst &IC);
+    void visitFCmpInst(FCmpInst &FC);
     void visitShiftInst(ShiftInst &SI);
     void visitExtractElementInst(ExtractElementInst &EI);
     void visitInsertElementInst(InsertElementInst &EI);
     void visitShuffleVectorInst(ShuffleVectorInst &EI);
     void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
@@ -549,10 +551,43 @@ void Verifier::visitBinaryOperator(Binar
   }
 
   visitInstruction(B);
 }
 
+void Verifier::visitICmpInst(ICmpInst& IC) {
+  // Check that icmp instructions return bool
+  Assert1(IC.getType() == Type::BoolTy,
+         "ICmp instructions must return boolean values!", &IC);
+  // Check that the operands are the same type
+  const Type* Op0Ty = IC.getOperand(0)->getType();
+  const Type* Op1Ty = IC.getOperand(0)->getType();
+  Assert1(Op0Ty == Op1Ty,
+          "Both operands to ICmp instruction are not of the same type!", &IC);
+  // Check that the operands are the right type
+  Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
+          (isa<PackedType>(Op0Ty) && 
+           cast<PackedType>(Op0Ty)->getElementType()->isIntegral()),
+          "Invalid operand types for ICmp instruction", &IC);
+  visitInstruction(IC);
+}
+
+void Verifier::visitFCmpInst(FCmpInst& FC) {
+  // Check that icmp instructions return bool
+  Assert1(FC.getType() == Type::BoolTy,
+         "ICmp instructions must return boolean values!", &FC);
+  // Check that the operands are the same type
+  const Type* Op0Ty = FC.getOperand(0)->getType();
+  const Type* Op1Ty = FC.getOperand(0)->getType();
+  Assert1(Op0Ty == Op1Ty,
+          "Both operands to FCmp instruction are not of the same type!", &FC);
+  // Check that the operands are the right type
+  Assert1(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) &&
+           cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()),
+          "Invalid operand types for FCmp instruction", &FC);
+  visitInstruction(FC);
+}
+
 void Verifier::visitShiftInst(ShiftInst &SI) {
   Assert1(SI.getType()->isInteger(),
           "Shift must return an integer result!", &SI);
   Assert1(SI.getType() == SI.getOperand(0)->getType(),
           "Shift return type must be same as first operand!", &SI);
Index: lib/Analysis/ValueNumbering.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Analysis/ValueNumbering.cpp,v
retrieving revision 1.21
diff -t -d -u -p -5 -r1.21 ValueNumbering.cpp
--- lib/Analysis/ValueNumbering.cpp	28 Aug 2006 00:42:29 -0000	1.21
+++ lib/Analysis/ValueNumbering.cpp	19 Nov 2006 07:32:59 -0000
@@ -73,10 +73,11 @@ namespace {
     std::vector<Value*> &RetVals;
     BVNImpl(std::vector<Value*> &RV) : RetVals(RV) {}
 
     void visitCastInst(CastInst &I);
     void visitGetElementPtrInst(GetElementPtrInst &I);
+    void visitCmpInst(CmpInst &I);
 
     void handleBinaryInst(Instruction &I);
     void visitBinaryOperator(Instruction &I)     { handleBinaryInst(I); }
     void visitShiftInst(Instruction &I)          { handleBinaryInst(I); }
     void visitExtractElementInst(Instruction &I) { handleBinaryInst(I); }
@@ -122,10 +123,34 @@ void BVNImpl::visitCastInst(CastInst &CI
         // These instructions are identical.  Add to list...
         RetVals.push_back(Other);
       }
 }
 
+void  BVNImpl::visitCmpInst(CmpInst &CI1) {
+  Value *LHS = CI1.getOperand(0);
+  for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
+       UI != UE; ++UI)
+    if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI))
+      // Check to see if this comparinstruction is not CI, but same opcode,
+      // same predicate, and in the same function.
+      if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() &&
+          CI2->getPredicate() == CI1.getPredicate() &&
+          CI2->getParent()->getParent() == CI1.getParent()->getParent())
+        // If the operands are the same
+        if ((CI2->getOperand(0) == CI1.getOperand(0) &&
+            CI2->getOperand(1) == CI1.getOperand(1)) ||
+            // Or the operands are reversed
+            ((CI2->getOperand(0) == CI1.getOperand(1) &&
+              CI2->getOperand(1) == CI1.getOperand(0)) &&
+            // And its commutative (equal or not equal)
+             ((isa<ICmpInst>(CI1) && cast<ICmpInst>(CI1).isCommutative()) ||
+              (isa<FCmpInst>(CI1) && cast<ICmpInst>(CI1).isCommutative()))))
+          // Then the instructiosn are identical, add to list.
+          RetVals.push_back(CI2);
+}
+
+
 
 // isIdenticalBinaryInst - Return true if the two binary instructions are
 // identical.
 //
 static inline bool isIdenticalBinaryInst(const Instruction &I1,
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp,v
retrieving revision 1.318
diff -t -d -u -p -5 -r1.318 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	15 Nov 2006 17:51:15 -0000	1.318
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	19 Nov 2006 07:33:03 -0000
@@ -539,10 +539,12 @@ public:
   void visitOr (User &I) { visitIntBinary(I, ISD::OR,  ISD::VOR); }
   void visitXor(User &I) { visitIntBinary(I, ISD::XOR, ISD::VXOR); }
   void visitShl(User &I) { visitShift(I, ISD::SHL); }
   void visitLShr(User &I) { visitShift(I, ISD::SRL); }
   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,
@@ -1440,10 +1442,64 @@ void SelectionDAGLowering::visitShift(Us
   Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
   
   setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
 }
 
+void SelectionDAGLowering::visitICmp(User &I) {
+  ICmpInst *IC = cast<ICmpInst>(&I);
+  SDOperand Op1 = getValue(IC->getOperand(0));
+  SDOperand Op2 = getValue(IC->getOperand(1));
+  ISD::CondCode Opcode;
+  switch (IC->getPredicate()) {
+    case ICmpInst::EQ  : Opcode = ISD::SETEQ; break;
+    case ICmpInst::NE  : Opcode = ISD::SETNE; break;
+    case ICmpInst::UGT : Opcode = ISD::SETUGT; break;
+    case ICmpInst::UGE : Opcode = ISD::SETUGE; break;
+    case ICmpInst::ULT : Opcode = ISD::SETULT; break;
+    case ICmpInst::ULE : Opcode = ISD::SETULE; break;
+    case ICmpInst::SGT : Opcode = ISD::SETGT; break;
+    case ICmpInst::SGE : Opcode = ISD::SETGE; break;
+    case ICmpInst::SLT : Opcode = ISD::SETLT; break;
+    case ICmpInst::SLE : Opcode = ISD::SETLE; break;
+    default:
+      assert(!"Invalid ICmp predicate value");
+      Opcode = ISD::SETEQ;
+      break;
+  }
+  setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode));
+}
+
+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::FALSE : Opcode = ISD::SETFALSE;
+    case FCmpInst::OEQ   : Opcode = ISD::SETOEQ;
+    case FCmpInst::OGT   : Opcode = ISD::SETOGT;
+    case FCmpInst::OGE   : Opcode = ISD::SETOGE;
+    case FCmpInst::OLT   : Opcode = ISD::SETOLT;
+    case FCmpInst::OLE   : Opcode = ISD::SETOLE;
+    case FCmpInst::ONE   : Opcode = ISD::SETONE;
+    case FCmpInst::ORD   : Opcode = ISD::SETO;
+    case FCmpInst::UNO   : Opcode = ISD::SETUO;
+    case FCmpInst::UEQ   : Opcode = ISD::SETUEQ;
+    case FCmpInst::UGT   : Opcode = ISD::SETUGT;
+    case FCmpInst::UGE   : Opcode = ISD::SETUGE;
+    case FCmpInst::ULT   : Opcode = ISD::SETULT;
+    case FCmpInst::ULE   : Opcode = ISD::SETULE;
+    case FCmpInst::UNE   : Opcode = ISD::SETUNE;
+    case FCmpInst::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) {
   SDOperand Op1 = getValue(I.getOperand(0));
   SDOperand Op2 = getValue(I.getOperand(1));
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to