Skip to content

Commit 4a8d6b3

Browse files
committedAug 13, 2015
[X86][SSE] Use the general SMAX/SMIN/UMAX/UMIN pattern matching and remove the X86 implementation
Follow up to D10947 - D9746 added general SMAX/SMIN/UMAX/UMIN pattern matching to SelectionDAGBuilder::visitSelect. This patch removes the X86 implementation and improves the AVX1/AVX2 support to correctly lower 256-bit integer vectors. Differential Revision: http://reviews.llvm.org/D12006 llvm-svn: 244949
1 parent 361231e commit 4a8d6b3

File tree

1 file changed

+24
-116
lines changed

1 file changed

+24
-116
lines changed
 

‎llvm/lib/Target/X86/X86ISelLowering.cpp

+24-116
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,19 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
11981198
setOperationAction(ISD::MUL, MVT::v8i32, Custom);
11991199
setOperationAction(ISD::MUL, MVT::v16i16, Custom);
12001200
setOperationAction(ISD::MUL, MVT::v32i8, Custom);
1201+
1202+
setOperationAction(ISD::SMAX, MVT::v32i8, Custom);
1203+
setOperationAction(ISD::SMAX, MVT::v16i16, Custom);
1204+
setOperationAction(ISD::SMAX, MVT::v8i32, Custom);
1205+
setOperationAction(ISD::UMAX, MVT::v32i8, Custom);
1206+
setOperationAction(ISD::UMAX, MVT::v16i16, Custom);
1207+
setOperationAction(ISD::UMAX, MVT::v8i32, Custom);
1208+
setOperationAction(ISD::SMIN, MVT::v32i8, Custom);
1209+
setOperationAction(ISD::SMIN, MVT::v16i16, Custom);
1210+
setOperationAction(ISD::SMIN, MVT::v8i32, Custom);
1211+
setOperationAction(ISD::UMIN, MVT::v32i8, Custom);
1212+
setOperationAction(ISD::UMIN, MVT::v16i16, Custom);
1213+
setOperationAction(ISD::UMIN, MVT::v8i32, Custom);
12011214
}
12021215

12031216
// In the customized shift lowering, the legal cases in AVX2 will be
@@ -16881,6 +16894,13 @@ static SDValue LowerSUB(SDValue Op, SelectionDAG &DAG) {
1688116894
return Lower256IntArith(Op, DAG);
1688216895
}
1688316896

16897+
static SDValue LowerMINMAX(SDValue Op, SelectionDAG &DAG) {
16898+
assert(Op.getSimpleValueType().is256BitVector() &&
16899+
Op.getSimpleValueType().isInteger() &&
16900+
"Only handle AVX 256-bit vector integer operation");
16901+
return Lower256IntArith(Op, DAG);
16902+
}
16903+
1688416904
static SDValue LowerMUL(SDValue Op, const X86Subtarget *Subtarget,
1688516905
SelectionDAG &DAG) {
1688616906
SDLoc dl(Op);
@@ -18772,6 +18792,10 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1877218792
case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
1877318793
case ISD::ADD: return LowerADD(Op, DAG);
1877418794
case ISD::SUB: return LowerSUB(Op, DAG);
18795+
case ISD::SMAX:
18796+
case ISD::SMIN:
18797+
case ISD::UMAX:
18798+
case ISD::UMIN: return LowerMINMAX(Op, DAG);
1877518799
case ISD::FSINCOS: return LowerFSINCOS(Op, Subtarget, DAG);
1877618800
case ISD::MGATHER: return LowerMGATHER(Op, Subtarget, DAG);
1877718801
case ISD::MSCATTER: return LowerMSCATTER(Op, Subtarget, DAG);
@@ -22365,96 +22389,6 @@ static SDValue PerformEXTRACT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
2236522389
return SDValue();
2236622390
}
2236722391

22368-
/// \brief Matches a VSELECT onto min/max or return 0 if the node doesn't match.
22369-
static std::pair<unsigned, bool>
22370-
matchIntegerMINMAX(SDValue Cond, EVT VT, SDValue LHS, SDValue RHS,
22371-
SelectionDAG &DAG, const X86Subtarget *Subtarget) {
22372-
if (!VT.isVector())
22373-
return std::make_pair(0, false);
22374-
22375-
bool NeedSplit = false;
22376-
switch (VT.getSimpleVT().SimpleTy) {
22377-
default: return std::make_pair(0, false);
22378-
case MVT::v4i64:
22379-
case MVT::v2i64:
22380-
if (!Subtarget->hasVLX())
22381-
return std::make_pair(0, false);
22382-
break;
22383-
case MVT::v64i8:
22384-
case MVT::v32i16:
22385-
if (!Subtarget->hasBWI())
22386-
return std::make_pair(0, false);
22387-
break;
22388-
case MVT::v16i32:
22389-
case MVT::v8i64:
22390-
if (!Subtarget->hasAVX512())
22391-
return std::make_pair(0, false);
22392-
break;
22393-
case MVT::v32i8:
22394-
case MVT::v16i16:
22395-
case MVT::v8i32:
22396-
if (!Subtarget->hasAVX2())
22397-
NeedSplit = true;
22398-
if (!Subtarget->hasAVX())
22399-
return std::make_pair(0, false);
22400-
break;
22401-
case MVT::v16i8:
22402-
case MVT::v8i16:
22403-
case MVT::v4i32:
22404-
if (!Subtarget->hasSSE2())
22405-
return std::make_pair(0, false);
22406-
}
22407-
22408-
// SSE2 has only a small subset of the operations.
22409-
bool hasUnsigned = Subtarget->hasSSE41() ||
22410-
(Subtarget->hasSSE2() && VT == MVT::v16i8);
22411-
bool hasSigned = Subtarget->hasSSE41() ||
22412-
(Subtarget->hasSSE2() && VT == MVT::v8i16);
22413-
22414-
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
22415-
22416-
unsigned Opc = 0;
22417-
// Check for x CC y ? x : y.
22418-
if (DAG.isEqualTo(LHS, Cond.getOperand(0)) &&
22419-
DAG.isEqualTo(RHS, Cond.getOperand(1))) {
22420-
switch (CC) {
22421-
default: break;
22422-
case ISD::SETULT:
22423-
case ISD::SETULE:
22424-
Opc = hasUnsigned ? ISD::UMIN : 0; break;
22425-
case ISD::SETUGT:
22426-
case ISD::SETUGE:
22427-
Opc = hasUnsigned ? ISD::UMAX : 0; break;
22428-
case ISD::SETLT:
22429-
case ISD::SETLE:
22430-
Opc = hasSigned ? ISD::SMIN : 0; break;
22431-
case ISD::SETGT:
22432-
case ISD::SETGE:
22433-
Opc = hasSigned ? ISD::SMAX : 0; break;
22434-
}
22435-
// Check for x CC y ? y : x -- a min/max with reversed arms.
22436-
} else if (DAG.isEqualTo(LHS, Cond.getOperand(1)) &&
22437-
DAG.isEqualTo(RHS, Cond.getOperand(0))) {
22438-
switch (CC) {
22439-
default: break;
22440-
case ISD::SETULT:
22441-
case ISD::SETULE:
22442-
Opc = hasUnsigned ? ISD::UMAX : 0; break;
22443-
case ISD::SETUGT:
22444-
case ISD::SETUGE:
22445-
Opc = hasUnsigned ? ISD::UMIN : 0; break;
22446-
case ISD::SETLT:
22447-
case ISD::SETLE:
22448-
Opc = hasSigned ? ISD::SMAX : 0; break;
22449-
case ISD::SETGT:
22450-
case ISD::SETGE:
22451-
Opc = hasSigned ? ISD::SMIN : 0; break;
22452-
}
22453-
}
22454-
22455-
return std::make_pair(Opc, NeedSplit);
22456-
}
22457-
2245822392
static SDValue
2245922393
transformVSELECTtoBlendVECTOR_SHUFFLE(SDNode *N, SelectionDAG &DAG,
2246022394
const X86Subtarget *Subtarget) {
@@ -22864,32 +22798,6 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
2286422798
}
2286522799
}
2286622800

22867-
// Try to match a min/max vector operation.
22868-
if (N->getOpcode() == ISD::VSELECT && Cond.getOpcode() == ISD::SETCC) {
22869-
std::pair<unsigned, bool> ret = matchIntegerMINMAX(Cond, VT, LHS, RHS, DAG, Subtarget);
22870-
unsigned Opc = ret.first;
22871-
bool NeedSplit = ret.second;
22872-
22873-
if (Opc && NeedSplit) {
22874-
unsigned NumElems = VT.getVectorNumElements();
22875-
// Extract the LHS vectors
22876-
SDValue LHS1 = Extract128BitVector(LHS, 0, DAG, DL);
22877-
SDValue LHS2 = Extract128BitVector(LHS, NumElems/2, DAG, DL);
22878-
22879-
// Extract the RHS vectors
22880-
SDValue RHS1 = Extract128BitVector(RHS, 0, DAG, DL);
22881-
SDValue RHS2 = Extract128BitVector(RHS, NumElems/2, DAG, DL);
22882-
22883-
// Create min/max for each subvector
22884-
LHS = DAG.getNode(Opc, DL, LHS1.getValueType(), LHS1, RHS1);
22885-
RHS = DAG.getNode(Opc, DL, LHS2.getValueType(), LHS2, RHS2);
22886-
22887-
// Merge the result
22888-
return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, LHS, RHS);
22889-
} else if (Opc)
22890-
return DAG.getNode(Opc, DL, VT, LHS, RHS);
22891-
}
22892-
2289322801
// Simplify vector selection if condition value type matches vselect
2289422802
// operand type
2289522803
if (N->getOpcode() == ISD::VSELECT && CondVT == VT) {

0 commit comments

Comments
 (0)
Please sign in to comment.