42#define DEBUG_TYPE "gisel-known-bits"
50 "Analysis for ComputingKnownBits",
false,
true)
53 : MF(MF), MRI(MF.getRegInfo()), TL(*MF.getSubtarget().getTargetLowering()),
58 switch (
MI->getOpcode()) {
59 case TargetOpcode::COPY:
61 case TargetOpcode::G_ASSERT_ALIGN: {
63 return Align(
MI->getOperand(2).getImm());
65 case TargetOpcode::G_FRAME_INDEX: {
66 int FrameIdx =
MI->getOperand(1).getIndex();
67 return MF.getFrameInfo().getObjectAlign(FrameIdx);
69 case TargetOpcode::G_INTRINSIC:
70 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
71 case TargetOpcode::G_INTRINSIC_CONVERGENT:
72 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
74 return TL.computeKnownAlignForTargetInstr(*
this, R, MRI,
Depth + 1);
79 const LLT Ty = MRI.getType(R);
89 const APInt &DemandedElts,
97 LLT Ty = MRI.getType(R);
98 unsigned BitWidth = Ty.getScalarSizeInBits();
103 LLT Ty = MRI.getType(R);
104 const APInt ScalarDemandedElts(1, 1);
105 APInt DemandedElts = Ty.isFixedVector()
107 : ScalarDemandedElts;
116 const APInt ScalarDemandedElts(1, 1);
119 switch (
MI.getOpcode()) {
123 case TargetOpcode::G_BUILD_VECTOR: {
125 if (!DemandedElts[
I])
133 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
136 LLT VecTy = MRI.getType(InVec);
144 if (Idx->ult(NumSrcElts))
150 case TargetOpcode::G_SHUFFLE_VECTOR: {
153 if (SrcTy.isScalableVector())
155 APInt DemandedLHS, DemandedRHS;
157 DemandedElts, DemandedLHS, DemandedRHS))
159 if (!DemandedLHS.
isZero() &&
162 if (!DemandedRHS.
isZero() &&
168 case TargetOpcode::G_OR:
173 case TargetOpcode::G_SELECT:
178 case TargetOpcode::G_SHL: {
208[[maybe_unused]]
static void
211 <<
"] Computed for: " <<
MI <<
"[" <<
Depth <<
"] Known: 0x"
222 const APInt &DemandedElts,
228 if (
Known.isUnknown())
253 const APInt &DemandedElts,
255 MachineInstr &
MI = *MRI.getVRegDef(R);
256 unsigned Opcode =
MI.getOpcode();
257 LLT DstTy = MRI.getType(R);
271 "DemandedElt width should equal the fixed vector number of elements");
274 "DemandedElt width should be 1 for scalars or scalable vectors");
299 TL.computeKnownBitsForTargetInstr(*
this, R,
Known, DemandedElts, MRI,
302 case TargetOpcode::G_BUILD_VECTOR: {
304 Known.Zero.setAllBits();
305 Known.One.setAllBits();
307 if (!DemandedElts[
I])
316 if (
Known.isUnknown())
321 case TargetOpcode::G_SPLAT_VECTOR: {
329 case TargetOpcode::G_FREEZE: {
337 case TargetOpcode::COPY:
338 case TargetOpcode::G_PHI:
339 case TargetOpcode::PHI: {
345 assert(
MI.getOperand(0).getSubReg() == 0 &&
"Is this code in SSA?");
348 for (
unsigned Idx = 1;
Idx <
MI.getNumOperands();
Idx += 2) {
349 const MachineOperand &Src =
MI.getOperand(Idx);
351 LLT SrcTy = MRI.getType(SrcReg);
359 if (SrcReg.
isVirtual() && Src.getSubReg() == 0 &&
361 APInt NowDemandedElts;
363 NowDemandedElts = APInt(1, 1);
366 NowDemandedElts = DemandedElts;
373 Depth + (Opcode != TargetOpcode::COPY));
378 if (
Known.isUnknown())
388 case TargetOpcode::G_STEP_VECTOR: {
389 APInt Step =
MI.getOperand(1).getCImm()->getValue();
397 const APInt MinNumElts =
403 .
umul_ov(MinNumElts, Overflow);
406 const APInt MaxValue = (MaxNumElts - 1).
umul_ov(Step, Overflow);
412 case TargetOpcode::G_VSCALE: {
414 const APInt &Multiplier =
MI.
getOperand(1).getCImm()->getValue();
418 case TargetOpcode::G_CONSTANT: {
422 case TargetOpcode::G_FRAME_INDEX: {
423 int FrameIdx =
MI.getOperand(1).getIndex();
424 TL.computeKnownBitsForStackObjectPointer(
425 Known, MF, MF.getFrameInfo().getObjectAlign(FrameIdx));
428 case TargetOpcode::G_SUB: {
437 case TargetOpcode::G_XOR: {
446 case TargetOpcode::G_PTR_ADD: {
450 LLT Ty = MRI.getType(
MI.getOperand(1).getReg());
455 case TargetOpcode::G_ADD: {
463 case TargetOpcode::G_AND: {
473 case TargetOpcode::G_OR: {
483 case TargetOpcode::G_MUL: {
491 case TargetOpcode::G_UMULH: {
499 case TargetOpcode::G_SMULH: {
507 case TargetOpcode::G_CLMUL: {
515 case TargetOpcode::G_UAVGFLOOR: {
523 case TargetOpcode::G_UAVGCEIL: {
531 case TargetOpcode::G_SAVGFLOOR: {
539 case TargetOpcode::G_SAVGCEIL: {
547 case TargetOpcode::G_ABDU: {
555 case TargetOpcode::G_ABDS: {
564 if (SignBits1 == 1) {
570 Known.Zero.setHighBits(std::min(SignBits0, SignBits1) - 1);
573 case TargetOpcode::G_SADDSAT: {
581 case TargetOpcode::G_UADDSAT: {
589 case TargetOpcode::G_SSUBSAT: {
597 case TargetOpcode::G_USUBSAT: {
605 case TargetOpcode::G_UDIV: {
614 case TargetOpcode::G_SDIV: {
623 case TargetOpcode::G_UREM: {
624 KnownBits LHSKnown(
Known.getBitWidth());
625 KnownBits RHSKnown(
Known.getBitWidth());
635 case TargetOpcode::G_SREM: {
636 KnownBits LHSKnown(
Known.getBitWidth());
637 KnownBits RHSKnown(
Known.getBitWidth());
647 case TargetOpcode::G_SELECT: {
648 computeKnownBitsMin(
MI.getOperand(2).getReg(),
MI.getOperand(3).getReg(),
652 case TargetOpcode::G_SMIN: {
662 case TargetOpcode::G_SMAX: {
672 case TargetOpcode::G_UMIN: {
681 case TargetOpcode::G_UMAX: {
690 case TargetOpcode::G_FCMP:
691 case TargetOpcode::G_ICMP: {
694 if (TL.getBooleanContents(DstTy.
isVector(),
695 Opcode == TargetOpcode::G_FCMP) ==
698 Known.Zero.setBitsFrom(1);
701 case TargetOpcode::G_SEXT: {
709 case TargetOpcode::G_ASSERT_SEXT:
710 case TargetOpcode::G_SEXT_INREG: {
716 case TargetOpcode::G_ANYEXT: {
722 case TargetOpcode::G_LOAD: {
723 const MachineMemOperand *MMO = *
MI.memoperands_begin();
725 if (
const MDNode *Ranges = MMO->
getRanges())
727 Known = KnownRange.anyext(
Known.getBitWidth());
730 case TargetOpcode::G_SEXTLOAD:
731 case TargetOpcode::G_ZEXTLOAD: {
734 const MachineMemOperand *MMO = *
MI.memoperands_begin();
736 if (
const MDNode *Ranges = MMO->
getRanges())
738 Known = Opcode == TargetOpcode::G_SEXTLOAD
739 ? KnownRange.sext(
Known.getBitWidth())
740 : KnownRange.zext(
Known.getBitWidth());
743 case TargetOpcode::G_ASHR: {
744 KnownBits LHSKnown, RHSKnown;
752 case TargetOpcode::G_LSHR: {
753 KnownBits LHSKnown, RHSKnown;
761 case TargetOpcode::G_SHL: {
762 KnownBits LHSKnown, RHSKnown;
770 case TargetOpcode::G_ROTL:
771 case TargetOpcode::G_ROTR: {
780 unsigned Amt = MaybeAmtOp->urem(
BitWidth);
783 if (Opcode == TargetOpcode::G_ROTL)
790 case TargetOpcode::G_FSHL:
791 case TargetOpcode::G_FSHR: {
797 const APInt Amt = *MaybeAmtOp;
802 Known = Opcode == TargetOpcode::G_FSHL
807 case TargetOpcode::G_INTTOPTR:
808 case TargetOpcode::G_PTRTOINT:
813 case TargetOpcode::G_ZEXT:
814 case TargetOpcode::G_TRUNC: {
820 case TargetOpcode::G_TRUNC_SSAT_S: {
826 case TargetOpcode::G_TRUNC_SSAT_U: {
832 case TargetOpcode::G_TRUNC_USAT_U: {
838 case TargetOpcode::G_ASSERT_ZEXT: {
842 unsigned SrcBitWidth =
MI.getOperand(2).getImm();
843 assert(SrcBitWidth &&
"SrcBitWidth can't be zero");
845 Known.Zero |= (~InMask);
846 Known.One &= (~Known.Zero);
849 case TargetOpcode::G_ASSERT_ALIGN: {
850 int64_t LogOfAlign =
Log2_64(
MI.getOperand(2).getImm());
855 Known.Zero.setLowBits(LogOfAlign);
856 Known.One.clearLowBits(LogOfAlign);
859 case TargetOpcode::G_MERGE_VALUES: {
860 unsigned NumOps =
MI.getNumOperands();
861 unsigned OpSize = MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits();
863 for (
unsigned I = 0;
I !=
NumOps - 1; ++
I) {
864 KnownBits SrcOpKnown;
866 DemandedElts,
Depth + 1);
867 Known.insertBits(SrcOpKnown,
I * OpSize);
871 case TargetOpcode::G_UNMERGE_VALUES: {
872 unsigned NumOps =
MI.getNumOperands();
874 LLT SrcTy = MRI.getType(SrcReg);
880 unsigned DstIdx =
MI.findRegisterDefOperandIdx(R,
nullptr);
882 APInt SubDemandedElts = DemandedElts;
889 KnownBits SrcOpKnown;
893 Known = std::move(SrcOpKnown);
898 case TargetOpcode::G_BSWAP: {
904 case TargetOpcode::G_BITREVERSE: {
910 case TargetOpcode::G_CTPOP: {
917 Known.Zero.setBitsFrom(LowBits);
922 case TargetOpcode::G_UBFX: {
923 KnownBits SrcOpKnown, OffsetKnown, WidthKnown;
933 case TargetOpcode::G_SBFX: {
934 KnownBits SrcOpKnown, OffsetKnown, WidthKnown;
951 case TargetOpcode::G_UADDO:
952 case TargetOpcode::G_UADDE:
953 case TargetOpcode::G_SADDO:
954 case TargetOpcode::G_SADDE: {
955 if (
MI.getOperand(1).getReg() == R) {
958 if (TL.getBooleanContents(DstTy.
isVector(),
false) ==
961 Known.Zero.setBitsFrom(1);
965 assert(
MI.getOperand(0).getReg() == R &&
966 "We only compute knownbits for the sum here.");
969 if (Opcode == TargetOpcode::G_UADDE || Opcode == TargetOpcode::G_SADDE) {
973 Carry = Carry.trunc(1);
985 case TargetOpcode::G_USUBO:
986 case TargetOpcode::G_USUBE:
987 case TargetOpcode::G_SSUBO:
988 case TargetOpcode::G_SSUBE:
989 case TargetOpcode::G_UMULO:
990 case TargetOpcode::G_SMULO: {
991 if (
MI.getOperand(1).getReg() == R) {
994 if (TL.getBooleanContents(DstTy.
isVector(),
false) ==
997 Known.Zero.setBitsFrom(1);
1001 case TargetOpcode::G_CTTZ:
1002 case TargetOpcode::G_CTTZ_ZERO_POISON: {
1003 KnownBits SrcOpKnown;
1009 Known.Zero.setBitsFrom(LowBits);
1012 case TargetOpcode::G_CTLZ:
1013 case TargetOpcode::G_CTLZ_ZERO_POISON: {
1014 KnownBits SrcOpKnown;
1020 Known.Zero.setBitsFrom(LowBits);
1023 case TargetOpcode::G_CTLS: {
1025 unsigned MinRedundantSignBits =
1028 unsigned MaxUpperRedundantSignBits = MRI.getType(
Reg).getScalarSizeInBits();
1031 APInt(
BitWidth, MaxUpperRedundantSignBits));
1036 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1043 LLT VecVT = MRI.getType(InVec);
1055 Known.Zero.setAllBits();
1056 Known.One.setAllBits();
1061 if (ConstEltNo && ConstEltNo->ult(NumSrcElts))
1068 case TargetOpcode::G_INSERT_VECTOR_ELT: {
1073 LLT VecVT = MRI.getType(InVec);
1081 bool DemandedVal =
true;
1082 APInt DemandedVecElts = DemandedElts;
1083 if (ConstEltNo && ConstEltNo->ult(NumElts)) {
1084 unsigned EltIdx = ConstEltNo->getZExtValue();
1085 DemandedVal = !!DemandedElts[EltIdx];
1088 Known.setAllConflict();
1093 if (!!DemandedVecElts) {
1099 case TargetOpcode::G_INSERT_SUBVECTOR: {
1104 LLT SrcTy = MRI.getType(Src);
1105 LLT SubTy = MRI.getType(
Sub);
1106 APInt DemandedSubElts;
1107 APInt DemandedSrcElts;
1113 DemandedSrcElts = APInt(1, 1);
1116 DemandedSubElts = DemandedElts.
extractBits(NumSubElts, Idx);
1117 DemandedSrcElts = DemandedElts;
1118 DemandedSrcElts.
clearBits(Idx, Idx + NumSubElts);
1121 Known.setAllConflict();
1122 if (!!DemandedSubElts) {
1125 if (
Known.isUnknown())
1129 if (!!DemandedSrcElts) {
1136 case TargetOpcode::G_EXTRACT_SUBVECTOR: {
1138 LLT SrcTy = MRI.getType(SrcReg);
1139 APInt DemandedSrcElts;
1141 DemandedSrcElts = APInt(1, 1);
1145 DemandedSrcElts = DemandedElts.
zext(NumSrcElts).
shl(Idx);
1150 case TargetOpcode::G_SHUFFLE_VECTOR: {
1151 APInt DemandedLHS, DemandedRHS;
1154 unsigned NumElts = MRI.getType(
MI.getOperand(1).getReg()).getNumElements();
1156 DemandedElts, DemandedLHS, DemandedRHS))
1160 Known.Zero.setAllBits();
1161 Known.One.setAllBits();
1162 if (!!DemandedLHS) {
1168 if (
Known.isUnknown())
1170 if (!!DemandedRHS) {
1177 case TargetOpcode::G_CONCAT_VECTORS: {
1178 if (MRI.getType(
MI.getOperand(0).getReg()).isScalableVector())
1181 Known.Zero.setAllBits();
1182 Known.One.setAllBits();
1183 unsigned NumSubVectorElts =
1184 MRI.getType(
MI.getOperand(1).getReg()).getNumElements();
1188 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
1189 if (!!DemandedSub) {
1195 if (
Known.isUnknown())
1200 case TargetOpcode::G_VECTOR_COMPRESS: {
1204 Register PassThru =
MI.getOperand(3).getReg();
1207 if (
Known.isUnknown())
1216 case TargetOpcode::G_ABS: {
1232 if (!Ty.isValid()) {
1236 unsigned BitWidth = Ty.getScalarSizeInBits();
1243 const APInt &DemandedElts,
1247 if (!Stack.empty()) {
1248 if (!getKnownBitsResult(R, DemandedElts,
Depth,
Known)) {
1249 Stack.push_back({R, DemandedElts,
Depth});
1257 Stack.push_back({R, DemandedElts,
Depth});
1258 while (!Stack.empty()) {
1259 WorkItem Item = Stack.back();
1260 size_t StackSize = Stack.size();
1261 Register ItemReg = std::get<0>(Item);
1262 const APInt &ItemDemandedElts = std::get<1>(Item);
1263 const unsigned ItemDepth = std::get<2>(Item);
1266 if (getKnownBitsResult(ItemReg, ItemDemandedElts, ItemDepth, ItemKnown)) {
1274 computeKnownBits(ItemReg, ItemKnown, ItemDemandedElts, ItemDepth);
1278 if (Stack.size() == StackSize) {
1279 assert((std::get<0>(Stack.back()) == ItemReg &&
1280 std::get<1>(Stack.back()) == ItemDemandedElts &&
1281 std::get<2>(Stack.back()) == ItemDepth) &&
1282 "The item we just evaluated must still be the top one.");
1284 setKnownBitsResult(ItemReg, ItemDemandedElts, ItemDepth, ItemKnown);
1291 if (!getKnownBitsResult(R, DemandedElts,
Depth,
Known))
1293 "Top level query must be in `results` after iteration is complete.");
1302 APInt DemandedElts =
1316void GISelValueTracking::computeKnownFPClassForFPTrunc(
1324 KnownFPClass KnownSrc;
1325 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1330void GISelValueTracking::computeKnownFPClass(
Register R,
1331 const APInt &DemandedElts,
1335 assert(
Known.isUnknown() &&
"should not be called with known information");
1337 if (!DemandedElts) {
1345 MachineInstr &
MI = *MRI.getVRegDef(R);
1346 unsigned Opcode =
MI.getOpcode();
1347 LLT DstTy = MRI.getType(R);
1355 switch (Cst->getKind()) {
1357 auto APF = Cst->getScalarValue();
1358 Known.setKnownFPClasses(APF.classify());
1359 Known.setSignBit(APF.isNegative());
1364 bool SignBitAllZero =
true;
1365 bool SignBitAllOne =
true;
1367 for (
auto C : *Cst) {
1368 Known.setKnownFPClasses(
Known.getKnownFPClasses() |
C.classify());
1370 SignBitAllZero =
false;
1372 SignBitAllOne =
false;
1375 if (SignBitAllOne != SignBitAllZero)
1376 Known.setSignBit(SignBitAllOne);
1391 KnownNotFromFlags |=
fcNan;
1393 KnownNotFromFlags |=
fcInf;
1397 InterestedClasses &= ~KnownNotFromFlags;
1400 [=, &
Known] {
Known.knownNot(KnownNotFromFlags); });
1410 TL.computeKnownFPClassForTargetInstr(*
this, R,
Known, DemandedElts, MRI,
1413 case TargetOpcode::G_FNEG: {
1415 computeKnownFPClass(Val, DemandedElts, InterestedClasses,
Known,
Depth + 1);
1419 case TargetOpcode::G_SELECT: {
1442 bool LookThroughFAbsFNeg = CmpLHS !=
LHS && CmpLHS !=
RHS;
1443 std::tie(TestedValue, MaskIfTrue, MaskIfFalse) =
1449 MaskIfTrue = TestedMask;
1450 MaskIfFalse = ~TestedMask;
1453 if (TestedValue ==
LHS) {
1455 FilterLHS = MaskIfTrue;
1456 }
else if (TestedValue ==
RHS) {
1458 FilterRHS = MaskIfFalse;
1461 KnownFPClass Known2;
1462 computeKnownFPClass(
LHS, DemandedElts, InterestedClasses & FilterLHS,
Known,
1464 Known.setKnownFPClasses(
Known.getKnownFPClasses() & FilterLHS);
1466 computeKnownFPClass(
RHS, DemandedElts, InterestedClasses & FilterRHS,
1473 case TargetOpcode::G_FCOPYSIGN: {
1474 Register Magnitude =
MI.getOperand(1).getReg();
1477 KnownFPClass KnownSign;
1479 computeKnownFPClass(Magnitude, DemandedElts, InterestedClasses,
Known,
1481 computeKnownFPClass(Sign, DemandedElts, InterestedClasses, KnownSign,
1483 Known.copysign(KnownSign);
1486 case TargetOpcode::G_FMA:
1487 case TargetOpcode::G_FMAD: {
1491 const bool IsFMA = Opcode == TargetOpcode::G_FMA;
1502 KnownFPClass KnownSrc, KnownAddend;
1503 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownAddend,
1505 computeKnownFPClass(
A, DemandedElts, InterestedClasses, KnownSrc,
1507 if (KnownNotFromFlags) {
1508 KnownSrc.
knownNot(KnownNotFromFlags);
1509 KnownAddend.
knownNot(KnownNotFromFlags);
1512 : KnownFPClass::fmuladd_square(KnownSrc, KnownAddend,
Mode);
1514 KnownFPClass KnownSrc[3];
1515 computeKnownFPClass(
A, DemandedElts, InterestedClasses, KnownSrc[0],
1517 if (KnownSrc[0].isUnknown())
1519 computeKnownFPClass(
B, DemandedElts, InterestedClasses, KnownSrc[1],
1521 if (KnownSrc[1].isUnknown())
1523 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownSrc[2],
1525 if (KnownSrc[2].isUnknown())
1527 if (KnownNotFromFlags) {
1528 KnownSrc[0].
knownNot(KnownNotFromFlags);
1529 KnownSrc[1].
knownNot(KnownNotFromFlags);
1530 KnownSrc[2].
knownNot(KnownNotFromFlags);
1534 : KnownFPClass::fmuladd(KnownSrc[0], KnownSrc[1], KnownSrc[2],
1539 case TargetOpcode::G_FSQRT:
1540 case TargetOpcode::G_STRICT_FSQRT: {
1541 KnownFPClass KnownSrc;
1543 if (InterestedClasses &
fcNan)
1547 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1556 case TargetOpcode::G_FABS: {
1561 computeKnownFPClass(Val, DemandedElts, InterestedClasses,
Known,
1567 case TargetOpcode::G_FATAN2: {
1585 KnownFPClass KnownY, KnownX;
1586 computeKnownFPClass(
Y, DemandedElts, InterestedY, KnownY,
Depth + 1);
1587 computeKnownFPClass(
X, DemandedElts, InterestedX, KnownX,
Depth + 1);
1593 case TargetOpcode::G_FSINH: {
1595 KnownFPClass KnownSrc;
1596 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1601 case TargetOpcode::G_FCOSH: {
1603 KnownFPClass KnownSrc;
1604 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1609 case TargetOpcode::G_FTANH: {
1611 KnownFPClass KnownSrc;
1612 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1617 case TargetOpcode::G_FASIN: {
1619 KnownFPClass KnownSrc;
1620 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1625 case TargetOpcode::G_FACOS: {
1627 KnownFPClass KnownSrc;
1628 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1633 case TargetOpcode::G_FATAN: {
1635 KnownFPClass KnownSrc;
1636 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1641 case TargetOpcode::G_FTAN: {
1643 KnownFPClass KnownSrc;
1644 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1649 case TargetOpcode::G_FSIN:
1650 case TargetOpcode::G_FCOS: {
1653 KnownFPClass KnownSrc;
1654 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1657 : KnownFPClass::sin(KnownSrc);
1660 case TargetOpcode::G_FSINCOS: {
1663 KnownFPClass KnownSrc;
1664 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
1666 if (R ==
MI.getOperand(0).getReg())
1672 case TargetOpcode::G_FMAXNUM:
1673 case TargetOpcode::G_FMINNUM:
1674 case TargetOpcode::G_FMINNUM_IEEE:
1675 case TargetOpcode::G_FMAXIMUM:
1676 case TargetOpcode::G_FMINIMUM:
1677 case TargetOpcode::G_FMAXNUM_IEEE:
1678 case TargetOpcode::G_FMAXIMUMNUM:
1679 case TargetOpcode::G_FMINIMUMNUM: {
1682 KnownFPClass KnownLHS, KnownRHS;
1684 computeKnownFPClass(
LHS, DemandedElts, InterestedClasses, KnownLHS,
1686 computeKnownFPClass(
RHS, DemandedElts, InterestedClasses, KnownRHS,
1691 case TargetOpcode::G_FMINIMUM:
1694 case TargetOpcode::G_FMAXIMUM:
1697 case TargetOpcode::G_FMINIMUMNUM:
1700 case TargetOpcode::G_FMAXIMUMNUM:
1703 case TargetOpcode::G_FMINNUM:
1704 case TargetOpcode::G_FMINNUM_IEEE:
1707 case TargetOpcode::G_FMAXNUM:
1708 case TargetOpcode::G_FMAXNUM_IEEE:
1720 case TargetOpcode::G_FCANONICALIZE: {
1722 KnownFPClass KnownSrc;
1723 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1728 DenormalMode DenormMode = MF->getDenormalMode(FPType);
1732 case TargetOpcode::G_VECREDUCE_FMAX:
1733 case TargetOpcode::G_VECREDUCE_FMIN:
1734 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
1735 case TargetOpcode::G_VECREDUCE_FMINIMUM:
1736 case TargetOpcode::G_VECREDUCE_FMAXIMUMNUM:
1737 case TargetOpcode::G_VECREDUCE_FMINIMUMNUM: {
1743 computeKnownFPClass(Val,
MI.getFlags(), InterestedClasses,
Depth + 1);
1745 if (!
Known.isKnownNeverNaN())
1746 Known.setSignBit(std::nullopt);
1749 case TargetOpcode::G_FFLOOR:
1750 case TargetOpcode::G_FCEIL:
1751 case TargetOpcode::G_FRINT:
1752 case TargetOpcode::G_FNEARBYINT:
1753 case TargetOpcode::G_INTRINSIC_ROUND:
1754 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1755 case TargetOpcode::G_INTRINSIC_TRUNC: {
1757 KnownFPClass KnownSrc;
1768 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1772 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1776 case TargetOpcode::G_INTRINSIC_TRUNC:
1779 case TargetOpcode::G_FFLOOR:
1782 case TargetOpcode::G_FCEIL:
1791 case TargetOpcode::G_FEXP:
1792 case TargetOpcode::G_FEXP2:
1793 case TargetOpcode::G_FEXP10: {
1795 KnownFPClass KnownSrc;
1796 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1801 case TargetOpcode::G_FLOG:
1802 case TargetOpcode::G_FLOG2:
1803 case TargetOpcode::G_FLOG10: {
1827 KnownFPClass KnownSrc;
1828 if (InterestedSrcs !=
fcNone)
1829 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1834 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1839 case TargetOpcode::G_FPOW: {
1840 const bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1842 if (!WantNaN && !WantNegative)
1851 InterestedRHS |=
fcNan;
1860 KnownFPClass KnownLHS;
1861 computeKnownFPClass(
MI.getOperand(1).getReg(), DemandedElts, InterestedLHS,
1862 KnownLHS,
Depth + 1);
1869 KnownFPClass KnownRHS;
1870 computeKnownFPClass(
MI.getOperand(2).getReg(), DemandedElts, InterestedRHS,
1871 KnownRHS,
Depth + 1);
1875 case TargetOpcode::G_FPOWI: {
1880 LLT ExpTy = MRI.getType(Exp);
1882 Exp, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1885 if (InterestedClasses &
fcNan)
1886 InterestedSrcs |=
fcNan;
1887 if (!ExponentKnownBits.
isZero()) {
1888 if (InterestedClasses &
fcInf)
1894 KnownFPClass KnownSrc;
1895 if (InterestedSrcs !=
fcNone) {
1897 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1904 case TargetOpcode::G_FLDEXP: {
1906 KnownFPClass KnownSrc;
1907 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1915 LLT ExpTy = MRI.getType(ExpReg);
1917 ExpReg, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1922 DenormalMode
Mode = MF->getDenormalMode(Flt);
1926 case TargetOpcode::G_FADD:
1927 case TargetOpcode::G_FSUB: {
1930 bool IsAdd = Opcode == TargetOpcode::G_FADD;
1934 bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1937 if (!WantNaN && !WantNegative && !WantNegZero) {
1947 if (InterestedClasses &
fcNan)
1948 InterestedSrcs |=
fcInf;
1952 KnownFPClass KnownSelf;
1953 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSelf,
1959 KnownFPClass KnownLHS, KnownRHS;
1960 computeKnownFPClass(
RHS, DemandedElts, InterestedSrcs, KnownRHS,
Depth + 1);
1964 WantNegZero || !IsAdd) {
1967 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownLHS,
1977 case TargetOpcode::G_FMUL: {
1985 KnownFPClass KnownSrc;
1992 KnownFPClass KnownLHS;
1996 KnownFPClass KnownLHS, KnownRHS;
2012 case TargetOpcode::G_FDIV: {
2013 const bool WantNan = (InterestedClasses &
fcNan) !=
fcNone;
2028 KnownFPClass KnownSrc;
2029 computeKnownFPClass(
LHS, DemandedElts,
2038 if (!WantNan && !WantNegative && !WantPositive)
2041 KnownFPClass KnownLHS, KnownRHS;
2044 bool KnowSomethingUseful =
2049 if (KnowSomethingUseful)
2055 case TargetOpcode::G_FREM: {
2060 if (InterestedClasses &
fcNan) {
2088 FPClassTest InterestedSrcs = InterestedLHS | InterestedRHS;
2089 KnownFPClass KnownSrc;
2090 if (InterestedSrcs !=
fcNone)
2091 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSrc,
2097 KnownFPClass KnownLHS;
2098 if (InterestedLHS !=
fcNone)
2099 computeKnownFPClass(
LHS, DemandedElts, InterestedLHS, KnownLHS,
2102 KnownFPClass KnownRHS;
2105 computeKnownFPClass(
RHS, DemandedElts, InterestedRHS, KnownRHS,
2112 case TargetOpcode::G_FFREXP: {
2114 if (R !=
MI.getOperand(0).getReg())
2133 KnownFPClass KnownSrc;
2134 computeKnownFPClass(Src, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
2140 case TargetOpcode::G_FPEXT: {
2142 KnownFPClass KnownSrc;
2143 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
2154 case TargetOpcode::G_FPTRUNC:
2155 case TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND: {
2156 computeKnownFPClassForFPTrunc(
MI, DemandedElts, InterestedClasses,
Known,
2160 case TargetOpcode::G_SITOFP:
2161 case TargetOpcode::G_UITOFP: {
2172 if (Opcode == TargetOpcode::G_UITOFP)
2173 Known.signBitMustBeZero();
2180 LLT Ty = MRI.getType(Val);
2182 Val, Ty.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
2188 if (Opcode == TargetOpcode::G_SITOFP) {
2193 Known.signBitMustBeZero();
2195 Known.signBitMustBeOne();
2198 if (InterestedClasses &
fcInf) {
2205 if (Opcode == TargetOpcode::G_UITOFP)
2219 case TargetOpcode::G_BUILD_VECTOR:
2220 case TargetOpcode::G_CONCAT_VECTORS: {
2227 for (
unsigned Idx = 0;
Idx <
Merge.getNumSources(); ++
Idx) {
2229 bool NeedsElt = DemandedElts[
Idx];
2235 computeKnownFPClass(Src,
Known, InterestedClasses,
Depth + 1);
2238 KnownFPClass Known2;
2239 computeKnownFPClass(Src, Known2, InterestedClasses,
Depth + 1);
2244 if (
Known.isUnknown())
2251 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
2261 LLT VecTy = MRI.getType(Vec);
2266 if (CIdx && CIdx->ult(NumElts))
2268 return computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses,
Known,
2274 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2280 LLT VecTy = MRI.getType(Vec);
2288 APInt DemandedVecElts = DemandedElts;
2289 bool NeedsElt =
true;
2291 if (CIdx && CIdx->ult(NumElts)) {
2292 DemandedVecElts.
clearBit(CIdx->getZExtValue());
2293 NeedsElt = DemandedElts[CIdx->getZExtValue()];
2298 computeKnownFPClass(Elt,
Known, InterestedClasses,
Depth + 1);
2300 if (
Known.isUnknown())
2307 if (!DemandedVecElts.
isZero()) {
2308 KnownFPClass Known2;
2309 computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses, Known2,
2316 case TargetOpcode::G_SHUFFLE_VECTOR: {
2320 APInt DemandedLHS, DemandedRHS;
2322 assert(DemandedElts == APInt(1, 1));
2323 DemandedLHS = DemandedRHS = DemandedElts;
2325 unsigned NumElts = MRI.getType(Shuf.
getSrc1Reg()).getNumElements();
2327 DemandedLHS, DemandedRHS)) {
2333 if (!!DemandedLHS) {
2335 computeKnownFPClass(
LHS, DemandedLHS, InterestedClasses,
Known,
2339 if (
Known.isUnknown())
2345 if (!!DemandedRHS) {
2346 KnownFPClass Known2;
2348 computeKnownFPClass(
RHS, DemandedRHS, InterestedClasses, Known2,
2354 case TargetOpcode::G_PHI: {
2363 for (
unsigned Idx = 1;
Idx <
MI.getNumOperands();
Idx += 2) {
2364 const MachineOperand &Src =
MI.getOperand(Idx);
2367 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses,
Known,
2371 KnownFPClass Known2;
2372 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses, Known2,
2376 if (
Known.isUnknown())
2381 case TargetOpcode::G_FREEZE: {
2384 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
2389 case TargetOpcode::COPY: {
2392 if (!Src.isVirtual())
2395 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
Depth + 1);
2406 computeKnownFPClass(R, DemandedElts, InterestedClasses, KnownClasses,
Depth);
2407 return KnownClasses;
2413 computeKnownFPClass(R,
Known, InterestedClasses,
Depth);
2421 InterestedClasses &=
~fcNan;
2423 InterestedClasses &=
~fcInf;
2426 computeKnownFPClass(R, DemandedElts, InterestedClasses,
Depth);
2429 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcNan);
2431 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcInf);
2437 LLT Ty = MRI.getType(R);
2438 APInt DemandedElts =
2440 return computeKnownFPClass(R, DemandedElts, Flags, InterestedClasses,
Depth);
2455 switch (
DefMI->getOpcode()) {
2458 case TargetOpcode::G_FADD:
2459 case TargetOpcode::G_STRICT_FADD:
2460 case TargetOpcode::G_FSUB:
2461 case TargetOpcode::G_STRICT_FSUB:
2462 case TargetOpcode::G_FMUL:
2463 case TargetOpcode::G_STRICT_FMUL:
2464 case TargetOpcode::G_FDIV:
2465 case TargetOpcode::G_FREM:
2466 case TargetOpcode::G_FMA:
2467 case TargetOpcode::G_STRICT_FMA:
2468 case TargetOpcode::G_FMAD:
2469 case TargetOpcode::G_FSQRT:
2470 case TargetOpcode::G_STRICT_FSQRT:
2474 case TargetOpcode::G_FSIN:
2475 case TargetOpcode::G_FCOS:
2476 case TargetOpcode::G_FSINCOS:
2477 case TargetOpcode::G_FTAN:
2478 case TargetOpcode::G_FASIN:
2479 case TargetOpcode::G_FACOS:
2480 case TargetOpcode::G_FATAN:
2481 case TargetOpcode::G_FATAN2:
2482 case TargetOpcode::G_FSINH:
2483 case TargetOpcode::G_FCOSH:
2484 case TargetOpcode::G_FTANH:
2485 case TargetOpcode::G_FEXP:
2486 case TargetOpcode::G_FEXP2:
2487 case TargetOpcode::G_FEXP10:
2488 case TargetOpcode::G_FLOG:
2489 case TargetOpcode::G_FLOG2:
2490 case TargetOpcode::G_FLOG10:
2491 case TargetOpcode::G_FPOW:
2492 case TargetOpcode::G_FPOWI:
2493 case TargetOpcode::G_FLDEXP:
2494 case TargetOpcode::G_STRICT_FLDEXP:
2495 case TargetOpcode::G_FFREXP:
2496 case TargetOpcode::G_INTRINSIC_TRUNC:
2497 case TargetOpcode::G_INTRINSIC_ROUND:
2498 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
2499 case TargetOpcode::G_FFLOOR:
2500 case TargetOpcode::G_FCEIL:
2501 case TargetOpcode::G_FRINT:
2502 case TargetOpcode::G_FNEARBYINT:
2503 case TargetOpcode::G_FPEXT:
2504 case TargetOpcode::G_FPTRUNC:
2505 case TargetOpcode::G_FCANONICALIZE:
2506 case TargetOpcode::G_FMINNUM:
2507 case TargetOpcode::G_FMAXNUM:
2508 case TargetOpcode::G_FMINNUM_IEEE:
2509 case TargetOpcode::G_FMAXNUM_IEEE:
2510 case TargetOpcode::G_FMINIMUM:
2511 case TargetOpcode::G_FMAXIMUM:
2512 case TargetOpcode::G_FMINIMUMNUM:
2513 case TargetOpcode::G_FMAXIMUMNUM:
2529 return Known.isKnownNeverLogicalZero(
2534unsigned GISelValueTracking::computeNumSignBitsMin(
Register Src0,
Register Src1,
2535 const APInt &DemandedElts,
2539 if (Src1SignBits == 1)
2549 const MDNode *Ranges = Ld->getRanges();
2555 switch (Ld->getOpcode()) {
2556 case TargetOpcode::G_SEXTLOAD:
2559 case TargetOpcode::G_ZEXTLOAD:
2572 const APInt &DemandedElts,
2575 unsigned Opcode =
MI.getOpcode();
2577 if (Opcode == TargetOpcode::G_CONSTANT)
2578 return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
2586 LLT DstTy = MRI.getType(R);
2596 unsigned FirstAnswer = 1;
2598 case TargetOpcode::COPY: {
2600 if (Src.getReg().isVirtual() && Src.getSubReg() == 0 &&
2601 MRI.getType(Src.getReg()).isValid()) {
2608 case TargetOpcode::G_FREEZE: {
2614 case TargetOpcode::G_SEXT: {
2616 LLT SrcTy = MRI.getType(Src);
2617 unsigned Tmp = TyBits - SrcTy.getScalarSizeInBits();
2620 case TargetOpcode::G_ASSERT_SEXT:
2621 case TargetOpcode::G_SEXT_INREG: {
2624 unsigned SrcBits =
MI.getOperand(2).getImm();
2625 unsigned InRegBits = TyBits - SrcBits + 1;
2629 case TargetOpcode::G_LOAD: {
2636 case TargetOpcode::G_SEXTLOAD: {
2651 case TargetOpcode::G_ZEXTLOAD: {
2666 case TargetOpcode::G_AND:
2667 case TargetOpcode::G_OR:
2668 case TargetOpcode::G_XOR: {
2670 unsigned Src1NumSignBits =
2672 if (Src1NumSignBits != 1) {
2674 unsigned Src2NumSignBits =
2676 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits);
2680 case TargetOpcode::G_ASHR: {
2685 FirstAnswer = std::min<uint64_t>(FirstAnswer + *
C, TyBits);
2688 case TargetOpcode::G_SHL: {
2691 if (std::optional<ConstantRange> ShAmtRange =
2693 uint64_t MaxShAmt = ShAmtRange->getUnsignedMax().getZExtValue();
2694 uint64_t MinShAmt = ShAmtRange->getUnsignedMin().getZExtValue();
2704 if (ExtOpc == TargetOpcode::G_SEXT || ExtOpc == TargetOpcode::G_ZEXT ||
2705 ExtOpc == TargetOpcode::G_ANYEXT) {
2706 LLT ExtTy = MRI.getType(Src1);
2708 LLT ExtendeeTy = MRI.getType(Extendee);
2712 if (SizeDiff <= MinShAmt) {
2716 return Tmp - MaxShAmt;
2722 return Tmp - MaxShAmt;
2726 case TargetOpcode::G_ROTL:
2727 case TargetOpcode::G_ROTR: {
2736 case TargetOpcode::G_SAVGFLOOR:
2737 case TargetOpcode::G_SAVGCEIL: {
2740 FirstAnswer = computeNumSignBitsMin(Src1, Src2, DemandedElts,
Depth + 1);
2743 case TargetOpcode::G_SREM: {
2751 case TargetOpcode::G_TRUNC: {
2753 LLT SrcTy = MRI.getType(Src);
2758 if (NumSrcSignBits > (NumSrcBits - TyBits))
2759 return NumSrcSignBits - (NumSrcBits - TyBits);
2762 case TargetOpcode::G_SELECT: {
2763 return computeNumSignBitsMin(
MI.getOperand(2).getReg(),
2764 MI.getOperand(3).getReg(), DemandedElts,
2767 case TargetOpcode::G_SMIN:
2768 case TargetOpcode::G_SMAX:
2769 case TargetOpcode::G_UMIN:
2770 case TargetOpcode::G_UMAX:
2772 return computeNumSignBitsMin(
MI.getOperand(1).getReg(),
2773 MI.getOperand(2).getReg(), DemandedElts,
2775 case TargetOpcode::G_SADDO:
2776 case TargetOpcode::G_SADDE:
2777 case TargetOpcode::G_UADDO:
2778 case TargetOpcode::G_UADDE:
2779 case TargetOpcode::G_SSUBO:
2780 case TargetOpcode::G_SSUBE:
2781 case TargetOpcode::G_USUBO:
2782 case TargetOpcode::G_USUBE:
2783 case TargetOpcode::G_SMULO:
2784 case TargetOpcode::G_UMULO: {
2788 if (
MI.getOperand(1).getReg() == R) {
2789 if (TL.getBooleanContents(DstTy.
isVector(),
false) ==
2796 case TargetOpcode::G_SUB: {
2798 unsigned Src2NumSignBits =
2800 if (Src2NumSignBits == 1)
2810 if ((Known2.
Zero | 1).isAllOnes())
2817 FirstAnswer = Src2NumSignBits;
2824 unsigned Src1NumSignBits =
2826 if (Src1NumSignBits == 1)
2831 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2834 case TargetOpcode::G_ADD: {
2836 unsigned Src2NumSignBits =
2838 if (Src2NumSignBits <= 2)
2842 unsigned Src1NumSignBits =
2844 if (Src1NumSignBits == 1)
2853 if ((Known1.
Zero | 1).isAllOnes())
2859 FirstAnswer = Src1NumSignBits;
2868 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2871 case TargetOpcode::G_MUL: {
2872 unsigned Src2NumSignBits =
2874 if (Src2NumSignBits == 1)
2876 unsigned Src1NumSignBits =
2878 if (Src1NumSignBits == 1)
2882 unsigned OutValidBits =
2883 (TyBits - Src1NumSignBits + 1) + (TyBits - Src2NumSignBits + 1);
2884 if (OutValidBits <= TyBits)
2885 FirstAnswer = TyBits - OutValidBits + 1;
2888 case TargetOpcode::G_FCMP:
2889 case TargetOpcode::G_ICMP: {
2890 bool IsFP = Opcode == TargetOpcode::G_FCMP;
2893 auto BC = TL.getBooleanContents(DstTy.
isVector(), IsFP);
2900 case TargetOpcode::G_UNMERGE_VALUES: {
2901 unsigned NumOps =
MI.getNumOperands();
2903 LLT SrcTy = MRI.getType(SrcReg);
2905 if ((SrcTy.isVector() && SrcTy.getScalarType() != DstTy.
getScalarType()) ||
2906 (SrcTy.isScalar() && DstTy.
isVector()))
2910 unsigned DstIdx =
MI.findRegisterDefOperandIdx(R,
nullptr);
2912 APInt SubDemandedElts = DemandedElts;
2914 if (SrcTy.isVector()) {
2916 DemandedElts.
zext(SrcTy.getNumElements()).
shl(DstIdx * DstLanes);
2919 unsigned SrcOpKnown =
2921 if (SrcTy.isVector()) {
2922 FirstAnswer = SrcOpKnown;
2923 }
else if (SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 2) * TyBits) {
2924 FirstAnswer = SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 1) * TyBits
2926 : SrcOpKnown % TyBits;
2930 case TargetOpcode::G_BUILD_VECTOR: {
2932 FirstAnswer = TyBits;
2933 APInt SingleDemandedElt(1, 1);
2935 if (!DemandedElts[
I])
2940 FirstAnswer = std::min(FirstAnswer, Tmp2);
2943 if (FirstAnswer == 1)
2948 case TargetOpcode::G_CONCAT_VECTORS: {
2949 if (MRI.getType(
MI.getOperand(0).getReg()).isScalableVector())
2951 FirstAnswer = TyBits;
2954 unsigned NumSubVectorElts =
2955 MRI.getType(
MI.getOperand(1).getReg()).getNumElements();
2958 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
2963 FirstAnswer = std::min(FirstAnswer, Tmp2);
2966 if (FirstAnswer == 1)
2971 case TargetOpcode::G_VECTOR_COMPRESS: {
2975 Register PassThru =
MI.getOperand(3).getReg();
2984 FirstAnswer = std::min(Tmp, Tmp2);
2987 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2989 Register InVec = Insert.getVectorReg();
2990 Register InVal = Insert.getElementReg();
2991 LLT VecVT = MRI.getType(InVec);
2997 bool DemandedVal =
true;
2998 APInt DemandedVecElts = DemandedElts;
3002 if (ConstEltNo && ConstEltNo->ult(NumElts)) {
3003 unsigned EltIdx = ConstEltNo->getZExtValue();
3004 DemandedVal = !!DemandedElts[EltIdx];
3009 unsigned Tmp = TyBits;
3012 if (MRI.getType(InVal).getSizeInBits() != TyBits)
3015 Tmp = std::min(Tmp, ValSignBits);
3017 if (!!DemandedVecElts) {
3018 unsigned VecSignBits =
3020 Tmp = std::min(Tmp, VecSignBits);
3024 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
3028 LLT VecVT = MRI.getType(InVec);
3033 APInt DemandedSrcElts =
3034 ConstEltNo && ConstEltNo->ult(NumSrcElts)
3039 case TargetOpcode::G_EXTRACT_SUBVECTOR: {
3042 LLT SrcTy = MRI.getType(SrcReg);
3043 APInt DemandedSrcElts;
3044 if (SrcTy.isScalableVector()) {
3045 DemandedSrcElts =
APInt(1, 1);
3047 uint64_t Idx =
MI.getOperand(2).getImm();
3048 unsigned NumSrcElts = SrcTy.getNumElements();
3049 DemandedSrcElts = DemandedElts.
zext(NumSrcElts).
shl(Idx);
3053 case TargetOpcode::G_SHUFFLE_VECTOR: {
3056 APInt DemandedLHS, DemandedRHS;
3058 unsigned NumElts = MRI.getType(Src1).getNumElements();
3060 DemandedElts, DemandedLHS, DemandedRHS))
3066 if (FirstAnswer == 1)
3068 if (!!DemandedRHS) {
3071 FirstAnswer = std::min(FirstAnswer, Tmp2);
3075 case TargetOpcode::G_SPLAT_VECTOR: {
3079 unsigned NumSrcBits = MRI.getType(Src).getSizeInBits();
3080 if (NumSrcSignBits > (NumSrcBits - TyBits))
3081 return NumSrcSignBits - (NumSrcBits - TyBits);
3084 case TargetOpcode::G_INTRINSIC:
3085 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
3086 case TargetOpcode::G_INTRINSIC_CONVERGENT:
3087 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
3090 TL.computeNumSignBitsForTargetInstr(*
this, R, DemandedElts, MRI,
Depth);
3092 FirstAnswer = std::max(FirstAnswer, NumBits);
3100 return std::max(FirstAnswer,
Known.countMinSignBits());
3104 LLT Ty = MRI.getType(R);
3105 APInt DemandedElts =
3114 unsigned Opcode =
MI.getOpcode();
3116 LLT Ty = MRI.getType(R);
3117 unsigned BitWidth = Ty.getScalarSizeInBits();
3119 if (Opcode == TargetOpcode::G_CONSTANT) {
3120 const APInt &ShAmt =
MI.getOperand(1).getCImm()->getValue();
3122 return std::nullopt;
3126 if (Opcode == TargetOpcode::G_BUILD_VECTOR) {
3127 const APInt *MinAmt =
nullptr, *MaxAmt =
nullptr;
3128 for (
unsigned I = 0, E =
MI.getNumOperands() - 1;
I != E; ++
I) {
3129 if (!DemandedElts[
I])
3132 if (
Op->getOpcode() != TargetOpcode::G_CONSTANT) {
3133 MinAmt = MaxAmt =
nullptr;
3137 const APInt &ShAmt =
Op->getOperand(1).getCImm()->getValue();
3139 return std::nullopt;
3140 if (!MinAmt || MinAmt->
ugt(ShAmt))
3142 if (!MaxAmt || MaxAmt->ult(ShAmt))
3145 assert(((!MinAmt && !MaxAmt) || (MinAmt && MaxAmt)) &&
3146 "Failed to find matching min/max shift amounts");
3147 if (MinAmt && MaxAmt)
3157 return std::nullopt;
3162 if (std::optional<ConstantRange> AmtRange =
3164 return AmtRange->getUnsignedMin().getZExtValue();
3165 return std::nullopt;
3183 Info = std::make_unique<GISelValueTracking>(MF, MaxDepth);
3195 return Result(MF, MaxDepth);
3201 bool PrintFPClass) {
3211 if (!MO.isReg() || MO.getReg().isPhysical())
3214 if (!MRI.getType(
Reg).isValid())
3219 <<
" SignBitKnown:";
3227 unsigned SignedBits = VTA.computeNumSignBits(
Reg);
3228 bool IsKnownNeverZero = VTA.isKnownNeverZero(
Reg);
3229 OS <<
" " << MO <<
" KnownBits:" <<
Known
3230 <<
" SignBits:" << SignedBits
3231 <<
" IsKnownNeverZero:" << IsKnownNeverZero <<
'\n';
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Utilities for dealing with flags related to floating point properties and mode controls.
static void dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth)
static void genUnknown(MachineRegisterInfo &MRI, Register Reg, KnownBits &Known)
static PreservedAnalyses printGISelValueTracking(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM, raw_ostream &OS, bool PrintFPClass)
static unsigned computeNumSignBitsFromRangeMetadata(const GAnyLoad *Ld, unsigned TyBits)
Compute the known number of sign bits with attached range metadata in the memory operand.
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Implement a low-level type suitable for MachineInstr level instruction selection.
Contains matchers for matching SSA Machine Instructions.
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static uint64_t umul_ov(uint64_t i, uint64_t j, bool &Overflow)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static bool isAbsoluteValueULEOne(const Value *V)
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
static const fltSemantics & PPCDoubleDouble()
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
Class for arbitrary precision integers.
LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
unsigned getNumSignBits() const
Computes the number of leading bits of this APInt that are equal to its sign bit.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
void clearBits(unsigned LoBit, unsigned HiBit)
Clear the bits from LoBit (inclusive) to HiBit (exclusive) to 0.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This class represents a range of values.
static LLVM_ABI ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
LLVM_ABI KnownBits toKnownBits() const
Return known bits for values in this range.
LLVM_ABI ConstantRange zeroExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
LLVM_ABI APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
LLVM_ABI ConstantRange signExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
LLVM_ABI ConstantRange multiply(const ConstantRange &Other, unsigned NoWrapKind=0) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
LLVM_ABI APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
Represents any generic load, including sign/zero extending variants.
static LLVM_ABI std::optional< GFConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
GISelValueTracking & get(MachineFunction &MF)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
GISelValueTracking Result
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned getMaxDepth() const
KnownBits getKnownBits(Register R)
Align computeKnownAlignment(Register R, unsigned Depth=0)
std::optional< ConstantRange > getValidShiftAmountRange(Register R, const APInt &DemandedElts, unsigned Depth)
If a G_SHL/G_ASHR/G_LSHR node with shift operand R has shift amounts that are all less than the eleme...
bool maskedValueIsZero(Register Val, const APInt &Mask)
std::optional< uint64_t > getValidMinimumShiftAmount(Register R, const APInt &DemandedElts, unsigned Depth=0)
If a G_SHL/G_ASHR/G_LSHR node with shift operand R has shift amounts that are all less than the eleme...
bool signBitIsZero(Register Op)
const DataLayout & getDataLayout() const
unsigned computeNumSignBits(Register R, const APInt &DemandedElts, unsigned Depth=0)
const MachineFunction & getMachineFunction() const
bool isKnownNeverNaN(Register Val, bool SNaN=false)
Returns true if Val can be assumed to never be a NaN.
bool isKnownNeverLogicalZero(Register Val, unsigned Depth=0)
Returns true if Val can be assumed to never be a zero, accounting for denormal flushing of the contai...
APInt getKnownOnes(Register R)
APInt getKnownZeroes(Register R)
void computeKnownBitsImpl(Register R, KnownBits &Known, const APInt &DemandedElts, unsigned Depth=0)
Evaluate a known-bits query with an explicit worklist instead of recursive descent.
bool isKnownNeverZero(Register R, unsigned Depth=0)
Return true if the value defined by R is provably never zero.
Represents an insert vector element.
Register getCondReg() const
Register getFalseReg() const
Register getTrueReg() const
Represents a G_SHUFFLE_VECTOR.
Register getSrc2Reg() const
Register getSrc1Reg() const
ArrayRef< int > getMask() const
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr unsigned getScalarSizeInBits() const
LLT getScalarType() const
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr ElementCount getElementCount() const
constexpr unsigned getAddressSpace() const
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
TypeSize getValue() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
LLT getMemoryType() const
Return the memory type of the memory reference.
const MDNode * getRanges() const
Return the range tag for the memory reference.
LocationSize getSizeInBits() const
Return the size in bits of the memory reference.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
Value * getOperand(unsigned i) const
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt fshr(const APInt &Hi, const APInt &Lo, const APInt &Shift)
Perform a funnel shift right.
operand_type_match m_Reg()
UnaryOp_match< SrcTy, TargetOpcode::G_FFLOOR > m_GFFloor(const SrcTy &Src)
operand_type_match m_Pred()
bind_ty< FPClassTest > m_FPClassTest(FPClassTest &T)
deferred_ty< Register > m_DeferredReg(Register &R)
Similar to m_SpecificReg/Type, but the specific value to match originated from an earlier sub-pattern...
BinaryOp_match< LHS, RHS, TargetOpcode::G_FSUB, false > m_GFSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
ClassifyOp_match< LHS, Test, TargetOpcode::G_IS_FPCLASS > m_GIsFPClass(const LHS &L, const Test &T)
Matches the register and immediate used in a fpclass test G_IS_FPCLASS val, 96.
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP > m_GFCmp(const Pred &P, const LHS &L, const RHS &R)
LLVM_ABI unsigned rot(unsigned SrcSignBits, unsigned BitWidth, std::optional< APInt > RotAmt, bool IsRotateRight)
Compute the number of sign bits after rotating a value.
unsigned getNumElements(Type *Ty)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI std::optional< APInt > isConstantOrConstantSplatVector(Register Def, const MachineRegisterInfo &MRI)
Determines if Def defines a constant integer or a splat vector of constant integers.
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
@ Known
Known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI const llvm::fltSemantics & getFltSemanticForLLT(LLT Ty)
Get the appropriate floating point arithmetic semantic based on the bit size of the given scalar LLT.
scope_exit(Callable) -> scope_exit< Callable >
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
std::tuple< Value *, FPClassTest, FPClassTest > fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, FPClassTest RHSClass, bool LookThroughSrc=true)
LLVM_ABI bool getShuffleDemandedElts(int SrcWidth, ArrayRef< int > Mask, const APInt &DemandedElts, APInt &DemandedLHS, APInt &DemandedRHS, bool AllowUndefElts=false)
Transform a shuffle mask's output demanded element mask into demanded element masks for the 2 operand...
constexpr unsigned MaxAnalysisRecursionDepth
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
static uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo)
LLVM_ABI void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, KnownBits &Known)
Compute known bits from the range metadata.
This struct is a compact representation of a valid (non-zero power of two) alignment.
A special type used by analysis passes to provide an address that identifies that particular analysis...
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
static LLVM_ABI KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from llvm.sadd.sat(LHS, RHS)
KnownBits anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
static LLVM_ABI KnownBits mulhu(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits from zero-extended multiply-hi.
unsigned countMinSignBits() const
Returns the number of times the sign bit is replicated into the other bits.
static LLVM_ABI KnownBits smax(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for smax(LHS, RHS).
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
static LLVM_ABI KnownBits usub_sat(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from llvm.usub.sat(LHS, RHS)
static LLVM_ABI KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)
Compute known bits for ashr(LHS, RHS).
static LLVM_ABI KnownBits ssub_sat(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from llvm.ssub.sat(LHS, RHS)
static LLVM_ABI KnownBits urem(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for urem(LHS, RHS).
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
static LLVM_ABI KnownBits fshl(const KnownBits &LHS, const KnownBits &RHS, const APInt &Amt)
Compute known bits for fshl(LHS, RHS, Amt).
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
unsigned getBitWidth() const
Get the bit width of this value.
static LLVM_ABI KnownBits umax(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for umax(LHS, RHS).
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false, bool SelfAdd=false)
Compute knownbits resulting from addition of LHS and RHS.
static LLVM_ABI KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)
Compute known bits for lshr(LHS, RHS).
bool isNonZero() const
Returns true if this value is known to be non-zero.
static LLVM_ABI KnownBits abdu(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for abdu(LHS, RHS).
bool isEven() const
Return if the value is known even (the low bit is 0).
KnownBits extractBits(unsigned NumBits, unsigned BitPosition) const
Return a subset of the known bits from [bitPosition,bitPosition+numBits).
static LLVM_ABI KnownBits avgFloorU(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from APIntOps::avgFloorU.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
KnownBits zextOrTrunc(unsigned BitWidth) const
Return known bits for a zero extension or truncation of the value we're tracking.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
static LLVM_ABI KnownBits abds(KnownBits LHS, KnownBits RHS)
Compute known bits for abds(LHS, RHS).
static LLVM_ABI KnownBits smin(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for smin(LHS, RHS).
static LLVM_ABI KnownBits mulhs(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits from sign-extended multiply-hi.
static LLVM_ABI KnownBits srem(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for srem(LHS, RHS).
static LLVM_ABI KnownBits udiv(const KnownBits &LHS, const KnownBits &RHS, bool Exact=false)
Compute known bits for udiv(LHS, RHS).
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
static LLVM_ABI KnownBits sdiv(const KnownBits &LHS, const KnownBits &RHS, bool Exact=false)
Compute known bits for sdiv(LHS, RHS).
static LLVM_ABI KnownBits avgFloorS(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from APIntOps::avgFloorS.
bool isNegative() const
Returns true if this value is known to be negative.
static LLVM_ABI KnownBits computeForAddCarry(const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry)
Compute known bits resulting from adding LHS, RHS and a 1-bit Carry.
static KnownBits sub(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false)
Compute knownbits resulting from subtraction of LHS and RHS.
unsigned countMaxLeadingZeros() const
Returns the maximum number of leading zero bits possible.
static LLVM_ABI KnownBits avgCeilU(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from APIntOps::avgCeilU.
static LLVM_ABI KnownBits uadd_sat(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from llvm.uadd.sat(LHS, RHS)
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
static LLVM_ABI KnownBits clmul(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for clmul(LHS, RHS).
static LLVM_ABI KnownBits shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW=false, bool NSW=false, bool ShAmtNonZero=false)
Compute known bits for shl(LHS, RHS).
static LLVM_ABI KnownBits umin(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for umin(LHS, RHS).
bool isAllOnes() const
Returns true if value is all one bits.
static LLVM_ABI KnownBits avgCeilS(const KnownBits &LHS, const KnownBits &RHS)
Compute knownbits resulting from APIntOps::avgCeilS.
void setKnownFPClasses(FPClassTest Classes)
static LLVM_ABI KnownFPClass sin(const KnownFPClass &Src)
Report known values for sin.
static LLVM_ABI KnownFPClass frem(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem.
static LLVM_ABI KnownFPClass fdiv_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv x, x.
static constexpr FPClassTest OrderedLessThanZeroMask
void knownNot(FPClassTest RuleOut)
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmul.
static LLVM_ABI KnownFPClass ceil(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ceil.
static LLVM_ABI KnownFPClass fadd_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd x, x.
static KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fsub.
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
static LLVM_ABI KnownFPClass atan2(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for atan2.
static LLVM_ABI KnownFPClass atan(const KnownFPClass &Src)
Report known values for atan.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass cosh(const KnownFPClass &Src)
Report known values for cosh.
static LLVM_ABI KnownFPClass minMaxLike(const KnownFPClass &LHS, const KnownFPClass &RHS, MinMaxKind Kind, DenormalMode DenormMode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass exp(const KnownFPClass &Src)
Report known values for exp, exp2 and exp10.
static LLVM_ABI KnownFPClass frexp_mant(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for mantissa component of frexp.
static LLVM_ABI KnownFPClass asin(const KnownFPClass &Src)
Report known values for asin.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
std::optional< bool > getSignBit() const
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy)
Propagate known class for fpext.
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for rounding intrinsics (rint, nearbyint, round, roundeven).
static LLVM_ABI KnownFPClass fma(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma.
static LLVM_ABI KnownFPClass tan(const KnownFPClass &Src)
Report known values for tan.
static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc)
Propagate known class for fptrunc.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
static LLVM_ABI KnownFPClass sqrt(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for sqrt.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
static LLVM_ABI KnownFPClass trunc(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for trunc.
static LLVM_ABI KnownFPClass fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma squared, squared, addend.
static LLVM_ABI KnownFPClass acos(const KnownFPClass &Src)
Report known values for acos.
static LLVM_ABI KnownFPClass log(const KnownFPClass &Src, DenormalMode Mode, bool IsMultiUnitFPType)
Propagate known class for log/log2/log10.
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem x, x.
static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src, const KnownBits &N)
Propagate known class for powi.
static LLVM_ABI KnownFPClass floor(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for floor.
static LLVM_ABI KnownFPClass pow(const KnownFPClass &LHS, const KnownFPClass &RHS)
Propagate known class for pow.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const APInt &ConstantRangeMin, const APInt &ConstantRangeMax, const fltSemantics &Flt, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ldexp, assuming the exponent is known to be within [ConstantRangeMin,...
static LLVM_ABI KnownFPClass sinh(const KnownFPClass &Src)
Report known values for sinh.
static LLVM_ABI KnownFPClass tanh(const KnownFPClass &Src)
Report known values for tanh.