X86: Match pmin/pmax as a target specific dag combine. This occurs during vectorization.

Part of PR14667.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170908 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2012-12-21 17:46:58 +00:00
parent 38b06020db
commit 2556c6b4b6
3 changed files with 2867 additions and 3 deletions

View File

@ -14679,6 +14679,76 @@ static SDValue PerformEXTRACT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
/// \brief Matches a VSELECT onto min/max or return 0 if the node doesn't match.
static unsigned matchIntegerMINMAX(SDValue Cond, EVT VT, SDValue LHS,
SDValue RHS, SelectionDAG &DAG,
const X86Subtarget *Subtarget) {
if (!VT.isVector())
return 0;
switch (VT.getSimpleVT().SimpleTy) {
default: return 0;
case MVT::v32i8:
case MVT::v16i16:
case MVT::v8i32:
if (!Subtarget->hasAVX2())
return 0;
case MVT::v16i8:
case MVT::v8i16:
case MVT::v4i32:
if (!Subtarget->hasSSE2())
return 0;
}
// SSE2 has only a small subset of the operations.
bool hasUnsigned = Subtarget->hasSSE41() ||
(Subtarget->hasSSE2() && VT == MVT::v16i8);
bool hasSigned = Subtarget->hasSSE41() ||
(Subtarget->hasSSE2() && VT == MVT::v8i16);
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
// Check for x CC y ? x : y.
if (DAG.isEqualTo(LHS, Cond.getOperand(0)) &&
DAG.isEqualTo(RHS, Cond.getOperand(1))) {
switch (CC) {
default: break;
case ISD::SETULT:
case ISD::SETULE:
return hasUnsigned ? X86ISD::UMIN : 0;
case ISD::SETUGT:
case ISD::SETUGE:
return hasUnsigned ? X86ISD::UMAX : 0;
case ISD::SETLT:
case ISD::SETLE:
return hasSigned ? X86ISD::SMIN : 0;
case ISD::SETGT:
case ISD::SETGE:
return hasSigned ? X86ISD::SMAX : 0;
}
// Check for x CC y ? y : x -- a min/max with reversed arms.
} else if (DAG.isEqualTo(LHS, Cond.getOperand(1)) &&
DAG.isEqualTo(RHS, Cond.getOperand(0))) {
switch (CC) {
default: break;
case ISD::SETULT:
case ISD::SETULE:
return hasUnsigned ? X86ISD::UMAX : 0;
case ISD::SETUGT:
case ISD::SETUGE:
return hasUnsigned ? X86ISD::UMIN : 0;
case ISD::SETLT:
case ISD::SETLE:
return hasSigned ? X86ISD::SMAX : 0;
case ISD::SETGT:
case ISD::SETGE:
return hasSigned ? X86ISD::SMIN : 0;
}
}
return 0;
}
/// PerformSELECTCombine - Do target-specific dag combines on SELECT and VSELECT
/// nodes.
static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
@ -15018,6 +15088,13 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
}
}
// Try to match a min/max vector operation.
if (!DCI.isBeforeLegalize() &&
N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC)
if (unsigned Op = matchIntegerMINMAX(Cond, VT, LHS, RHS, DAG, Subtarget))
return DAG.getNode(Op, DL, N->getValueType(0), LHS, RHS);
// If we know that this node is legal then we know that it is going to be
// matched by one of the SSE/AVX BLEND instructions. These instructions only
// depend on the highest bit in each word. Try to use SimplifyDemandedBits

View File

@ -48,9 +48,8 @@ entry:
; CHECK: vpblendvb
; CHECK: vpblendvb %ymm
; CHECK: ret
define <32 x i8> @vpblendvb(<32 x i8> %x, <32 x i8> %y) {
%min_is_x = icmp ult <32 x i8> %x, %y
%min = select <32 x i1> %min_is_x, <32 x i8> %x, <32 x i8> %y
define <32 x i8> @vpblendvb(<32 x i1> %cond, <32 x i8> %x, <32 x i8> %y) {
%min = select <32 x i1> %cond, <32 x i8> %x, <32 x i8> %y
ret <32 x i8> %min
}

File diff suppressed because it is too large Load Diff