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(); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits