-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV][GISel] RegBank select and instruction select for vector G_ADD, G_SUB #74114
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
okay, there's nothing showing up under "Reviewers" to request your review, so I'll just @michaelmaitland @topperc |
@@ -240,6 +254,10 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { | |||
&RISCV::ValueMappings[GPRSize == 64 ? RISCV::GPRB64Idx | |||
: RISCV::GPRB32Idx]; | |||
|
|||
unsigned VRBSize = getMaximumSize(RISCV::VRBRegBankID); | |||
const ValueMapping *VRBValueMapping = | |||
&RISCV::ValueMappings[VRBSize == 64 ? RISCV::VRB64Idx : RISCV::VRB32Idx]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The size for VRB bank shouldn't change. We only have to do this for GPR because of RV32 vs RV64.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for VRB, do we always have size == 64?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like in build/lib/Target/RISCV/RISCVGenRegisterBank.inc
that the Sizes
array has 512 for both RV32 and RV64 for VRB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
512 is the size of LMUL=8. we should have 4 different sizes in the mapping for the 4 different whole LMUL register sizes. We should pick based on the known minimum size of the type. 512, 256, 128, and 64. Anything less than 64 should use the 64.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm a bit lost right now. Can I check my understanding?
The size for VRB bank shouldn't change.
Does this refer to unsigned VRBSize
never change?
- Based on my understanding of your description, in
PartMappings
, I'll probably have:
{0, 64, VRBRegBank}, // <= 64
{0, 64, VRBRegBank}, {64, 128, VRBRegBank}, // 128, LMUL=2
{0, 64, VRBRegBank}, {64, 128, VRBRegBank}, {128, 192, VRBRegBank}, {192, 256, VRBRegBank}, // 256, LMUL=4
{0, 64, VRBRegBank} .... // 512, LMUL=8
?
And that I'll only have PMI_VRB64
in PartialMappingIdx
since the size of VRB doesn't change?
And in ValueMapping
, I'll probably have:
{&PartMappings[PMI_VRB64], 1},
{&PartMappings[PMI_VB64], 2},
{&PartMappings[PMI_VRB64], 4},
{&PartMappings[PMI_VRB64], 8}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getMaximumSize(RISCV::VRBRegBankID)
will always return the same value. I don't know what that value is. It's probably 512?
PartialMappingIdx should be
enum PartialMappingIdx {
PMI_GPRB32 = 0,
PMI_GPRB64 = 1,
PMI_FPRB32 = 2,
PMI_FPRB64 = 3,
PMI_VRB64 = 4,
PMI_VRB128 = 5,
PMI_VRB256 = 6,
PMI_VRB512 = 7,
};
PartMappings should be
const RegisterBankInfo::PartialMapping PartMappings[] = {
{0, 32, GPRBRegBank},
{0, 64, GPRBRegBank},
{0, 32, FPRBRegBank},
{0, 64, FPRBRegBank},
{0, 64, VRBRegBank},
{0, 128, VRBRegBank},
{0, 256, VRBRegBank},
{0, 512, VRBRegBank},
};
ValueMappings should be
const RegisterBankInfo::ValueMapping ValueMappings[] = {
// Invalid value mapping.
{nullptr, 0},
// Maximum 3 GPR operands; 32 bit.
{&PartMappings[PMI_GPRB32], 1},
{&PartMappings[PMI_GPRB32], 1},
{&PartMappings[PMI_GPRB32], 1},
// Maximum 3 GPR operands; 64 bit.
{&PartMappings[PMI_GPRB64], 1},
{&PartMappings[PMI_GPRB64], 1},
{&PartMappings[PMI_GPRB64], 1},
// Maximum 3 FPR operands; 32 bit.
{&PartMappings[PMI_FPRB32], 1},
{&PartMappings[PMI_FPRB32], 1},
{&PartMappings[PMI_FPRB32], 1},
// Maximum 3 FPR operands; 64 bit.
{&PartMappings[PMI_FPRB64], 1},
{&PartMappings[PMI_FPRB64], 1},
{&PartMappings[PMI_FPRB64], 1},
// Maximum 3 VR LMUL=1 operands;
{&PartMappings[PMI_VRB64], 1},
{&PartMappings[PMI_VRB64], 1},
{&PartMappings[PMI_VRB64], 1},
// Maximum 3 VR LMUL=2 operands;
{&PartMappings[PMI_VRB128], 1},
{&PartMappings[PMI_VRB128], 1},
{&PartMappings[PMI_VRB128], 1},
// Maximum 3 VR LMUL=4 operands;
{&PartMappings[PMI_VRB256], 1},
{&PartMappings[PMI_VRB256], 1},
{&PartMappings[PMI_VRB256], 1},
// Maximum 3 VR LMUL=8 operands;
{&PartMappings[PMI_VRB512], 1},
{&PartMappings[PMI_VRB512], 1},
{&PartMappings[PMI_VRB512], 1},
};
ValueMappingIdx should be
enum ValueMappingIdx {
InvalidIdx = 0,
GPRB32Idx = 1,
GPRB64Idx = 4,
FPRB32Idx = 7,
FPRB64Idx = 10,
VPRB64Idx = 13,
VPRB128Idx = 16,
VPRB256Idx = 19,
VPRB512Idx = 22,
};
You'll need a function like getFPValueMapping
to pick the correct VRB*Idx from the minimum type size. If the size is <=64 pick VPRB64Idx, if the size is 128 pick VPRB128Idx, if the size is 256 pick VPRB256Idx, and if the size is 512 VPRB512Idx.
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-llvm-globalisel Author: Jiahan Xie (jiahanxie353) ChangesHi folks, Now I'm moving on to the select function.
However, when it's trying to select And I'm a bit confused about all the Full diff: https://github.com/llvm/llvm-project/pull/74114.diff 1 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index cf0ff63a5e51c29..f3be5ba74b2f313 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -29,6 +29,8 @@ const RegisterBankInfo::PartialMapping PartMappings[] = {
{0, 64, GPRBRegBank},
{0, 32, FPRBRegBank},
{0, 64, FPRBRegBank},
+ {0, 32, VRBRegBank},
+ {0, 64, VRBRegBank},
};
enum PartialMappingIdx {
@@ -36,6 +38,8 @@ enum PartialMappingIdx {
PMI_GPRB64 = 1,
PMI_FPRB32 = 2,
PMI_FPRB64 = 3,
+ PMI_VRB32 = 4,
+ PMI_VRB64 = 5,
};
const RegisterBankInfo::ValueMapping ValueMappings[] = {
@@ -57,6 +61,14 @@ const RegisterBankInfo::ValueMapping ValueMappings[] = {
{&PartMappings[PMI_FPRB64], 1},
{&PartMappings[PMI_FPRB64], 1},
{&PartMappings[PMI_FPRB64], 1},
+ // Maximum 3 VRB operands; 32 bit.
+ {&PartMappings[PMI_VRB32], 1},
+ {&PartMappings[PMI_VRB32], 1},
+ {&PartMappings[PMI_VRB32], 1},
+ // Maximum 3 VRB operands; 64 bit.
+ {&PartMappings[PMI_VRB64], 1},
+ {&PartMappings[PMI_VRB64], 1},
+ {&PartMappings[PMI_VRB64], 1},
};
enum ValueMappingIdx {
@@ -65,6 +77,8 @@ enum ValueMappingIdx {
GPRB64Idx = 4,
FPRB32Idx = 7,
FPRB64Idx = 10,
+ VRB32Idx = 13,
+ VRB64Idx = 16,
};
} // namespace RISCV
} // namespace llvm
@@ -240,6 +254,10 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
&RISCV::ValueMappings[GPRSize == 64 ? RISCV::GPRB64Idx
: RISCV::GPRB32Idx];
+ unsigned VRBSize = getMaximumSize(RISCV::VRBRegBankID);
+ const ValueMapping *VRBValueMapping =
+ &RISCV::ValueMappings[VRBSize == 64 ? RISCV::VRB64Idx : RISCV::VRB32Idx];
+
switch (Opc) {
case TargetOpcode::G_ADD:
case TargetOpcode::G_SUB:
@@ -269,6 +287,9 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_SEXTLOAD:
case TargetOpcode::G_ZEXTLOAD:
+ if (MRI.getType(MI.getOperand(0).getReg()).isVector())
+ return getInstructionMapping(DefaultMappingID, /*Cost=*/1,
+ VRBValueMapping, NumOperands);
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
NumOperands);
case TargetOpcode::G_FADD:
|
You're missing changes to |
I checked out your code and I am not seeing early exit before selectImpl for the G_ADD. I only see the COPY and PseudoRET instructions entering into the |
did you pick the vector legalizer commits from my other PR? |
Yes |
you are right, I was confused by the backward order |
Hi, |
Before the addition of scalable vectors, the size of scalars and fixed vectors is always known. For example an i32 is 32 bits, a float is 32 bits, and 4 x i32 is 4 * 32 bits. With the addition of scalable vectors, we do not know the size at compile time. The size of a type like Instead of returning |
Thanks! |
To implement Let's take I was trying to use I'm wondering if I'm on the right track, and is there a generic function to extract |
|
0a2f5de
to
d797bfa
Compare
Seems like I don't need to implement all the The test results here looks reasonable to me, but I don't understand the Please let me know what you think |
The |
It worked because the test cases have
If you run the full gisel pipeline on a llvm program or |
The -1 is the VL operand where -1 means VLMAX. |
d797bfa
to
04b558b
Compare
What is the |
This. Instruction selection is responsible for lowering into target specific MIR ( |
@@ -57,6 +60,22 @@ const RegisterBankInfo::ValueMapping ValueMappings[] = { | |||
{&PartMappings[PMI_FPRB64], 1}, | |||
{&PartMappings[PMI_FPRB64], 1}, | |||
{&PartMappings[PMI_FPRB64], 1}, | |||
// Maximum 3 VR LMUL=1 operands. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Maximum 3 VR LMUL=1 operands. | |
// Maximum 3 VR LMUL={1, MF2, MF4, MF8} operands. |
@@ -0,0 +1,556 @@ | |||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py | |||
# RUN: llc -mtriple=riscv32 -mattr=+v -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the test cases are the same for rv32 and rv64. Should we collapse to rvv/add.mir
and have a run line for rv32 and a run line for rv64?
# RUN: llc -mtriple=riscv32 -mattr=+v -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV32 %s
# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV64 %s
tracksRegLiveness: true | ||
body: | | ||
bb.0.entry: | ||
liveins: $x10, $x11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x10 and x11 are scalar registers. You should pass $vN
registers. Remember that LMUL 1 and fractional LMUL cases use one vector register, LMUL 2 cases use 2 vector registers and so on:
# LMUL 1 liveins:
liveins: $v8, $v9
# LMUL 2 liveins:
liveins: $v8, $v10
# LMUL 4 liveins:
liveins: $v8, $v12, $v16
# LMUL 8 liveins:
liveins: $v8, $v16, $v24
%0:vrb(<vscale x 1 x s8>) = COPY $x10 | ||
%1:vrb(<vscale x 1 x s8>) = COPY $x11 | ||
%2:vrb(<vscale x 1 x s8>) = G_ADD %0, %1 | ||
$x10 = COPY %2(<vscale x 1 x s8>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to copy to vector register, not scalar register.
tracksRegLiveness: true | ||
body: | | ||
bb.0.entry: | ||
liveins: $v10, $v11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful which vector registers you are passing as livein. M8 operations will be using v10, v11, v12, v13, v14, v15, v16, v17
as a single register grouping. That means that you probably should use the next available register for the next live in.
I am calling out this specific LMUL 8 case in this test, but make sure this holds for all your test cases for their respective LMULs. It could be helpful to see which registers the IR translator for a test that lowers to this MIR test case chooses if you are not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful which vector registers you are passing as livein. M8 operations will be using
v10, v11, v12, v13, v14, v15, v16, v17
as a single register grouping. That means that you probably should use the next available register for the next live in.I am calling out this specific LMUL 8 case in this test, but make sure this holds for all your test cases for their respective LMULs. It could be helpful to see which registers the IR translator for a test that lowers to this MIR test case chooses if you are not sure.
Why hand construct the test at all? Write the IR test and use -stop-before to get the MIR.
04b558b
to
14db7ee
Compare
@@ -277,7 +277,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { | |||
} | |||
|
|||
const LLT Ty = MRI.getType(VReg); | |||
if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { | |||
if (Ty.isValid() && TypeSize::isKnownGT(Ty.getSizeInBits(), TRI.getRegSizeInBits(*RC))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang format needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you mention regbankselect in the title/description of PR?
14db7ee
to
4114266
Compare
@@ -785,6 +785,21 @@ const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank( | |||
} | |||
|
|||
// TODO: Non-GPR register classes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can delete this TODO
{0, 64, GPRBRegBank}, | ||
{0, 32, FPRBRegBank}, | ||
{0, 64, FPRBRegBank}, | ||
{0, 32, GPRBRegBank}, {0, 64, GPRBRegBank}, {0, 32, FPRBRegBank}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put these back on single lines regardless of what clang-format says
52b9430
to
66db262
Compare
This patch could use a rebase and an update to the PR description. |
…vector add and sub
66db262
to
5d60e8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with nit comment that RISCV
-> RISC-V
in commit description.
* llvm/main: (500 commits) [docs] Add beginner-focused office hours (llvm#80308) [mlir][sparse] external entry method wrapper for sparse tensors (llvm#80326) [StackSlotColoring] Ignore non-spill objects in RemoveDeadStores. (llvm#80242) [libc][stdbit] fix return types (llvm#80337) Revert "[RISCV] Refine cost on Min/Max reduction" (llvm#80340) [TTI]Add support for strided loads/stores. [analyzer][HTMLRewriter] Cache partial rewrite results. (llvm#80220) [flang][openacc][openmp] Use #0 from hlfir.declare value when generating bound ops (llvm#80317) [AArch64][PAC] Expand blend(reg, imm) operation in aarch64-pauth pass (llvm#74729) [SHT_LLVM_BB_ADDR_MAP][llvm-readobj] Implements llvm-readobj handling for PGOAnalysisMap. (llvm#79520) [libc] add bazel support for most of unistd (llvm#80078) [clang-tidy] Remove enforcement of rule C.48 from cppcoreguidelines-prefer-member-init (llvm#80330) [OpenMP] Fix typo (NFC) (llvm#80332) [BOLT] Enable re-writing of Linux kernel binary (llvm#80228) [BOLT] Adjust section sizes based on file offsets (llvm#80226) [libc] fix stdbit include test when not all entrypoints are available (llvm#80323) [RISCV][GISel] RegBank select and instruction select for vector G_ADD, G_SUB (llvm#74114) [RISCV] Add srmcfg CSR from Ssqosid extension. (llvm#79914) [mlir][sparse] add sparsification options to pretty print and debug s… (llvm#80205) [RISCV][MC] MC layer support for the experimental zalasr extension (llvm#79911) ...
…, G_SUB (llvm#74114) RegisterBank Selection for scalable vector G_ADD and G_SUB by creating new mappings for different types of vector register banks. Then implement Instruction Selection for the same operations by choosing the correct RISC-V vector register class.
RegisterBank Selection for scalable vector G_ADD and G_SUB by creating new mappings for different types of vector register banks.
Then implement Instruction Selection for the same operations by choosing the correct RISC-V vector register class.