diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 30d1623d80c28..164cbd7107132 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4418,6 +4418,10 @@ class TargetLowering : public TargetLoweringBase { SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT, SDValue Index) const; + /// Method for building the DAG expansion of ISD::[US][MIN|MAX]. This + /// method accepts integers as its arguments. + SDValue expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const; + /// Method for building the DAG expansion of ISD::[US][ADD|SUB]SAT. This /// method accepts integers as its arguments. SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index d3e95818af971..db44ea2553ced 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -812,6 +812,15 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl &Results) { return; } break; + case ISD::SMIN: + case ISD::SMAX: + case ISD::UMIN: + case ISD::UMAX: + if (SDValue Expanded = TLI.expandIntMINMAX(Node, DAG)) { + Results.push_back(Expanded); + return; + } + break; case ISD::UADDO: case ISD::USUBO: ExpandUADDSUBO(Node, Results); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 875a429253ca6..1d51773dc2d8e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -7458,6 +7458,31 @@ TargetLowering::getCanonicalIndexType(ISD::MemIndexType IndexType, EVT MemVT, return IndexType; } +SDValue TargetLowering::expandIntMINMAX(SDNode *Node, SelectionDAG &DAG) const { + SDValue Op0 = Node->getOperand(0); + SDValue Op1 = Node->getOperand(1); + EVT VT = Op0.getValueType(); + + // Expand Y = MAX(A, B) -> Y = (A > B) ? A : B + ISD::CondCode CC; + switch (Node->getOpcode()) { + default: llvm_unreachable("How did we get here?"); + case ISD::SMAX: CC = ISD::SETGT; break; + case ISD::SMIN: CC = ISD::SETLT; break; + case ISD::UMAX: CC = ISD::SETUGT; break; + case ISD::UMIN: CC = ISD::SETULT; break; + } + + // FIXME: Should really try to split the vector in case it's legal on a + // subvector. + if (VT.isVector() && !isOperationLegalOrCustom(ISD::VSELECT, VT)) + return DAG.UnrollVectorOp(Node); + + SDLoc DL(Node); + SDValue Cond = DAG.getSetCC(DL, VT, Op0, Op1, CC); + return DAG.getSelect(DL, VT, Cond, Op0, Op1); +} + SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const { unsigned Opcode = Node->getOpcode(); SDValue LHS = Node->getOperand(0); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 3587e0eb294c6..fcbe1330b5460 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -26975,18 +26975,8 @@ static SDValue LowerMINMAX(SDValue Op, SelectionDAG &DAG) { DAG.getNode(ISD::USUBSAT, DL, VT, N1, N0), N0); } - // Else, expand to a compare/select. - ISD::CondCode CC; - switch (Opcode) { - case ISD::SMIN: CC = ISD::CondCode::SETLT; break; - case ISD::SMAX: CC = ISD::CondCode::SETGT; break; - case ISD::UMIN: CC = ISD::CondCode::SETULT; break; - case ISD::UMAX: CC = ISD::CondCode::SETUGT; break; - default: llvm_unreachable("Unknown MINMAX opcode"); - } - - SDValue Cond = DAG.getSetCC(DL, VT, N0, N1, CC); - return DAG.getSelect(DL, VT, Cond, N0, N1); + // Default to expand. + return SDValue(); } static SDValue LowerMUL(SDValue Op, const X86Subtarget &Subtarget,