[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Chris Lattner sabre at nondot.org
Tue Oct 3 23:57:21 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.267 -> 1.268
---
Log message:

Pattern match min/max nodes when we have sse.  This implements
CodeGen/X86/scalar_sse_minmax.ll


---
Diffs of the changes:  (+66 -0)

 X86ISelLowering.cpp |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.267 llvm/lib/Target/X86/X86ISelLowering.cpp:1.268
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.267	Tue Oct  3 19:56:09 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Wed Oct  4 01:57:07 2006
@@ -386,6 +386,7 @@
 
   // We have target-specific dag combine patterns for the following nodes:
   setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
+  setTargetDAGCombine(ISD::SELECT);
 
   computeRegisterProperties();
 
@@ -5355,6 +5356,69 @@
   }
 }
 
+/// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes.
+static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
+                                      const X86Subtarget *Subtarget) {
+  SDOperand Cond = N->getOperand(0);
+  
+  // If we have SSE[12] support, try to form min/max nodes.
+  if (Subtarget->hasSSE2() &&
+      (N->getValueType(0) == MVT::f32 || N->getValueType(0) == MVT::f64)) {
+    if (Cond.getOpcode() == ISD::SETCC) {
+      // Get the LHS/RHS of the select.
+      SDOperand LHS = N->getOperand(1);
+      SDOperand RHS = N->getOperand(2);
+      ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
+      
+      unsigned IntNo = 0;
+      if (LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
+        // (X olt Y) ? X : Y -> min
+        if (CC == ISD::SETOLT || CC == ISD::SETLT)
+          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
+                                                   Intrinsic::x86_sse2_min_sd;
+        // (X uge Y) ? X : Y -> max
+        if (CC == ISD::SETUGE || CC == ISD::SETGE)
+          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
+            Intrinsic::x86_sse2_max_sd;
+        // TODO: Handle more cases if unsafe math!
+      } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) {
+        // (X uge Y) ? Y : X -> min
+        if (CC == ISD::SETUGE || CC == ISD::SETGE)
+          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
+            Intrinsic::x86_sse2_min_sd;
+        // (X olt Y) ? Y : X -> max
+        if (CC == ISD::SETOLT || CC == ISD::SETLT)
+          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
+            Intrinsic::x86_sse2_max_sd;
+        // TODO: Handle more cases if unsafe math!
+      }
+      
+      // minss/maxss take a v4f32 operand.
+      if (IntNo) {
+        if (LHS.getValueType() == MVT::f32) {
+          LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, LHS);
+          RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, RHS);
+        } else {
+          LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, LHS);
+          RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, RHS);
+        }
+        
+        MVT::ValueType PtrTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
+        SDOperand IntNoN = DAG.getConstant(IntNo, PtrTy);
+        
+        SDOperand Val = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, LHS.getValueType(),
+                                    IntNoN, LHS, RHS);
+        return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getValueType(0), Val,
+                           DAG.getConstant(0, PtrTy));
+      }
+    }
+    
+  }
+
+  return SDOperand();
+}
+
+
 SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N, 
                                                DAGCombinerInfo &DCI) const {
   TargetMachine &TM = getTargetMachine();
@@ -5363,6 +5427,8 @@
   default: break;
   case ISD::VECTOR_SHUFFLE:
     return PerformShuffleCombine(N, DAG, Subtarget);
+  case ISD::SELECT:
+    return PerformSELECTCombine(N, DAG, Subtarget);
   }
 
   return SDOperand();






More information about the llvm-commits mailing list