add support for pattern matching 'neg'
authorChris Lattner <sabre@nondot.org>
Fri, 9 May 2008 05:20:27 +0000 (05:20 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 9 May 2008 05:20:27 +0000 (05:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50883 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/InstrTypes.h
include/llvm/Support/PatternMatch.h

index ef0ee89a3edac9631d30057936d984c6bd68803e..f735602ca8ce56a3e76574562b7931bdf06179c3 100644 (file)
@@ -236,10 +236,8 @@ public:
 
   /// swapOperands - Exchange the two operands to this instruction.
   /// This instruction is safe to use on any binary instruction and
-  /// does not modify the semantics of the instruction.  If the
-  /// instruction is order dependent (SetLT f.e.) the opcode is
-  /// changed.  If the instruction cannot be reversed (ie, it's a Div),
-  /// then return true.
+  /// does not modify the semantics of the instruction.  If the instruction
+  /// cannot be reversed (ie, it's a Div), then return true.
   ///
   bool swapOperands();
 
index ca558821021cf55433af008b1508e91d88ee53e4..a3951e2dd39d59c44b43bf40b2b95cf7ce98b620 100644 (file)
@@ -385,6 +385,35 @@ template<typename LHS>
 inline not_match<LHS> m_Not(const LHS &L) { return L; }
 
 
+template<typename LHS_t>
+struct neg_match {
+  LHS_t L;
+  
+  neg_match(const LHS_t &LHS) : L(LHS) {}
+  
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Instruction *I = dyn_cast<Instruction>(V))
+      if (I->getOpcode() == Instruction::Sub)
+        return matchIfNeg(I->getOperand(0), I->getOperand(1));
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+      if (CE->getOpcode() == Instruction::Sub)
+        return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+      return L.match(ConstantExpr::getNeg(CI));
+    return false;
+  }
+private:
+  bool matchIfNeg(Value *LHS, Value *RHS) {
+    return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
+           L.match(RHS);
+  }
+};
+
+template<typename LHS>
+inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
+
+
 //===----------------------------------------------------------------------===//
 // Matchers for control flow
 //