@@ -1198,6 +1198,19 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
1198
1198
setOperationAction(ISD::MUL, MVT::v8i32, Custom);
1199
1199
setOperationAction(ISD::MUL, MVT::v16i16, Custom);
1200
1200
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);
1201
1214
}
1202
1215
1203
1216
// In the customized shift lowering, the legal cases in AVX2 will be
@@ -16881,6 +16894,13 @@ static SDValue LowerSUB(SDValue Op, SelectionDAG &DAG) {
16881
16894
return Lower256IntArith(Op, DAG);
16882
16895
}
16883
16896
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
+
16884
16904
static SDValue LowerMUL(SDValue Op, const X86Subtarget *Subtarget,
16885
16905
SelectionDAG &DAG) {
16886
16906
SDLoc dl(Op);
@@ -18772,6 +18792,10 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
18772
18792
case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
18773
18793
case ISD::ADD: return LowerADD(Op, DAG);
18774
18794
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);
18775
18799
case ISD::FSINCOS: return LowerFSINCOS(Op, Subtarget, DAG);
18776
18800
case ISD::MGATHER: return LowerMGATHER(Op, Subtarget, DAG);
18777
18801
case ISD::MSCATTER: return LowerMSCATTER(Op, Subtarget, DAG);
@@ -22365,96 +22389,6 @@ static SDValue PerformEXTRACT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
22365
22389
return SDValue();
22366
22390
}
22367
22391
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
-
22458
22392
static SDValue
22459
22393
transformVSELECTtoBlendVECTOR_SHUFFLE(SDNode *N, SelectionDAG &DAG,
22460
22394
const X86Subtarget *Subtarget) {
@@ -22864,32 +22798,6 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
22864
22798
}
22865
22799
}
22866
22800
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
-
22893
22801
// Simplify vector selection if condition value type matches vselect
22894
22802
// operand type
22895
22803
if (N->getOpcode() == ISD::VSELECT && CondVT == VT) {
0 commit comments