[llvm] [RISCV] Take SEW/LMUL into account for value tracking of vsetvli[max] (PR #82163)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 18 21:27:32 PST 2024
================
@@ -1576,12 +1577,31 @@ static void computeKnownBitsFromOperator(const Operator *I,
Known.Zero.setBitsFrom(32);
break;
case Intrinsic::riscv_vsetvli:
- case Intrinsic::riscv_vsetvlimax:
- // Assume that VL output is <= 65536.
- // TODO: Take SEW and LMUL into account.
- if (BitWidth > 17)
- Known.Zero.setBitsFrom(17);
+ case Intrinsic::riscv_vsetvlimax: {
+ bool HasAVL = II->getIntrinsicID() == Intrinsic::riscv_vsetvli;
+ const ConstantRange &Range =
+ getVScaleRange(II->getFunction(), BitWidth);
+ uint64_t VSEW =
+ cast<ConstantInt>(II->getArgOperand(HasAVL))->getZExtValue();
+ uint64_t SEW = 1 << (VSEW + 3);
+ uint64_t VLMUL =
+ cast<ConstantInt>(II->getArgOperand(1 + HasAVL))->getZExtValue();
+ bool Fractional = VLMUL > 4;
+ uint64_t LMUL = Fractional ? (1 << (8 - VLMUL)) : (1 << VLMUL);
+ uint64_t MaxVL =
+ Range.getUpper().getZExtValue() * RISCV::RVVBitsPerBlock / SEW;
+ MaxVL = Fractional ? MaxVL / LMUL : MaxVL * LMUL;
----------------
lukel97 wrote:
Would using `RISCVVType::decodeVLMUL` help here? Something like
```c++
auto [Fractional, LMUL] = RISCVVType::decodeVLMUL(VLMUL);
```
Or alternatively you can just compute VLMAX as MaxVLEN / SEWLMULRatio
```suggestion
uint64_t MaxVLEN = Range.getUpper().getZExtValue() * RISCV::RVVBitsPerBlock;
uint64_t MaxVL = MaxVLEN / RISCVII:getSEWLMULRatio(SEW, VLMUL);
```
https://github.com/llvm/llvm-project/pull/82163
More information about the llvm-commits
mailing list