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_STRICT_FMA:
1488 case TargetOpcode::G_FMAD: {
1501 KnownFPClass KnownSrc, KnownAddend;
1502 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownAddend,
1504 computeKnownFPClass(
A, DemandedElts, InterestedClasses, KnownSrc,
1506 if (KnownNotFromFlags) {
1507 KnownSrc.
knownNot(KnownNotFromFlags);
1508 KnownAddend.
knownNot(KnownNotFromFlags);
1512 KnownFPClass KnownSrc[3];
1513 computeKnownFPClass(
A, DemandedElts, InterestedClasses, KnownSrc[0],
1515 if (KnownSrc[0].isUnknown())
1517 computeKnownFPClass(
B, DemandedElts, InterestedClasses, KnownSrc[1],
1519 if (KnownSrc[1].isUnknown())
1521 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownSrc[2],
1523 if (KnownSrc[2].isUnknown())
1525 if (KnownNotFromFlags) {
1526 KnownSrc[0].
knownNot(KnownNotFromFlags);
1527 KnownSrc[1].
knownNot(KnownNotFromFlags);
1528 KnownSrc[2].
knownNot(KnownNotFromFlags);
1534 case TargetOpcode::G_FSQRT:
1535 case TargetOpcode::G_STRICT_FSQRT: {
1536 KnownFPClass KnownSrc;
1538 if (InterestedClasses &
fcNan)
1542 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1551 case TargetOpcode::G_FABS: {
1556 computeKnownFPClass(Val, DemandedElts, InterestedClasses,
Known,
1562 case TargetOpcode::G_FATAN2: {
1580 KnownFPClass KnownY, KnownX;
1581 computeKnownFPClass(
Y, DemandedElts, InterestedY, KnownY,
Depth + 1);
1582 computeKnownFPClass(
X, DemandedElts, InterestedX, KnownX,
Depth + 1);
1588 case TargetOpcode::G_FSINH: {
1590 KnownFPClass KnownSrc;
1591 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1596 case TargetOpcode::G_FCOSH: {
1598 KnownFPClass KnownSrc;
1599 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1604 case TargetOpcode::G_FTANH: {
1606 KnownFPClass KnownSrc;
1607 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1612 case TargetOpcode::G_FASIN: {
1614 KnownFPClass KnownSrc;
1615 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1620 case TargetOpcode::G_FACOS: {
1622 KnownFPClass KnownSrc;
1623 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1628 case TargetOpcode::G_FATAN: {
1630 KnownFPClass KnownSrc;
1631 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1636 case TargetOpcode::G_FTAN: {
1638 KnownFPClass KnownSrc;
1639 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1644 case TargetOpcode::G_FSIN:
1645 case TargetOpcode::G_FCOS: {
1648 KnownFPClass KnownSrc;
1649 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1652 : KnownFPClass::sin(KnownSrc);
1655 case TargetOpcode::G_FSINCOS: {
1658 KnownFPClass KnownSrc;
1659 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
1661 if (R ==
MI.getOperand(0).getReg())
1667 case TargetOpcode::G_FMAXNUM:
1668 case TargetOpcode::G_FMINNUM:
1669 case TargetOpcode::G_FMINNUM_IEEE:
1670 case TargetOpcode::G_FMAXIMUM:
1671 case TargetOpcode::G_FMINIMUM:
1672 case TargetOpcode::G_FMAXNUM_IEEE:
1673 case TargetOpcode::G_FMAXIMUMNUM:
1674 case TargetOpcode::G_FMINIMUMNUM: {
1677 KnownFPClass KnownLHS, KnownRHS;
1679 computeKnownFPClass(
LHS, DemandedElts, InterestedClasses, KnownLHS,
1681 computeKnownFPClass(
RHS, DemandedElts, InterestedClasses, KnownRHS,
1686 case TargetOpcode::G_FMINIMUM:
1689 case TargetOpcode::G_FMAXIMUM:
1692 case TargetOpcode::G_FMINIMUMNUM:
1695 case TargetOpcode::G_FMAXIMUMNUM:
1698 case TargetOpcode::G_FMINNUM:
1699 case TargetOpcode::G_FMINNUM_IEEE:
1702 case TargetOpcode::G_FMAXNUM:
1703 case TargetOpcode::G_FMAXNUM_IEEE:
1715 case TargetOpcode::G_FCANONICALIZE: {
1717 KnownFPClass KnownSrc;
1718 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1723 DenormalMode DenormMode = MF->getDenormalMode(FPType);
1727 case TargetOpcode::G_VECREDUCE_FMAX:
1728 case TargetOpcode::G_VECREDUCE_FMIN:
1729 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
1730 case TargetOpcode::G_VECREDUCE_FMINIMUM:
1731 case TargetOpcode::G_VECREDUCE_FMAXIMUMNUM:
1732 case TargetOpcode::G_VECREDUCE_FMINIMUMNUM: {
1738 computeKnownFPClass(Val,
MI.getFlags(), InterestedClasses,
Depth + 1);
1740 if (!
Known.isKnownNeverNaN())
1741 Known.setSignBit(std::nullopt);
1744 case TargetOpcode::G_FFLOOR:
1745 case TargetOpcode::G_FCEIL:
1746 case TargetOpcode::G_FRINT:
1747 case TargetOpcode::G_FNEARBYINT:
1748 case TargetOpcode::G_INTRINSIC_ROUND:
1749 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1750 case TargetOpcode::G_INTRINSIC_TRUNC: {
1752 KnownFPClass KnownSrc;
1763 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1767 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1770 const bool IsTrunc = Opcode == TargetOpcode::G_INTRINSIC_TRUNC;
1775 case TargetOpcode::G_FEXP:
1776 case TargetOpcode::G_FEXP2:
1777 case TargetOpcode::G_FEXP10: {
1779 KnownFPClass KnownSrc;
1780 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1785 case TargetOpcode::G_FLOG:
1786 case TargetOpcode::G_FLOG2:
1787 case TargetOpcode::G_FLOG10: {
1811 KnownFPClass KnownSrc;
1812 if (InterestedSrcs !=
fcNone)
1813 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1818 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1823 case TargetOpcode::G_FPOW: {
1824 const bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1826 if (!WantNaN && !WantNegative)
1835 InterestedRHS |=
fcNan;
1844 KnownFPClass KnownLHS;
1845 computeKnownFPClass(
MI.getOperand(1).getReg(), DemandedElts, InterestedLHS,
1846 KnownLHS,
Depth + 1);
1853 KnownFPClass KnownRHS;
1854 computeKnownFPClass(
MI.getOperand(2).getReg(), DemandedElts, InterestedRHS,
1855 KnownRHS,
Depth + 1);
1859 case TargetOpcode::G_FPOWI: {
1864 LLT ExpTy = MRI.getType(Exp);
1866 Exp, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1869 if (InterestedClasses &
fcNan)
1870 InterestedSrcs |=
fcNan;
1871 if (!ExponentKnownBits.
isZero()) {
1872 if (InterestedClasses &
fcInf)
1878 KnownFPClass KnownSrc;
1879 if (InterestedSrcs !=
fcNone) {
1881 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1888 case TargetOpcode::G_FLDEXP:
1889 case TargetOpcode::G_STRICT_FLDEXP: {
1891 KnownFPClass KnownSrc;
1892 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1900 LLT ExpTy = MRI.getType(ExpReg);
1902 ExpReg, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1907 DenormalMode
Mode = MF->getDenormalMode(Flt);
1911 case TargetOpcode::G_FADD:
1912 case TargetOpcode::G_STRICT_FADD:
1913 case TargetOpcode::G_FSUB:
1914 case TargetOpcode::G_STRICT_FSUB: {
1917 bool IsAdd = (Opcode == TargetOpcode::G_FADD ||
1918 Opcode == TargetOpcode::G_STRICT_FADD);
1922 bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1925 if (!WantNaN && !WantNegative && !WantNegZero) {
1935 if (InterestedClasses &
fcNan)
1936 InterestedSrcs |=
fcInf;
1940 KnownFPClass KnownSelf;
1941 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSelf,
1947 KnownFPClass KnownLHS, KnownRHS;
1948 computeKnownFPClass(
RHS, DemandedElts, InterestedSrcs, KnownRHS,
Depth + 1);
1952 WantNegZero || !IsAdd) {
1955 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownLHS,
1965 case TargetOpcode::G_FMUL:
1966 case TargetOpcode::G_STRICT_FMUL: {
1974 KnownFPClass KnownSrc;
1981 KnownFPClass KnownLHS;
1985 KnownFPClass KnownLHS, KnownRHS;
2001 case TargetOpcode::G_FDIV: {
2002 const bool WantNan = (InterestedClasses &
fcNan) !=
fcNone;
2017 KnownFPClass KnownSrc;
2018 computeKnownFPClass(
LHS, DemandedElts,
2027 if (!WantNan && !WantNegative && !WantPositive)
2030 KnownFPClass KnownLHS, KnownRHS;
2033 bool KnowSomethingUseful =
2038 if (KnowSomethingUseful)
2044 case TargetOpcode::G_FREM: {
2049 if (InterestedClasses &
fcNan) {
2077 FPClassTest InterestedSrcs = InterestedLHS | InterestedRHS;
2078 KnownFPClass KnownSrc;
2079 if (InterestedSrcs !=
fcNone)
2080 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSrc,
2086 KnownFPClass KnownLHS;
2087 if (InterestedLHS !=
fcNone)
2088 computeKnownFPClass(
LHS, DemandedElts, InterestedLHS, KnownLHS,
2091 KnownFPClass KnownRHS;
2094 computeKnownFPClass(
RHS, DemandedElts, InterestedRHS, KnownRHS,
2101 case TargetOpcode::G_FFREXP: {
2103 if (R !=
MI.getOperand(0).getReg())
2122 KnownFPClass KnownSrc;
2123 computeKnownFPClass(Src, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
2129 case TargetOpcode::G_FPEXT: {
2131 KnownFPClass KnownSrc;
2132 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
2143 case TargetOpcode::G_FPTRUNC:
2144 case TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND: {
2145 computeKnownFPClassForFPTrunc(
MI, DemandedElts, InterestedClasses,
Known,
2149 case TargetOpcode::G_SITOFP:
2150 case TargetOpcode::G_UITOFP: {
2161 if (Opcode == TargetOpcode::G_UITOFP)
2162 Known.signBitMustBeZero();
2169 LLT Ty = MRI.getType(Val);
2171 Val, Ty.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
2177 if (Opcode == TargetOpcode::G_SITOFP) {
2182 Known.signBitMustBeZero();
2184 Known.signBitMustBeOne();
2187 if (InterestedClasses &
fcInf) {
2194 if (Opcode == TargetOpcode::G_UITOFP)
2208 case TargetOpcode::G_BUILD_VECTOR:
2209 case TargetOpcode::G_CONCAT_VECTORS: {
2216 for (
unsigned Idx = 0;
Idx <
Merge.getNumSources(); ++
Idx) {
2218 bool NeedsElt = DemandedElts[
Idx];
2224 computeKnownFPClass(Src,
Known, InterestedClasses,
Depth + 1);
2227 KnownFPClass Known2;
2228 computeKnownFPClass(Src, Known2, InterestedClasses,
Depth + 1);
2233 if (
Known.isUnknown())
2240 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
2250 LLT VecTy = MRI.getType(Vec);
2255 if (CIdx && CIdx->ult(NumElts))
2257 return computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses,
Known,
2263 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2269 LLT VecTy = MRI.getType(Vec);
2277 APInt DemandedVecElts = DemandedElts;
2278 bool NeedsElt =
true;
2280 if (CIdx && CIdx->ult(NumElts)) {
2281 DemandedVecElts.
clearBit(CIdx->getZExtValue());
2282 NeedsElt = DemandedElts[CIdx->getZExtValue()];
2287 computeKnownFPClass(Elt,
Known, InterestedClasses,
Depth + 1);
2289 if (
Known.isUnknown())
2296 if (!DemandedVecElts.
isZero()) {
2297 KnownFPClass Known2;
2298 computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses, Known2,
2305 case TargetOpcode::G_SHUFFLE_VECTOR: {
2309 APInt DemandedLHS, DemandedRHS;
2311 assert(DemandedElts == APInt(1, 1));
2312 DemandedLHS = DemandedRHS = DemandedElts;
2314 unsigned NumElts = MRI.getType(Shuf.
getSrc1Reg()).getNumElements();
2316 DemandedLHS, DemandedRHS)) {
2322 if (!!DemandedLHS) {
2324 computeKnownFPClass(
LHS, DemandedLHS, InterestedClasses,
Known,
2328 if (
Known.isUnknown())
2334 if (!!DemandedRHS) {
2335 KnownFPClass Known2;
2337 computeKnownFPClass(
RHS, DemandedRHS, InterestedClasses, Known2,
2343 case TargetOpcode::G_PHI: {
2352 for (
unsigned Idx = 1;
Idx <
MI.getNumOperands();
Idx += 2) {
2353 const MachineOperand &Src =
MI.getOperand(Idx);
2356 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses,
Known,
2360 KnownFPClass Known2;
2361 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses, Known2,
2365 if (
Known.isUnknown())
2370 case TargetOpcode::G_FREEZE: {
2373 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
2378 case TargetOpcode::COPY: {
2381 if (!Src.isVirtual())
2384 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
Depth + 1);
2395 computeKnownFPClass(R, DemandedElts, InterestedClasses, KnownClasses,
Depth);
2396 return KnownClasses;
2402 computeKnownFPClass(R,
Known, InterestedClasses,
Depth);
2410 InterestedClasses &=
~fcNan;
2412 InterestedClasses &=
~fcInf;
2415 computeKnownFPClass(R, DemandedElts, InterestedClasses,
Depth);
2418 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcNan);
2420 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcInf);
2426 LLT Ty = MRI.getType(R);
2427 APInt DemandedElts =
2429 return computeKnownFPClass(R, DemandedElts, Flags, InterestedClasses,
Depth);
2444 switch (
DefMI->getOpcode()) {
2447 case TargetOpcode::G_FADD:
2448 case TargetOpcode::G_STRICT_FADD:
2449 case TargetOpcode::G_FSUB:
2450 case TargetOpcode::G_STRICT_FSUB:
2451 case TargetOpcode::G_FMUL:
2452 case TargetOpcode::G_STRICT_FMUL:
2453 case TargetOpcode::G_FDIV:
2454 case TargetOpcode::G_FREM:
2455 case TargetOpcode::G_FMA:
2456 case TargetOpcode::G_STRICT_FMA:
2457 case TargetOpcode::G_FMAD:
2458 case TargetOpcode::G_FSQRT:
2459 case TargetOpcode::G_STRICT_FSQRT:
2463 case TargetOpcode::G_FSIN:
2464 case TargetOpcode::G_FCOS:
2465 case TargetOpcode::G_FSINCOS:
2466 case TargetOpcode::G_FTAN:
2467 case TargetOpcode::G_FASIN:
2468 case TargetOpcode::G_FACOS:
2469 case TargetOpcode::G_FATAN:
2470 case TargetOpcode::G_FATAN2:
2471 case TargetOpcode::G_FSINH:
2472 case TargetOpcode::G_FCOSH:
2473 case TargetOpcode::G_FTANH:
2474 case TargetOpcode::G_FEXP:
2475 case TargetOpcode::G_FEXP2:
2476 case TargetOpcode::G_FEXP10:
2477 case TargetOpcode::G_FLOG:
2478 case TargetOpcode::G_FLOG2:
2479 case TargetOpcode::G_FLOG10:
2480 case TargetOpcode::G_FPOW:
2481 case TargetOpcode::G_FPOWI:
2482 case TargetOpcode::G_FLDEXP:
2483 case TargetOpcode::G_STRICT_FLDEXP:
2484 case TargetOpcode::G_FFREXP:
2485 case TargetOpcode::G_INTRINSIC_TRUNC:
2486 case TargetOpcode::G_INTRINSIC_ROUND:
2487 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
2488 case TargetOpcode::G_FFLOOR:
2489 case TargetOpcode::G_FCEIL:
2490 case TargetOpcode::G_FRINT:
2491 case TargetOpcode::G_FNEARBYINT:
2492 case TargetOpcode::G_FPEXT:
2493 case TargetOpcode::G_FPTRUNC:
2494 case TargetOpcode::G_FCANONICALIZE:
2495 case TargetOpcode::G_FMINNUM:
2496 case TargetOpcode::G_FMAXNUM:
2497 case TargetOpcode::G_FMINNUM_IEEE:
2498 case TargetOpcode::G_FMAXNUM_IEEE:
2499 case TargetOpcode::G_FMINIMUM:
2500 case TargetOpcode::G_FMAXIMUM:
2501 case TargetOpcode::G_FMINIMUMNUM:
2502 case TargetOpcode::G_FMAXIMUMNUM:
2518 return Known.isKnownNeverLogicalZero(
2523unsigned GISelValueTracking::computeNumSignBitsMin(
Register Src0,
Register Src1,
2524 const APInt &DemandedElts,
2528 if (Src1SignBits == 1)
2538 const MDNode *Ranges = Ld->getRanges();
2544 switch (Ld->getOpcode()) {
2545 case TargetOpcode::G_SEXTLOAD:
2548 case TargetOpcode::G_ZEXTLOAD:
2561 const APInt &DemandedElts,
2564 unsigned Opcode =
MI.getOpcode();
2566 if (Opcode == TargetOpcode::G_CONSTANT)
2567 return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
2575 LLT DstTy = MRI.getType(R);
2585 unsigned FirstAnswer = 1;
2587 case TargetOpcode::COPY: {
2589 if (Src.getReg().isVirtual() && Src.getSubReg() == 0 &&
2590 MRI.getType(Src.getReg()).isValid()) {
2597 case TargetOpcode::G_FREEZE: {
2603 case TargetOpcode::G_SEXT: {
2605 LLT SrcTy = MRI.getType(Src);
2606 unsigned Tmp = TyBits - SrcTy.getScalarSizeInBits();
2609 case TargetOpcode::G_ASSERT_SEXT:
2610 case TargetOpcode::G_SEXT_INREG: {
2613 unsigned SrcBits =
MI.getOperand(2).getImm();
2614 unsigned InRegBits = TyBits - SrcBits + 1;
2618 case TargetOpcode::G_LOAD: {
2625 case TargetOpcode::G_SEXTLOAD: {
2640 case TargetOpcode::G_ZEXTLOAD: {
2655 case TargetOpcode::G_AND:
2656 case TargetOpcode::G_OR:
2657 case TargetOpcode::G_XOR: {
2659 unsigned Src1NumSignBits =
2661 if (Src1NumSignBits != 1) {
2663 unsigned Src2NumSignBits =
2665 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits);
2669 case TargetOpcode::G_ASHR: {
2674 FirstAnswer = std::min<uint64_t>(FirstAnswer + *
C, TyBits);
2677 case TargetOpcode::G_SHL: {
2680 if (std::optional<ConstantRange> ShAmtRange =
2682 uint64_t MaxShAmt = ShAmtRange->getUnsignedMax().getZExtValue();
2683 uint64_t MinShAmt = ShAmtRange->getUnsignedMin().getZExtValue();
2693 if (ExtOpc == TargetOpcode::G_SEXT || ExtOpc == TargetOpcode::G_ZEXT ||
2694 ExtOpc == TargetOpcode::G_ANYEXT) {
2695 LLT ExtTy = MRI.getType(Src1);
2697 LLT ExtendeeTy = MRI.getType(Extendee);
2701 if (SizeDiff <= MinShAmt) {
2705 return Tmp - MaxShAmt;
2711 return Tmp - MaxShAmt;
2715 case TargetOpcode::G_ROTL:
2716 case TargetOpcode::G_ROTR: {
2725 case TargetOpcode::G_SAVGFLOOR:
2726 case TargetOpcode::G_SAVGCEIL: {
2729 FirstAnswer = computeNumSignBitsMin(Src1, Src2, DemandedElts,
Depth + 1);
2732 case TargetOpcode::G_SREM: {
2740 case TargetOpcode::G_TRUNC: {
2742 LLT SrcTy = MRI.getType(Src);
2747 if (NumSrcSignBits > (NumSrcBits - TyBits))
2748 return NumSrcSignBits - (NumSrcBits - TyBits);
2751 case TargetOpcode::G_SELECT: {
2752 return computeNumSignBitsMin(
MI.getOperand(2).getReg(),
2753 MI.getOperand(3).getReg(), DemandedElts,
2756 case TargetOpcode::G_SMIN:
2757 case TargetOpcode::G_SMAX:
2758 case TargetOpcode::G_UMIN:
2759 case TargetOpcode::G_UMAX:
2761 return computeNumSignBitsMin(
MI.getOperand(1).getReg(),
2762 MI.getOperand(2).getReg(), DemandedElts,
2764 case TargetOpcode::G_SADDO:
2765 case TargetOpcode::G_SADDE:
2766 case TargetOpcode::G_UADDO:
2767 case TargetOpcode::G_UADDE:
2768 case TargetOpcode::G_SSUBO:
2769 case TargetOpcode::G_SSUBE:
2770 case TargetOpcode::G_USUBO:
2771 case TargetOpcode::G_USUBE:
2772 case TargetOpcode::G_SMULO:
2773 case TargetOpcode::G_UMULO: {
2777 if (
MI.getOperand(1).getReg() == R) {
2778 if (TL.getBooleanContents(DstTy.
isVector(),
false) ==
2785 case TargetOpcode::G_SUB: {
2787 unsigned Src2NumSignBits =
2789 if (Src2NumSignBits == 1)
2799 if ((Known2.
Zero | 1).isAllOnes())
2806 FirstAnswer = Src2NumSignBits;
2813 unsigned Src1NumSignBits =
2815 if (Src1NumSignBits == 1)
2820 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2823 case TargetOpcode::G_ADD: {
2825 unsigned Src2NumSignBits =
2827 if (Src2NumSignBits <= 2)
2831 unsigned Src1NumSignBits =
2833 if (Src1NumSignBits == 1)
2842 if ((Known1.
Zero | 1).isAllOnes())
2848 FirstAnswer = Src1NumSignBits;
2857 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2860 case TargetOpcode::G_MUL: {
2861 unsigned Src2NumSignBits =
2863 if (Src2NumSignBits == 1)
2865 unsigned Src1NumSignBits =
2867 if (Src1NumSignBits == 1)
2871 unsigned OutValidBits =
2872 (TyBits - Src1NumSignBits + 1) + (TyBits - Src2NumSignBits + 1);
2873 if (OutValidBits <= TyBits)
2874 FirstAnswer = TyBits - OutValidBits + 1;
2877 case TargetOpcode::G_FCMP:
2878 case TargetOpcode::G_ICMP: {
2879 bool IsFP = Opcode == TargetOpcode::G_FCMP;
2882 auto BC = TL.getBooleanContents(DstTy.
isVector(), IsFP);
2889 case TargetOpcode::G_UNMERGE_VALUES: {
2890 unsigned NumOps =
MI.getNumOperands();
2892 LLT SrcTy = MRI.getType(SrcReg);
2894 if ((SrcTy.isVector() && SrcTy.getScalarType() != DstTy.
getScalarType()) ||
2895 (SrcTy.isScalar() && DstTy.
isVector()))
2899 unsigned DstIdx =
MI.findRegisterDefOperandIdx(R,
nullptr);
2901 APInt SubDemandedElts = DemandedElts;
2903 if (SrcTy.isVector()) {
2905 DemandedElts.
zext(SrcTy.getNumElements()).
shl(DstIdx * DstLanes);
2908 unsigned SrcOpKnown =
2910 if (SrcTy.isVector()) {
2911 FirstAnswer = SrcOpKnown;
2912 }
else if (SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 2) * TyBits) {
2913 FirstAnswer = SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 1) * TyBits
2915 : SrcOpKnown % TyBits;
2919 case TargetOpcode::G_BUILD_VECTOR: {
2921 FirstAnswer = TyBits;
2922 APInt SingleDemandedElt(1, 1);
2924 if (!DemandedElts[
I])
2929 FirstAnswer = std::min(FirstAnswer, Tmp2);
2932 if (FirstAnswer == 1)
2937 case TargetOpcode::G_CONCAT_VECTORS: {
2938 if (MRI.getType(
MI.getOperand(0).getReg()).isScalableVector())
2940 FirstAnswer = TyBits;
2943 unsigned NumSubVectorElts =
2944 MRI.getType(
MI.getOperand(1).getReg()).getNumElements();
2947 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
2952 FirstAnswer = std::min(FirstAnswer, Tmp2);
2955 if (FirstAnswer == 1)
2960 case TargetOpcode::G_VECTOR_COMPRESS: {
2964 Register PassThru =
MI.getOperand(3).getReg();
2973 FirstAnswer = std::min(Tmp, Tmp2);
2976 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2978 Register InVec = Insert.getVectorReg();
2979 Register InVal = Insert.getElementReg();
2980 LLT VecVT = MRI.getType(InVec);
2986 bool DemandedVal =
true;
2987 APInt DemandedVecElts = DemandedElts;
2991 if (ConstEltNo && ConstEltNo->ult(NumElts)) {
2992 unsigned EltIdx = ConstEltNo->getZExtValue();
2993 DemandedVal = !!DemandedElts[EltIdx];
2998 unsigned Tmp = TyBits;
3001 if (MRI.getType(InVal).getSizeInBits() != TyBits)
3004 Tmp = std::min(Tmp, ValSignBits);
3006 if (!!DemandedVecElts) {
3007 unsigned VecSignBits =
3009 Tmp = std::min(Tmp, VecSignBits);
3013 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
3017 LLT VecVT = MRI.getType(InVec);
3022 APInt DemandedSrcElts =
3023 ConstEltNo && ConstEltNo->ult(NumSrcElts)
3028 case TargetOpcode::G_EXTRACT_SUBVECTOR: {
3031 LLT SrcTy = MRI.getType(SrcReg);
3032 APInt DemandedSrcElts;
3033 if (SrcTy.isScalableVector()) {
3034 DemandedSrcElts =
APInt(1, 1);
3036 uint64_t Idx =
MI.getOperand(2).getImm();
3037 unsigned NumSrcElts = SrcTy.getNumElements();
3038 DemandedSrcElts = DemandedElts.
zext(NumSrcElts).
shl(Idx);
3042 case TargetOpcode::G_SHUFFLE_VECTOR: {
3045 APInt DemandedLHS, DemandedRHS;
3047 unsigned NumElts = MRI.getType(Src1).getNumElements();
3049 DemandedElts, DemandedLHS, DemandedRHS))
3055 if (FirstAnswer == 1)
3057 if (!!DemandedRHS) {
3060 FirstAnswer = std::min(FirstAnswer, Tmp2);
3064 case TargetOpcode::G_SPLAT_VECTOR: {
3068 unsigned NumSrcBits = MRI.getType(Src).getSizeInBits();
3069 if (NumSrcSignBits > (NumSrcBits - TyBits))
3070 return NumSrcSignBits - (NumSrcBits - TyBits);
3073 case TargetOpcode::G_INTRINSIC:
3074 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
3075 case TargetOpcode::G_INTRINSIC_CONVERGENT:
3076 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
3079 TL.computeNumSignBitsForTargetInstr(*
this, R, DemandedElts, MRI,
Depth);
3081 FirstAnswer = std::max(FirstAnswer, NumBits);
3089 return std::max(FirstAnswer,
Known.countMinSignBits());
3093 LLT Ty = MRI.getType(R);
3094 APInt DemandedElts =
3103 unsigned Opcode =
MI.getOpcode();
3105 LLT Ty = MRI.getType(R);
3106 unsigned BitWidth = Ty.getScalarSizeInBits();
3108 if (Opcode == TargetOpcode::G_CONSTANT) {
3109 const APInt &ShAmt =
MI.getOperand(1).getCImm()->getValue();
3111 return std::nullopt;
3115 if (Opcode == TargetOpcode::G_BUILD_VECTOR) {
3116 const APInt *MinAmt =
nullptr, *MaxAmt =
nullptr;
3117 for (
unsigned I = 0, E =
MI.getNumOperands() - 1;
I != E; ++
I) {
3118 if (!DemandedElts[
I])
3121 if (
Op->getOpcode() != TargetOpcode::G_CONSTANT) {
3122 MinAmt = MaxAmt =
nullptr;
3126 const APInt &ShAmt =
Op->getOperand(1).getCImm()->getValue();
3128 return std::nullopt;
3129 if (!MinAmt || MinAmt->
ugt(ShAmt))
3131 if (!MaxAmt || MaxAmt->ult(ShAmt))
3134 assert(((!MinAmt && !MaxAmt) || (MinAmt && MaxAmt)) &&
3135 "Failed to find matching min/max shift amounts");
3136 if (MinAmt && MaxAmt)
3146 return std::nullopt;
3151 if (std::optional<ConstantRange> AmtRange =
3153 return AmtRange->getUnsignedMin().getZExtValue();
3154 return std::nullopt;
3172 Info = std::make_unique<GISelValueTracking>(MF, MaxDepth);
3184 return Result(MF, MaxDepth);
3190 bool PrintFPClass) {
3200 if (!MO.isReg() || MO.getReg().isPhysical())
3203 if (!MRI.getType(
Reg).isValid())
3208 <<
" SignBitKnown:";
3216 unsigned SignedBits = VTA.computeNumSignBits(
Reg);
3217 bool IsKnownNeverZero = VTA.isKnownNeverZero(
Reg);
3218 OS <<
" " << MO <<
" KnownBits:" <<
Known
3219 <<
" SignBits:" << SignedBits
3220 <<
" 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 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 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 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 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 roundToIntegral(const KnownFPClass &Src, bool IsTrunc, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for rounding intrinsics (trunc, floor, ceil, rint, nearbyint,...
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.