[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