@@ -3554,7 +3554,7 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
3554
3554
3555
3555
static SDValue splatPartsI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
3556
3556
SDValue Lo, SDValue Hi, SDValue VL,
3557
- SelectionDAG &DAG) {
3557
+ SelectionDAG &DAG, bool HasVendorXTHeadV ) {
3558
3558
if (!Passthru)
3559
3559
Passthru = DAG.getUNDEF(VT);
3560
3560
if (isa<ConstantSDNode>(Lo) && isa<ConstantSDNode>(Hi)) {
@@ -3563,7 +3563,9 @@ static SDValue splatPartsI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
3563
3563
// If Hi constant is all the same sign bit as Lo, lower this as a custom
3564
3564
// node in order to try and match RVV vector/scalar instructions.
3565
3565
if ((LoC >> 31) == HiC)
3566
- return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Lo, VL);
3566
+ return DAG.getNode(HasVendorXTHeadV ?
3567
+ RISCVISD::TH_VMV_V_X_VL : RISCVISD::VMV_V_X_VL,
3568
+ DL, VT, Passthru, Lo, VL);
3567
3569
3568
3570
// If vl is equal to XLEN_MAX and Hi constant is equal to Lo, we could use
3569
3571
// vmv.v.x whose EEW = 32 to lower it.
@@ -3572,8 +3574,8 @@ static SDValue splatPartsI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
3572
3574
// TODO: if vl <= min(VLMAX), we can also do this. But we could not
3573
3575
// access the subtarget here now.
3574
3576
auto InterVec = DAG.getNode(
3575
- RISCVISD::VMV_V_X_VL, DL, InterVT, DAG.getUNDEF(InterVT), Lo ,
3576
- DAG.getRegister(RISCV::X0, MVT::i32));
3577
+ HasVendorXTHeadV ? RISCVISD::TH_VMV_V_X_VL : RISCVISD::VMV_V_X_VL ,
3578
+ DL, InterVT, DAG.getUNDEF(InterVT), Lo, DAG.getRegister(RISCV::X0, MVT::i32));
3577
3579
return DAG.getNode(ISD::BITCAST, DL, VT, InterVec);
3578
3580
}
3579
3581
}
@@ -3588,11 +3590,11 @@ static SDValue splatPartsI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
3588
3590
// of the halves.
3589
3591
static SDValue splatSplitI64WithVL(const SDLoc &DL, MVT VT, SDValue Passthru,
3590
3592
SDValue Scalar, SDValue VL,
3591
- SelectionDAG &DAG) {
3593
+ SelectionDAG &DAG, bool HasVendorXTHeadV ) {
3592
3594
assert(Scalar.getValueType() == MVT::i64 && "Unexpected VT!");
3593
3595
SDValue Lo, Hi;
3594
3596
std::tie(Lo, Hi) = DAG.SplitScalar(Scalar, DL, MVT::i32, MVT::i32);
3595
- return splatPartsI64WithVL(DL, VT, Passthru, Lo, Hi, VL, DAG);
3597
+ return splatPartsI64WithVL(DL, VT, Passthru, Lo, Hi, VL, DAG, HasVendorXTHeadV );
3596
3598
}
3597
3599
3598
3600
// This function lowers a splat of a scalar operand Splat with the vector
@@ -3628,7 +3630,9 @@ static SDValue lowerScalarSplat(SDValue Passthru, SDValue Scalar, SDValue VL,
3628
3630
if (isOneConstant(VL) &&
3629
3631
(!Const || isNullConstant(Scalar) || !isInt<5>(Const->getSExtValue())))
3630
3632
return DAG.getNode(RISCVISD::VMV_S_X_VL, DL, VT, Passthru, Scalar, VL);
3631
- return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, Passthru, Scalar, VL);
3633
+ return DAG.getNode(
3634
+ Subtarget.hasVendorXTHeadV() ? RISCVISD::TH_VMV_V_X_VL : RISCVISD::VMV_V_X_VL,
3635
+ DL, VT, Passthru, Scalar, VL);
3632
3636
}
3633
3637
3634
3638
assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
@@ -3639,7 +3643,8 @@ static SDValue lowerScalarSplat(SDValue Passthru, SDValue Scalar, SDValue VL,
3639
3643
DAG.getConstant(0, DL, XLenVT), VL);
3640
3644
3641
3645
// Otherwise use the more complicated splatting algorithm.
3642
- return splatSplitI64WithVL(DL, VT, Passthru, Scalar, VL, DAG);
3646
+ return splatSplitI64WithVL(DL, VT, Passthru, Scalar, VL,
3647
+ DAG, Subtarget.hasVendorXTHeadV());
3643
3648
}
3644
3649
3645
3650
static MVT getLMUL1VT(MVT VT) {
@@ -6637,7 +6642,8 @@ SDValue RISCVTargetLowering::lowerSPLAT_VECTOR_PARTS(SDValue Op,
6637
6642
auto VL = getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).second;
6638
6643
6639
6644
SDValue Res =
6640
- splatPartsI64WithVL(DL, ContainerVT, SDValue(), Lo, Hi, VL, DAG);
6645
+ splatPartsI64WithVL(DL, ContainerVT, SDValue(), Lo, Hi, VL,
6646
+ DAG, Subtarget.hasVendorXTHeadV());
6641
6647
return convertFromScalableVector(VecVT, Res, DAG, Subtarget);
6642
6648
}
6643
6649
@@ -7369,7 +7375,8 @@ static SDValue lowerVectorIntrinsicScalars(SDValue Op, SelectionDAG &DAG,
7369
7375
// We need to convert the scalar to a splat vector.
7370
7376
SDValue VL = getVLOperand(Op);
7371
7377
assert(VL.getValueType() == XLenVT);
7372
- ScalarOp = splatSplitI64WithVL(DL, VT, SDValue(), ScalarOp, VL, DAG);
7378
+ ScalarOp = splatSplitI64WithVL(DL, VT, SDValue(), ScalarOp, VL,
7379
+ DAG, Subtarget.hasVendorXTHeadV());
7373
7380
return DAG.getNode(Op->getOpcode(), DL, Op->getVTList(), Operands);
7374
7381
}
7375
7382
@@ -7483,6 +7490,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
7483
7490
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, Op.getValueType(),
7484
7491
Op.getOperand(1), DAG.getConstant(0, DL, XLenVT));
7485
7492
case Intrinsic::riscv_vmv_v_x:
7493
+ case Intrinsic::riscv_th_vmv_v_x:
7486
7494
return lowerScalarSplat(Op.getOperand(1), Op.getOperand(2),
7487
7495
Op.getOperand(3), Op.getSimpleValueType(), DL, DAG,
7488
7496
Subtarget);
@@ -7519,7 +7527,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
7519
7527
SDValue Vec = Op.getOperand(1);
7520
7528
SDValue VL = getVLOperand(Op);
7521
7529
7522
- SDValue SplattedVal = splatSplitI64WithVL(DL, VT, SDValue(), Scalar, VL, DAG);
7530
+ SDValue SplattedVal = splatSplitI64WithVL(DL, VT, SDValue(), Scalar, VL,
7531
+ DAG, Subtarget.hasVendorXTHeadV());
7523
7532
if (Op.getOperand(1).isUndef())
7524
7533
return SplattedVal;
7525
7534
SDValue SplattedIdx =
@@ -16429,6 +16438,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
16429
16438
NODE_NAME_CASE(TH_SDD)
16430
16439
NODE_NAME_CASE(VMV_V_V_VL)
16431
16440
NODE_NAME_CASE(VMV_V_X_VL)
16441
+ NODE_NAME_CASE(TH_VMV_V_X_VL)
16432
16442
NODE_NAME_CASE(VFMV_V_F_VL)
16433
16443
NODE_NAME_CASE(VMV_X_S)
16434
16444
NODE_NAME_CASE(VMV_S_X_VL)
0 commit comments