Skip to content

Commit 290074a

Browse files
committed
[llvm][RISCV] Support RISCV vector tuple CodeGen and Calling Convention
This patch handles target lowering and calling convention. For target lowering, the vector tuple type represented as multiple scalable vectors is now changed to a single `MVT`, each `MVT` has a corresponding register class. The load/store of vector tuples are handled as the same way but need another vector insert/extract instructions to get sub-register group. Inline assembly constraint for vector tuple type can directly be modeled as "vr" which is identical to normal vector registers. For calling convention, it no longer needs an alternative algorithm to handle register allocation, this makes the code easier to maintain and read.
1 parent 6fda19d commit 290074a

40 files changed

+101727
-107264
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7250,7 +7250,7 @@ static std::optional<EVT> findMemType(SelectionDAG &DAG,
72507250
// element type and is evenly divisible with the WidenVT.
72517251
for (EVT MemVT : reverse(MVT::vector_valuetypes())) {
72527252
// Skip vector MVTs which don't match the scalable property of WidenVT.
7253-
if (Scalable != MemVT.isScalableVector())
7253+
if (Scalable != MemVT.isScalableVector() || MemVT.isRISCVVectorTuple())
72547254
continue;
72557255
unsigned MemVTWidth = MemVT.getSizeInBits().getKnownMinValue();
72567256
auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7235,17 +7235,19 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
72357235
EVT N1VT = N1.getValueType();
72367236
assert(VT.isVector() && N1VT.isVector() &&
72377237
"Extract subvector VTs must be vectors!");
7238-
assert(VT.getVectorElementType() == N1VT.getVectorElementType() &&
7239-
"Extract subvector VTs must have the same element type!");
7240-
assert((VT.isFixedLengthVector() || N1VT.isScalableVector()) &&
7238+
if (!N1VT.isRISCVVectorTuple())
7239+
assert(VT.getVectorElementType() == N1VT.getVectorElementType() &&
7240+
"Extract subvector VTs must have the same element type!");
7241+
assert((VT.isFixedLengthVector() || N1VT.isScalableVector() ||
7242+
N1VT.isRISCVVectorTuple()) &&
72417243
"Cannot extract a scalable vector from a fixed length vector!");
72427244
assert((VT.isScalableVector() != N1VT.isScalableVector() ||
72437245
VT.getVectorMinNumElements() <= N1VT.getVectorMinNumElements()) &&
72447246
"Extract subvector must be from larger vector to smaller vector!");
72457247
assert(N2C && "Extract subvector index must be a constant");
72467248
assert((VT.isScalableVector() != N1VT.isScalableVector() ||
7247-
(VT.getVectorMinNumElements() + N2C->getZExtValue()) <=
7248-
N1VT.getVectorMinNumElements()) &&
7249+
((N1VT.isRISCVVectorTuple() ? 0 : VT.getVectorMinNumElements()) +
7250+
N2C->getZExtValue()) <= N1VT.getVectorMinNumElements()) &&
72497251
"Extract subvector overflow!");
72507252
assert(N2C->getAPIntValue().getBitWidth() ==
72517253
TLI->getVectorIdxTy(getDataLayout()).getFixedSizeInBits() &&
@@ -7468,18 +7470,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
74687470
"Dest and insert subvector source types must match!");
74697471
assert(VT.isVector() && N2VT.isVector() &&
74707472
"Insert subvector VTs must be vectors!");
7471-
assert(VT.getVectorElementType() == N2VT.getVectorElementType() &&
7472-
"Insert subvector VTs must have the same element type!");
7473-
assert((VT.isScalableVector() || N2VT.isFixedLengthVector()) &&
7474-
"Cannot insert a scalable vector into a fixed length vector!");
7473+
if (!VT.isRISCVVectorTuple()) {
7474+
assert(VT.getVectorElementType() == N2VT.getVectorElementType() &&
7475+
"Insert subvector VTs must have the same element type!");
7476+
assert((VT.isScalableVector() || N2VT.isFixedLengthVector()) &&
7477+
"Cannot insert a scalable vector into a fixed length vector!");
7478+
}
7479+
if (VT.isRISCVVectorTuple())
7480+
assert((N2VT.isScalableVector() || N2VT.isRISCVVectorTuple()) &&
7481+
"Cannot insert a fixed length vector into a RISCV vector tuple!");
74757482
assert((VT.isScalableVector() != N2VT.isScalableVector() ||
74767483
VT.getVectorMinNumElements() >= N2VT.getVectorMinNumElements()) &&
74777484
"Insert subvector must be from smaller vector to larger vector!");
74787485
assert(isa<ConstantSDNode>(N3) &&
74797486
"Insert subvector index must be constant");
74807487
assert((VT.isScalableVector() != N2VT.isScalableVector() ||
7481-
(N2VT.getVectorMinNumElements() + N3->getAsZExtVal()) <=
7482-
VT.getVectorMinNumElements()) &&
7488+
((VT.isRISCVVectorTuple() ? 0 : N2VT.getVectorMinNumElements()) +
7489+
N3->getAsZExtVal()) <= VT.getVectorMinNumElements()) &&
74837490
"Insert subvector overflow!");
74847491
assert(N3->getAsAPIntVal().getBitWidth() ==
74857492
TLI->getVectorIdxTy(getDataLayout()).getFixedSizeInBits() &&

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3046,7 +3046,7 @@ bool TargetLowering::SimplifyDemandedVectorElts(
30463046
return false;
30473047

30483048
// TODO: For now we assume we know nothing about scalable vectors.
3049-
if (VT.isScalableVector())
3049+
if (VT.isScalableVector() || VT.isRISCVVectorTuple())
30503050
return false;
30513051

30523052
assert(VT.getVectorNumElements() == NumElts &&

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,10 @@ void TargetLoweringBase::computeRegisterProperties(
16071607
// Try to widen the vector.
16081608
for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
16091609
MVT SVT = (MVT::SimpleValueType) nVT;
1610+
// Skip RISCV vector tuple types since they don't involve in any
1611+
// widen/narrow operation.
1612+
if (SVT.isRISCVVectorTuple())
1613+
continue;
16101614
if (SVT.getVectorElementType() == EltVT &&
16111615
SVT.isScalableVector() == IsScalable &&
16121616
SVT.getVectorElementCount().getKnownMinValue() >

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,12 @@ MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name) const {
16511651
Reg = MatchRegisterAltName(Name);
16521652
if (isRVE() && Reg >= RISCV::X16 && Reg <= RISCV::X31)
16531653
Reg = RISCV::NoRegister;
1654+
1655+
// Replace vector tuple with the starting register, e.g. V4M4_V8M4 -> V4
1656+
for (int i = 30; i >= 0; --i)
1657+
if (Name.starts_with("V" + utostr(i)))
1658+
return RISCV::V0 + i;
1659+
16541660
return Reg;
16551661
}
16561662

0 commit comments

Comments
 (0)