[llvm] [RISCV][DAG] Teach computeKnownBits consider SEW/LMUL/AVL for vsetvli. (PR #76158)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 08:10:14 PST 2023


================
@@ -16001,13 +16001,27 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
       // We can't do anything for most intrinsics.
       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 = IntNo == Intrinsic::riscv_vsetvli;
+      unsigned VSEW = Op.getConstantOperandVal(HasAVL + 1);
+      RISCVII::VLMUL VLMUL =
+          static_cast<RISCVII::VLMUL>(Op.getConstantOperandVal(HasAVL + 2));
+      unsigned SEW = RISCVVType::decodeVSEW(VSEW);
+      auto [LMul, Fractional] = RISCVVType::decodeVLMUL(VLMUL);
+      unsigned VLenMax = Subtarget.getRealMaxVLen();
+      unsigned MaxVL = VLenMax / SEW;
+      if (Fractional)
+        MaxVL /= LMul;
+      else
+        MaxVL *= LMul;
+      if (HasAVL && isa<ConstantSDNode>(Op.getOperand(1)))
+        MaxVL = std::min(MaxVL, (unsigned)Op.getConstantOperandVal(1));
----------------
topperc wrote:

I don't think you can cast `Op.getConstantOperandVal(1)` to `unsigned` here. If the AVL is 0x100000001 the cast will change it to 1 causing the std::min to return 1. That's too low, it should be VLMax.

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


More information about the llvm-commits mailing list