Skip to content

Commit 332eb5f

Browse files
authored
[RISCV][GISel] Support select vx, vf form rvv intrinsics (#157398)
For vx form, we legalize it with widen scalar. And for vf form, we select the right register bank.
1 parent dd669c3 commit 332eb5f

File tree

7 files changed

+3333
-76
lines changed

7 files changed

+3333
-76
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 89 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class RISCVVIntrinsic {
126126
Intrinsic IntrinsicID = !cast<Intrinsic>(NAME);
127127
bits<4> ScalarOperand = NoScalarOperand;
128128
bits<5> VLOperand = NoVLOperand;
129+
bit IsFPIntrinsic = 0;
129130
}
130131

131132
let TargetPrefix = "riscv" in {
@@ -1442,14 +1443,15 @@ let TargetPrefix = "riscv" in {
14421443
defm vwmaccus : RISCVTernaryWide;
14431444
defm vwmaccsu : RISCVTernaryWide;
14441445

1445-
defm vfadd : RISCVBinaryAAXRoundingMode;
1446-
defm vfsub : RISCVBinaryAAXRoundingMode;
1447-
defm vfrsub : RISCVBinaryAAXRoundingMode;
1448-
1449-
defm vfwadd : RISCVBinaryABXRoundingMode;
1450-
defm vfwsub : RISCVBinaryABXRoundingMode;
1451-
defm vfwadd_w : RISCVBinaryAAXRoundingMode;
1452-
defm vfwsub_w : RISCVBinaryAAXRoundingMode;
1446+
let IsFPIntrinsic = 1 in {
1447+
defm vfadd : RISCVBinaryAAXRoundingMode;
1448+
defm vfsub : RISCVBinaryAAXRoundingMode;
1449+
defm vfrsub : RISCVBinaryAAXRoundingMode;
1450+
defm vfwadd : RISCVBinaryABXRoundingMode;
1451+
defm vfwsub : RISCVBinaryABXRoundingMode;
1452+
defm vfwadd_w : RISCVBinaryAAXRoundingMode;
1453+
defm vfwsub_w : RISCVBinaryAAXRoundingMode;
1454+
}
14531455

14541456
defm vsaddu : RISCVSaturatingBinaryAAX;
14551457
defm vsadd : RISCVSaturatingBinaryAAX;
@@ -1484,6 +1486,7 @@ let TargetPrefix = "riscv" in {
14841486
llvm_anyint_ty],
14851487
[IntrNoMem]>, RISCVVIntrinsic {
14861488
let VLOperand = 2;
1489+
let IsFPIntrinsic = 1;
14871490
}
14881491

14891492
def int_riscv_vmv_x_s : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
@@ -1506,51 +1509,57 @@ let TargetPrefix = "riscv" in {
15061509
llvm_anyint_ty],
15071510
[IntrNoMem]>, RISCVVIntrinsic {
15081511
let VLOperand = 2;
1512+
let IsFPIntrinsic = 1;
15091513
}
15101514

1511-
defm vfmul : RISCVBinaryAAXRoundingMode;
1512-
defm vfdiv : RISCVBinaryAAXRoundingMode;
1513-
defm vfrdiv : RISCVBinaryAAXRoundingMode;
1515+
let IsFPIntrinsic = 1 in {
1516+
defm vfmul : RISCVBinaryAAXRoundingMode;
1517+
defm vfdiv : RISCVBinaryAAXRoundingMode;
1518+
defm vfrdiv : RISCVBinaryAAXRoundingMode;
15141519

1515-
defm vfwmul : RISCVBinaryABXRoundingMode;
1520+
defm vfwmul : RISCVBinaryABXRoundingMode;
15161521

1517-
defm vfmacc : RISCVTernaryAAXARoundingMode;
1518-
defm vfnmacc : RISCVTernaryAAXARoundingMode;
1519-
defm vfmsac : RISCVTernaryAAXARoundingMode;
1520-
defm vfnmsac : RISCVTernaryAAXARoundingMode;
1521-
defm vfmadd : RISCVTernaryAAXARoundingMode;
1522-
defm vfnmadd : RISCVTernaryAAXARoundingMode;
1523-
defm vfmsub : RISCVTernaryAAXARoundingMode;
1524-
defm vfnmsub : RISCVTernaryAAXARoundingMode;
1522+
defm vfmacc : RISCVTernaryAAXARoundingMode;
1523+
defm vfnmacc : RISCVTernaryAAXARoundingMode;
1524+
defm vfmsac : RISCVTernaryAAXARoundingMode;
1525+
defm vfnmsac : RISCVTernaryAAXARoundingMode;
1526+
defm vfmadd : RISCVTernaryAAXARoundingMode;
1527+
defm vfnmadd : RISCVTernaryAAXARoundingMode;
1528+
defm vfmsub : RISCVTernaryAAXARoundingMode;
1529+
defm vfnmsub : RISCVTernaryAAXARoundingMode;
15251530

1526-
defm vfwmacc : RISCVTernaryWideRoundingMode;
1527-
defm vfwmaccbf16 : RISCVTernaryWideRoundingMode;
1528-
defm vfwnmacc : RISCVTernaryWideRoundingMode;
1529-
defm vfwmsac : RISCVTernaryWideRoundingMode;
1530-
defm vfwnmsac : RISCVTernaryWideRoundingMode;
1531+
defm vfwmacc : RISCVTernaryWideRoundingMode;
1532+
defm vfwmaccbf16 : RISCVTernaryWideRoundingMode;
1533+
defm vfwnmacc : RISCVTernaryWideRoundingMode;
1534+
defm vfwmsac : RISCVTernaryWideRoundingMode;
1535+
defm vfwnmsac : RISCVTernaryWideRoundingMode;
15311536

1532-
defm vfsqrt : RISCVUnaryAARoundingMode;
1533-
defm vfrsqrt7 : RISCVUnaryAA;
1534-
defm vfrec7 : RISCVUnaryAARoundingMode;
1537+
defm vfsqrt : RISCVUnaryAARoundingMode;
1538+
defm vfrsqrt7 : RISCVUnaryAA;
1539+
defm vfrec7 : RISCVUnaryAARoundingMode;
15351540

1536-
defm vfmin : RISCVBinaryAAX;
1537-
defm vfmax : RISCVBinaryAAX;
1541+
defm vfmin : RISCVBinaryAAX;
1542+
defm vfmax : RISCVBinaryAAX;
15381543

1539-
defm vfsgnj : RISCVBinaryAAX;
1540-
defm vfsgnjn : RISCVBinaryAAX;
1541-
defm vfsgnjx : RISCVBinaryAAX;
1544+
defm vfsgnj : RISCVBinaryAAX;
1545+
defm vfsgnjn : RISCVBinaryAAX;
1546+
defm vfsgnjx : RISCVBinaryAAX;
15421547

1543-
defm vfclass : RISCVClassify;
1548+
defm vfclass : RISCVClassify;
15441549

1545-
defm vfmerge : RISCVBinaryWithV0;
1550+
defm vfmerge : RISCVBinaryWithV0;
1551+
}
15461552

15471553
defm vslideup : RVVSlide;
15481554
defm vslidedown : RVVSlide;
15491555

15501556
defm vslide1up : RISCVBinaryAAX;
15511557
defm vslide1down : RISCVBinaryAAX;
1552-
defm vfslide1up : RISCVBinaryAAX;
1553-
defm vfslide1down : RISCVBinaryAAX;
1558+
1559+
let IsFPIntrinsic = 1 in {
1560+
defm vfslide1up : RISCVBinaryAAX;
1561+
defm vfslide1down : RISCVBinaryAAX;
1562+
}
15541563

15551564
defm vrgather_vv : RISCVRGatherVV;
15561565
defm vrgather_vx : RISCVRGatherVX;
@@ -1571,12 +1580,14 @@ let TargetPrefix = "riscv" in {
15711580
defm vnclipu : RISCVSaturatingBinaryABShiftRoundingMode;
15721581
defm vnclip : RISCVSaturatingBinaryABShiftRoundingMode;
15731582

1574-
defm vmfeq : RISCVCompare;
1575-
defm vmfne : RISCVCompare;
1576-
defm vmflt : RISCVCompare;
1577-
defm vmfle : RISCVCompare;
1578-
defm vmfgt : RISCVCompare;
1579-
defm vmfge : RISCVCompare;
1583+
let IsFPIntrinsic = 1 in {
1584+
defm vmfeq : RISCVCompare;
1585+
defm vmfne : RISCVCompare;
1586+
defm vmflt : RISCVCompare;
1587+
defm vmfle : RISCVCompare;
1588+
defm vmfgt : RISCVCompare;
1589+
defm vmfge : RISCVCompare;
1590+
}
15801591

15811592
defm vredsum : RISCVReduction;
15821593
defm vredand : RISCVReduction;
@@ -1590,13 +1601,15 @@ let TargetPrefix = "riscv" in {
15901601
defm vwredsumu : RISCVReduction;
15911602
defm vwredsum : RISCVReduction;
15921603

1593-
defm vfredosum : RISCVReductionRoundingMode;
1594-
defm vfredusum : RISCVReductionRoundingMode;
1595-
defm vfredmin : RISCVReduction;
1596-
defm vfredmax : RISCVReduction;
1604+
let IsFPIntrinsic = 1 in {
1605+
defm vfredosum : RISCVReductionRoundingMode;
1606+
defm vfredusum : RISCVReductionRoundingMode;
1607+
defm vfredmin : RISCVReduction;
1608+
defm vfredmax : RISCVReduction;
15971609

1598-
defm vfwredusum : RISCVReductionRoundingMode;
1599-
defm vfwredosum : RISCVReductionRoundingMode;
1610+
defm vfwredusum : RISCVReductionRoundingMode;
1611+
defm vfwredosum : RISCVReductionRoundingMode;
1612+
}
16001613

16011614
def int_riscv_vmand: RISCVBinaryAAAUnMasked;
16021615
def int_riscv_vmnand: RISCVBinaryAAAUnMasked;
@@ -1615,31 +1628,33 @@ let TargetPrefix = "riscv" in {
16151628
defm vmsof : RISCVMaskedUnaryMOut;
16161629
defm vmsif : RISCVMaskedUnaryMOut;
16171630

1618-
defm vfcvt_xu_f_v : RISCVConversionRoundingMode;
1619-
defm vfcvt_x_f_v : RISCVConversionRoundingMode;
1620-
defm vfcvt_rtz_xu_f_v : RISCVConversion;
1621-
defm vfcvt_rtz_x_f_v : RISCVConversion;
1622-
defm vfcvt_f_xu_v : RISCVConversionRoundingMode;
1623-
defm vfcvt_f_x_v : RISCVConversionRoundingMode;
1624-
1625-
defm vfwcvt_f_xu_v : RISCVConversion;
1626-
defm vfwcvt_f_x_v : RISCVConversion;
1627-
defm vfwcvt_xu_f_v : RISCVConversionRoundingMode;
1628-
defm vfwcvt_x_f_v : RISCVConversionRoundingMode;
1629-
defm vfwcvt_rtz_xu_f_v : RISCVConversion;
1630-
defm vfwcvt_rtz_x_f_v : RISCVConversion;
1631-
defm vfwcvt_f_f_v : RISCVConversion;
1632-
defm vfwcvtbf16_f_f_v : RISCVConversion;
1633-
1634-
defm vfncvt_f_xu_w : RISCVConversionRoundingMode;
1635-
defm vfncvt_f_x_w : RISCVConversionRoundingMode;
1636-
defm vfncvt_xu_f_w : RISCVConversionRoundingMode;
1637-
defm vfncvt_x_f_w : RISCVConversionRoundingMode;
1638-
defm vfncvt_rtz_xu_f_w : RISCVConversion;
1639-
defm vfncvt_rtz_x_f_w : RISCVConversion;
1640-
defm vfncvt_f_f_w : RISCVConversionRoundingMode;
1641-
defm vfncvtbf16_f_f_w : RISCVConversionRoundingMode;
1642-
defm vfncvt_rod_f_f_w : RISCVConversion;
1631+
let IsFPIntrinsic = 1 in {
1632+
defm vfcvt_xu_f_v : RISCVConversionRoundingMode;
1633+
defm vfcvt_x_f_v : RISCVConversionRoundingMode;
1634+
defm vfcvt_rtz_xu_f_v : RISCVConversion;
1635+
defm vfcvt_rtz_x_f_v : RISCVConversion;
1636+
defm vfcvt_f_xu_v : RISCVConversionRoundingMode;
1637+
defm vfcvt_f_x_v : RISCVConversionRoundingMode;
1638+
1639+
defm vfwcvt_f_xu_v : RISCVConversion;
1640+
defm vfwcvt_f_x_v : RISCVConversion;
1641+
defm vfwcvt_xu_f_v : RISCVConversionRoundingMode;
1642+
defm vfwcvt_x_f_v : RISCVConversionRoundingMode;
1643+
defm vfwcvt_rtz_xu_f_v : RISCVConversion;
1644+
defm vfwcvt_rtz_x_f_v : RISCVConversion;
1645+
defm vfwcvt_f_f_v : RISCVConversion;
1646+
defm vfwcvtbf16_f_f_v : RISCVConversion;
1647+
1648+
defm vfncvt_f_xu_w : RISCVConversionRoundingMode;
1649+
defm vfncvt_f_x_w : RISCVConversionRoundingMode;
1650+
defm vfncvt_xu_f_w : RISCVConversionRoundingMode;
1651+
defm vfncvt_x_f_w : RISCVConversionRoundingMode;
1652+
defm vfncvt_rtz_xu_f_w : RISCVConversion;
1653+
defm vfncvt_rtz_x_f_w : RISCVConversion;
1654+
defm vfncvt_f_f_w : RISCVConversionRoundingMode;
1655+
defm vfncvtbf16_f_f_w : RISCVConversionRoundingMode;
1656+
defm vfncvt_rod_f_f_w : RISCVConversion;
1657+
}
16431658

16441659
// Output: (vector)
16451660
// Input: (passthru, mask type input, vl)

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,29 @@ bool RISCVLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
725725
MachineInstr &MI) const {
726726
Intrinsic::ID IntrinsicID = cast<GIntrinsic>(MI).getIntrinsicID();
727727

728-
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID))
728+
if (const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II =
729+
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
730+
if (II->hasScalarOperand() && !II->IsFPIntrinsic) {
731+
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
732+
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
733+
734+
auto OldScalar = MI.getOperand(II->ScalarOperand + 2).getReg();
735+
// Legalize integer vx form intrinsic.
736+
if (MRI.getType(OldScalar).isScalar()) {
737+
if (MRI.getType(OldScalar).getSizeInBits() < sXLen.getSizeInBits()) {
738+
Helper.Observer.changingInstr(MI);
739+
Helper.widenScalarSrc(MI, sXLen, II->ScalarOperand + 2,
740+
TargetOpcode::G_ANYEXT);
741+
Helper.Observer.changedInstr(MI);
742+
} else if (MRI.getType(OldScalar).getSizeInBits() >
743+
sXLen.getSizeInBits()) {
744+
// TODO: i64 in riscv32.
745+
return false;
746+
}
747+
}
748+
}
729749
return true;
750+
}
730751

731752
switch (IntrinsicID) {
732753
default:

llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,33 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
500500
OpdsMapping[1] = GPRValueMapping;
501501
break;
502502
}
503+
case TargetOpcode::G_INTRINSIC: {
504+
Intrinsic::ID IntrinsicID = cast<GIntrinsic>(MI).getIntrinsicID();
505+
506+
if (const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II =
507+
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
508+
unsigned ScalarIdx = -1;
509+
if (II->hasScalarOperand()) {
510+
ScalarIdx = II->ScalarOperand + 2;
511+
}
512+
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
513+
const MachineOperand &MO = MI.getOperand(Idx);
514+
if (!MO.isReg())
515+
continue;
516+
LLT Ty = MRI.getType(MO.getReg());
517+
if (Ty.isVector()) {
518+
OpdsMapping[Idx] =
519+
getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
520+
} else if (II->IsFPIntrinsic && ScalarIdx == Idx) {
521+
// Chose the right FPR for scalar operand of RVV intrinsics.
522+
OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits());
523+
} else {
524+
OpdsMapping[Idx] = GPRValueMapping;
525+
}
526+
}
527+
}
528+
break;
529+
}
503530
default:
504531
// By default map all scalars to GPR.
505532
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ struct RISCVVIntrinsicInfo {
642642
unsigned IntrinsicID;
643643
uint8_t ScalarOperand;
644644
uint8_t VLOperand;
645+
bool IsFPIntrinsic;
645646
bool hasScalarOperand() const {
646647
// 0xF is not valid. See NoScalarOperand in IntrinsicsRISCV.td.
647648
return ScalarOperand != 0xF;

llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ def RISCVVInversePseudosTable : GenericTable {
575575
def RISCVVIntrinsicsTable : GenericTable {
576576
let FilterClass = "RISCVVIntrinsic";
577577
let CppTypeName = "RISCVVIntrinsicInfo";
578-
let Fields = ["IntrinsicID", "ScalarOperand", "VLOperand"];
578+
let Fields = ["IntrinsicID", "ScalarOperand", "VLOperand", "IsFPIntrinsic"];
579579
let PrimaryKey = ["IntrinsicID"];
580580
let PrimaryKeyName = "getRISCVVIntrinsicInfo";
581581
}

0 commit comments

Comments
 (0)