From 4a397e0e9411cb32db242487c633c849e5794ed8 Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Mon, 30 Jan 2006 03:51:45 +0000
Subject: [PATCH] Implement isMaskedValueZeroForTargetNode for the various v8
 selectcc nodes, allowing redundant and's to be eliminated by the dag
 combiner.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25800 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Target/Sparc/SparcISelDAGToDAG.cpp     | 26 ++++++++++++++++++++++
 lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp | 26 ++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index 62062185201..099c2e5ed6d 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -57,6 +57,14 @@ namespace {
   public:
     SparcV8TargetLowering(TargetMachine &TM);
     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    
+    /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
+    /// be zero. Op is expected to be a target specific node. Used by DAG
+    /// combiner.
+    virtual bool isMaskedValueZeroForTargetNode(const SDOperand &Op,
+                                                uint64_t Mask,
+                                                MVIZFnPtr MVIZ) const;
+    
     virtual std::vector<SDOperand>
       LowerArguments(Function &F, SelectionDAG &DAG);
     virtual std::pair<SDOperand, SDOperand>
@@ -191,6 +199,24 @@ const char *SparcV8TargetLowering::getTargetNodeName(unsigned Opcode) const {
   }
 }
 
+/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
+/// be zero. Op is expected to be a target specific node. Used by DAG
+/// combiner.
+bool SparcV8TargetLowering::
+isMaskedValueZeroForTargetNode(const SDOperand &Op, uint64_t Mask,
+                               MVIZFnPtr MVIZ) const {
+  switch (Op.getOpcode()) {
+  default: return false; 
+  case V8ISD::SELECT_ICC:
+  case V8ISD::SELECT_FCC:
+    assert(MVT::isInteger(Op.getValueType()) && "Not an integer select!");
+    // These operations are masked zero if both the left and the right are zero.
+    return MVIZ(Op.getOperand(0), Mask, *this) &&
+           MVIZ(Op.getOperand(1), Mask, *this);
+  }
+}
+
+
 /// LowerArguments - V8 uses a very simple ABI, where all values are passed in
 /// either one or two GPRs, including FP values.  TODO: we should pass FP values
 /// in FP registers for fastcc functions.
diff --git a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
index 62062185201..099c2e5ed6d 100644
--- a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
+++ b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
@@ -57,6 +57,14 @@ namespace {
   public:
     SparcV8TargetLowering(TargetMachine &TM);
     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    
+    /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
+    /// be zero. Op is expected to be a target specific node. Used by DAG
+    /// combiner.
+    virtual bool isMaskedValueZeroForTargetNode(const SDOperand &Op,
+                                                uint64_t Mask,
+                                                MVIZFnPtr MVIZ) const;
+    
     virtual std::vector<SDOperand>
       LowerArguments(Function &F, SelectionDAG &DAG);
     virtual std::pair<SDOperand, SDOperand>
@@ -191,6 +199,24 @@ const char *SparcV8TargetLowering::getTargetNodeName(unsigned Opcode) const {
   }
 }
 
+/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
+/// be zero. Op is expected to be a target specific node. Used by DAG
+/// combiner.
+bool SparcV8TargetLowering::
+isMaskedValueZeroForTargetNode(const SDOperand &Op, uint64_t Mask,
+                               MVIZFnPtr MVIZ) const {
+  switch (Op.getOpcode()) {
+  default: return false; 
+  case V8ISD::SELECT_ICC:
+  case V8ISD::SELECT_FCC:
+    assert(MVT::isInteger(Op.getValueType()) && "Not an integer select!");
+    // These operations are masked zero if both the left and the right are zero.
+    return MVIZ(Op.getOperand(0), Mask, *this) &&
+           MVIZ(Op.getOperand(1), Mask, *this);
+  }
+}
+
+
 /// LowerArguments - V8 uses a very simple ABI, where all values are passed in
 /// either one or two GPRs, including FP values.  TODO: we should pass FP values
 /// in FP registers for fastcc functions.