@@ -164,6 +164,12 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
164
164
case ISD::ROTR:
165
165
R = ScalarizeVecRes_BinOp (N);
166
166
break ;
167
+
168
+ case ISD::SCMP:
169
+ case ISD::UCMP:
170
+ R = ScalarizeVecRes_CMP (N);
171
+ break ;
172
+
167
173
case ISD::FMA:
168
174
case ISD::FSHL:
169
175
case ISD::FSHR:
@@ -213,6 +219,27 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
213
219
LHS.getValueType (), LHS, RHS, N->getFlags ());
214
220
}
215
221
222
+ SDValue DAGTypeLegalizer::ScalarizeVecRes_CMP (SDNode *N) {
223
+ SDLoc DL (N);
224
+
225
+ SDValue LHS = N->getOperand (0 );
226
+ SDValue RHS = N->getOperand (1 );
227
+ if (getTypeAction (LHS.getValueType ()) ==
228
+ TargetLowering::TypeScalarizeVector) {
229
+ LHS = GetScalarizedVector (LHS);
230
+ RHS = GetScalarizedVector (RHS);
231
+ } else {
232
+ EVT VT = LHS.getValueType ().getVectorElementType ();
233
+ LHS = DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, VT, LHS,
234
+ DAG.getVectorIdxConstant (0 , DL));
235
+ RHS = DAG.getNode (ISD::EXTRACT_VECTOR_ELT, DL, VT, RHS,
236
+ DAG.getVectorIdxConstant (0 , DL));
237
+ }
238
+
239
+ return DAG.getNode (N->getOpcode (), SDLoc (N),
240
+ N->getValueType (0 ).getVectorElementType (), LHS, RHS);
241
+ }
242
+
216
243
SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp (SDNode *N) {
217
244
SDValue Op0 = GetScalarizedVector (N->getOperand (0 ));
218
245
SDValue Op1 = GetScalarizedVector (N->getOperand (1 ));
@@ -741,6 +768,10 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
741
768
case ISD::VECREDUCE_SEQ_FMUL:
742
769
Res = ScalarizeVecOp_VECREDUCE_SEQ (N);
743
770
break ;
771
+ case ISD::SCMP:
772
+ case ISD::UCMP:
773
+ Res = ScalarizeVecOp_CMP (N);
774
+ break ;
744
775
}
745
776
746
777
// If the result is null, the sub-method took care of registering results etc.
@@ -961,6 +992,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N) {
961
992
AccOp, Op, N->getFlags ());
962
993
}
963
994
995
+ SDValue DAGTypeLegalizer::ScalarizeVecOp_CMP (SDNode *N) {
996
+ SDValue LHS = GetScalarizedVector (N->getOperand (0 ));
997
+ SDValue RHS = GetScalarizedVector (N->getOperand (1 ));
998
+ return DAG.getNode (N->getOpcode (), SDLoc (N), N->getValueType (0 ), LHS, RHS);
999
+ }
1000
+
964
1001
// ===----------------------------------------------------------------------===//
965
1002
// Result Vector Splitting
966
1003
// ===----------------------------------------------------------------------===//
@@ -1184,6 +1221,10 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
1184
1221
SplitVecRes_TernaryOp (N, Lo, Hi);
1185
1222
break ;
1186
1223
1224
+ case ISD::SCMP: case ISD::UCMP:
1225
+ SplitVecRes_CMP (N, Lo, Hi);
1226
+ break ;
1227
+
1187
1228
#define DAG_INSTRUCTION (NAME, NARG, ROUND_MODE, INTRINSIC, DAGN ) \
1188
1229
case ISD::STRICT_##DAGN:
1189
1230
#include " llvm/IR/ConstrainedOps.def"
@@ -1327,6 +1368,27 @@ void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo,
1327
1368
{Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1328
1369
}
1329
1370
1371
+ void DAGTypeLegalizer::SplitVecRes_CMP (SDNode *N, SDValue &Lo, SDValue &Hi) {
1372
+ LLVMContext &Ctxt = *DAG.getContext ();
1373
+ SDLoc dl (N);
1374
+
1375
+ SDValue LHS = N->getOperand (0 );
1376
+ SDValue RHS = N->getOperand (1 );
1377
+
1378
+ SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1379
+ if (getTypeAction (LHS.getValueType ()) == TargetLowering::TypeSplitVector) {
1380
+ GetSplitVector (LHS, LHSLo, LHSHi);
1381
+ GetSplitVector (RHS, RHSLo, RHSHi);
1382
+ } else {
1383
+ std::tie (LHSLo, LHSHi) = DAG.SplitVector (LHS, dl);
1384
+ std::tie (RHSLo, RHSHi) = DAG.SplitVector (RHS, dl);
1385
+ }
1386
+
1387
+ EVT SplitResVT = N->getValueType (0 ).getHalfNumVectorElementsVT (Ctxt);
1388
+ Lo = DAG.getNode (N->getOpcode (), dl, SplitResVT, LHSLo, RHSLo);
1389
+ Hi = DAG.getNode (N->getOpcode (), dl, SplitResVT, LHSHi, RHSHi);
1390
+ }
1391
+
1330
1392
void DAGTypeLegalizer::SplitVecRes_FIX (SDNode *N, SDValue &Lo, SDValue &Hi) {
1331
1393
SDValue LHSLo, LHSHi;
1332
1394
GetSplitVector (N->getOperand (0 ), LHSLo, LHSHi);
@@ -3054,6 +3116,11 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
3054
3116
Res = SplitVecOp_FPOpDifferentTypes (N);
3055
3117
break ;
3056
3118
3119
+ case ISD::SCMP:
3120
+ case ISD::UCMP:
3121
+ Res = SplitVecOp_CMP (N);
3122
+ break ;
3123
+
3057
3124
case ISD::ANY_EXTEND_VECTOR_INREG:
3058
3125
case ISD::SIGN_EXTEND_VECTOR_INREG:
3059
3126
case ISD::ZERO_EXTEND_VECTOR_INREG:
@@ -4043,6 +4110,25 @@ SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(SDNode *N) {
4043
4110
return DAG.getNode (ISD::CONCAT_VECTORS, DL, N->getValueType (0 ), Lo, Hi);
4044
4111
}
4045
4112
4113
+ SDValue DAGTypeLegalizer::SplitVecOp_CMP (SDNode *N) {
4114
+ LLVMContext &Ctxt = *DAG.getContext ();
4115
+ SDLoc dl (N);
4116
+
4117
+ SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4118
+ GetSplitVector (N->getOperand (0 ), LHSLo, LHSHi);
4119
+ GetSplitVector (N->getOperand (1 ), RHSLo, RHSHi);
4120
+
4121
+ EVT ResVT = N->getValueType (0 );
4122
+ ElementCount SplitOpEC = LHSLo.getValueType ().getVectorElementCount ();
4123
+ EVT NewResVT =
4124
+ EVT::getVectorVT (Ctxt, ResVT.getVectorElementType (), SplitOpEC);
4125
+
4126
+ SDValue Lo = DAG.getNode (N->getOpcode (), dl, NewResVT, LHSLo, RHSLo);
4127
+ SDValue Hi = DAG.getNode (N->getOpcode (), dl, NewResVT, LHSHi, RHSHi);
4128
+
4129
+ return DAG.getNode (ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
4130
+ }
4131
+
4046
4132
SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT (SDNode *N) {
4047
4133
EVT ResVT = N->getValueType (0 );
4048
4134
SDValue Lo, Hi;
@@ -4220,6 +4306,11 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
4220
4306
Res = WidenVecRes_Binary (N);
4221
4307
break ;
4222
4308
4309
+ case ISD::SCMP:
4310
+ case ISD::UCMP:
4311
+ Res = WidenVecRes_CMP (N);
4312
+ break ;
4313
+
4223
4314
case ISD::FPOW:
4224
4315
case ISD::FREM:
4225
4316
if (unrollExpandedOp ())
@@ -4426,6 +4517,53 @@ SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
4426
4517
{InOp1, InOp2, Mask, N->getOperand (3 )}, N->getFlags ());
4427
4518
}
4428
4519
4520
+ SDValue DAGTypeLegalizer::WidenVecRes_CMP (SDNode *N) {
4521
+ LLVMContext &Ctxt = *DAG.getContext ();
4522
+ SDLoc dl (N);
4523
+
4524
+ SDValue LHS = N->getOperand (0 );
4525
+ SDValue RHS = N->getOperand (1 );
4526
+ EVT OpVT = LHS.getValueType ();
4527
+ if (getTypeAction (OpVT) == TargetLowering::TypeWidenVector) {
4528
+ LHS = GetWidenedVector (LHS);
4529
+ RHS = GetWidenedVector (RHS);
4530
+ }
4531
+
4532
+ EVT WidenResVT = TLI.getTypeToTransformTo (Ctxt, N->getValueType (0 ));
4533
+ ElementCount WidenResEC = WidenResVT.getVectorElementCount ();
4534
+ EVT WidenResElementVT = WidenResVT.getVectorElementType ();
4535
+
4536
+ // At this point we know that the type of LHS and RHS will not require
4537
+ // widening any further, so we can use the current (updated) type of the
4538
+ // operands as the return type of the CMP node, and then extend/truncate
4539
+ // and resize it appropriately.
4540
+ EVT CmpRetTy = LHS.getValueType ();
4541
+ SDValue CMP = DAG.getNode (N->getOpcode (), dl, CmpRetTy, LHS, RHS);
4542
+ if (CmpRetTy.getVectorNumElements () < WidenResVT.getVectorNumElements ()) {
4543
+ EVT WideUndefVectorVT =
4544
+ EVT::getVectorVT (Ctxt, CmpRetTy.getVectorElementType (), WidenResEC);
4545
+ SDValue WideUndefValue = DAG.getUNDEF (WideUndefVectorVT);
4546
+ CMP = DAG.getNode (ISD::INSERT_SUBVECTOR, dl, WideUndefVectorVT,
4547
+ WideUndefValue, CMP, DAG.getVectorIdxConstant (0 , dl));
4548
+ } else if (CmpRetTy.getVectorNumElements () >
4549
+ WidenResVT.getVectorNumElements ()) {
4550
+ EVT NarrowedVecVT =
4551
+ EVT::getVectorVT (Ctxt, CmpRetTy.getVectorElementType (), WidenResEC);
4552
+ CMP = DAG.getNode (ISD::EXTRACT_SUBVECTOR, dl, NarrowedVecVT, CMP,
4553
+ DAG.getVectorIdxConstant (0 , dl));
4554
+ }
4555
+
4556
+ ISD::NodeType ExtendCode;
4557
+ if (CMP.getValueType ().getVectorElementType ().getSizeInBits () >
4558
+ WidenResElementVT.getSizeInBits ()) {
4559
+ ExtendCode = ISD::TRUNCATE;
4560
+ } else {
4561
+ ExtendCode =
4562
+ (N->getOpcode () == ISD::SCMP ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND);
4563
+ }
4564
+ return DAG.getNode (ExtendCode, dl, WidenResVT, CMP);
4565
+ }
4566
+
4429
4567
SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp (SDNode *N) {
4430
4568
// Binary op widening, but with an extra operand that shouldn't be widened.
4431
4569
SDLoc dl (N);
@@ -6129,6 +6267,11 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
6129
6267
Res = WidenVecOp_EXTEND (N);
6130
6268
break ;
6131
6269
6270
+ case ISD::SCMP:
6271
+ case ISD::UCMP:
6272
+ Res = WidenVecOp_CMP (N);
6273
+ break ;
6274
+
6132
6275
case ISD::FP_EXTEND:
6133
6276
case ISD::STRICT_FP_EXTEND:
6134
6277
case ISD::FP_ROUND:
@@ -6273,6 +6416,32 @@ SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) {
6273
6416
}
6274
6417
}
6275
6418
6419
+ SDValue DAGTypeLegalizer::WidenVecOp_CMP (SDNode *N) {
6420
+ SDLoc dl (N);
6421
+
6422
+ EVT OpVT = N->getOperand (0 ).getValueType ();
6423
+ EVT ResVT = N->getValueType (0 );
6424
+ SDValue LHS = GetWidenedVector (N->getOperand (0 ));
6425
+ SDValue RHS = GetWidenedVector (N->getOperand (1 ));
6426
+
6427
+ // 1. EXTRACT_SUBVECTOR
6428
+ // 2. SIGN_EXTEND/ZERO_EXTEND
6429
+ // 3. CMP
6430
+ LHS = DAG.getNode (ISD::EXTRACT_SUBVECTOR, dl, OpVT, LHS,
6431
+ DAG.getVectorIdxConstant (0 , dl));
6432
+ RHS = DAG.getNode (ISD::EXTRACT_SUBVECTOR, dl, OpVT, RHS,
6433
+ DAG.getVectorIdxConstant (0 , dl));
6434
+
6435
+ // At this point the result type is guaranteed to be valid, so we can use it
6436
+ // as the operand type by extending it appropriately
6437
+ ISD::NodeType ExtendOpcode =
6438
+ N->getOpcode () == ISD::SCMP ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
6439
+ LHS = DAG.getNode (ExtendOpcode, dl, ResVT, LHS);
6440
+ RHS = DAG.getNode (ExtendOpcode, dl, ResVT, RHS);
6441
+
6442
+ return DAG.getNode (N->getOpcode (), dl, ResVT, LHS, RHS);
6443
+ }
6444
+
6276
6445
SDValue DAGTypeLegalizer::WidenVecOp_UnrollVectorOp (SDNode *N) {
6277
6446
// The result (and first input) is legal, but the second input is illegal.
6278
6447
// We can't do much to fix that, so just unroll and let the extracts off of
0 commit comments