When we have a precisely known VLEN, we can replace runtime usage of VLENB with compile time constants. This converts offsets involving both fixed and scalable components into fixed offsets. The result is that we avoid the csr read of vlenb, and can often fold the multiply as well.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll | ||
---|---|---|
6 | And this also an old problem here, should we emit a warring or error when zvl*b info is mismatch with -riscv-v-vector-bits-min=? min vlen is 128 according the zvl128b (which implied by v), but we force that become 256 by -riscv-v-vector-bits-min=, that became an issue when we use Tag_RISCV_arch* to check the expected minimal vlen requirement for the object?
|
llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll | ||
---|---|---|
90 | my bad, it's separated patch, I saw https://reviews.llvm.org/D137593 now |
llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll | ||
---|---|---|
6 | There's no conflict here. Zvl128b is a minimum, not a maximum. As such, specifying a larger VLEN via -riscv-v-vector-bits-min does not conflict. There's a separate question of whether the -riscv-v-vector-bits-min should effect the attributes, but that's well out of scope for this patch. | |
7 | This is a typo, and I'll fix. |
llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll | ||
---|---|---|
98 | The offset here is wrong. I missed a factor of 8 divide in my code which exists in the original getVLENFactoredAmount path. It's not really clear to me where that factor comes from, but what's here is definitely wrong in this test. Updated version forthcoming. |
Fix bug around missing divide by 8.
I have to admit I don't know why that divide is needed. It parallels the code in getVLENFactoredAmount, but it's not clear to me where the factor of 8 comes from.
I think all scalable vector stack objects are rounded up to be a multiple of 8 by this code in RISCVFrameLowering::assignRVVStackObjectOffsets
// If the data type is the fractional vector type, reserve one vector // register for it. if (ObjectSize < 8) ObjectSize = 8;
I think this is done because there is no fractional whole register load/store. The divide by 8 is trying to figure out how many whole registers there are.
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | ||
---|---|---|
185 | I'm sure you copy and pasted this from somewhere else, but this message isn't great. It should be something like "Scalable offset is not a multiple of a single vector size." |
The bit I don't understand is the interpretation of object size for a scalable value. Why is "8" the right number for a single VLEN sized register?
I'm sure you copy and pasted this from somewhere else, but this message isn't great. It should be something like "Scalable offset is not a multiple of a single vector size."