Skip to content

Commit af837d4

Browse files
authored
[RISCV][DAG] Teach computeKnownBits consider SEW/LMUL/AVL for vsetvli. (#76158)
This patch also add tests whose masks are too narrow to combine. I think it can help us to find out bugs caused by too large known bits.
1 parent 81ae2a8 commit af837d4

File tree

3 files changed

+1250
-9
lines changed

3 files changed

+1250
-9
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16099,13 +16099,26 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1609916099
// We can't do anything for most intrinsics.
1610016100
break;
1610116101
case Intrinsic::riscv_vsetvli:
16102-
case Intrinsic::riscv_vsetvlimax:
16103-
// Assume that VL output is <= 65536.
16104-
// TODO: Take SEW and LMUL into account.
16105-
if (BitWidth > 17)
16106-
Known.Zero.setBitsFrom(17);
16102+
case Intrinsic::riscv_vsetvlimax: {
16103+
bool HasAVL = IntNo == Intrinsic::riscv_vsetvli;
16104+
unsigned VSEW = Op.getConstantOperandVal(HasAVL + 1);
16105+
RISCVII::VLMUL VLMUL =
16106+
static_cast<RISCVII::VLMUL>(Op.getConstantOperandVal(HasAVL + 2));
16107+
unsigned SEW = RISCVVType::decodeVSEW(VSEW);
16108+
auto [LMul, Fractional] = RISCVVType::decodeVLMUL(VLMUL);
16109+
uint64_t MaxVL = Subtarget.getRealMaxVLen() / SEW;
16110+
MaxVL = (Fractional) ? MaxVL / LMul : MaxVL * LMul;
16111+
16112+
// Result of vsetvli must be not larger than AVL.
16113+
if (HasAVL && isa<ConstantSDNode>(Op.getOperand(1)))
16114+
MaxVL = std::min(MaxVL, Op.getConstantOperandVal(1));
16115+
16116+
unsigned KnownZeroFirstBit = Log2_32(MaxVL) + 1;
16117+
if (BitWidth > KnownZeroFirstBit)
16118+
Known.Zero.setBitsFrom(KnownZeroFirstBit);
1610716119
break;
1610816120
}
16121+
}
1610916122
break;
1611016123
}
1611116124
}

0 commit comments

Comments
 (0)