[llvm] [RISCV] Take SEW/LMUL into account for value tracking of vsetvli[max] (PR #82163)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 18 11:56:08 PST 2024


================
@@ -1576,12 +1577,30 @@ 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 SEW =
+            1 << (cast<ConstantInt>(II->getArgOperand(HasAVL))->getZExtValue() +
+                  3);
+        uint64_t LMUL =
+            cast<ConstantInt>(II->getArgOperand(1 + HasAVL))->getZExtValue();
+        bool Fractional = LMUL > 4;
+        uint64_t MaxVL =
+            Range.getLower().getZExtValue() * RISCV::RVVBitsPerBlock / SEW;
+        MaxVL = Fractional ? MaxVL / (1 << (8 - LMUL)) : MaxVL * (1 << LMUL);
+
+        // Result of vsetvli must be not larger than AVL.
+        if (HasAVL)
+          if (auto *CI = dyn_cast<ConstantInt>(II->getArgOperand(0)))
+            MaxVL = std::min(MaxVL, CI->getZExtValue());
+
+        unsigned KnownZeroFirstBit = Log2_32(MaxVL) + 1;
+        if (BitWidth > KnownZeroFirstBit)
----------------
topperc wrote:

This doesn't look right to me. On line 1590 you computed the lower bound on VL. Don't we need the upper bound to set the known bits here?

https://github.com/llvm/llvm-project/pull/82163


More information about the llvm-commits mailing list