41#define DEBUG_TYPE "gisel-known-bits"
44using namespace MIPatternMatch;
49 "Analysis for ComputingKnownBits",
false,
true)
52 : MF(MF),
MRI(MF.getRegInfo()), TL(*MF.getSubtarget().getTargetLowering()),
57 switch (
MI->getOpcode()) {
58 case TargetOpcode::COPY:
60 case TargetOpcode::G_ASSERT_ALIGN: {
62 return Align(
MI->getOperand(2).getImm());
64 case TargetOpcode::G_FRAME_INDEX: {
65 int FrameIdx =
MI->getOperand(1).getIndex();
68 case TargetOpcode::G_INTRINSIC:
69 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
70 case TargetOpcode::G_INTRINSIC_CONVERGENT:
71 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
78 assert(
MI.getNumExplicitDefs() == 1 &&
79 "expected single return generic instruction");
94 const APInt &DemandedElts,
97 assert(ComputeKnownBitsCache.empty() &&
"Cache should have been cleared");
101 ComputeKnownBitsCache.clear();
122 <<
"] Computed for: " <<
MI <<
"[" <<
Depth <<
"] Known: 0x"
133 const APInt &DemandedElts,
164 const APInt &DemandedElts,
167 unsigned Opcode =
MI.getOpcode();
182 "DemandedElt width should equal the fixed vector number of elements");
185 "DemandedElt width should be 1 for scalars or scalable vectors");
190 auto CacheEntry = ComputeKnownBitsCache.find(R);
191 if (CacheEntry != ComputeKnownBitsCache.end()) {
192 Known = CacheEntry->second;
221 case TargetOpcode::G_BUILD_VECTOR: {
226 if (!DemandedElts[
I])
240 case TargetOpcode::G_SPLAT_VECTOR: {
248 case TargetOpcode::COPY:
249 case TargetOpcode::G_PHI:
250 case TargetOpcode::PHI: {
256 assert(
MI.getOperand(0).getSubReg() == 0 &&
"Is this code in SSA?");
269 for (
unsigned Idx = 1;
Idx <
MI.getNumOperands();
Idx += 2) {
279 if (SrcReg.
isVirtual() && Src.getSubReg() == 0 &&
283 Depth + (Opcode != TargetOpcode::COPY));
298 case TargetOpcode::G_CONSTANT: {
302 case TargetOpcode::G_FRAME_INDEX: {
303 int FrameIdx =
MI.getOperand(1).getIndex();
307 case TargetOpcode::G_SUB: {
315 case TargetOpcode::G_XOR: {
324 case TargetOpcode::G_PTR_ADD: {
333 case TargetOpcode::G_ADD: {
341 case TargetOpcode::G_AND: {
351 case TargetOpcode::G_OR: {
361 case TargetOpcode::G_MUL: {
369 case TargetOpcode::G_SELECT: {
370 computeKnownBitsMin(
MI.getOperand(2).getReg(),
MI.getOperand(3).getReg(),
371 Known, DemandedElts,
Depth + 1);
374 case TargetOpcode::G_SMIN: {
384 case TargetOpcode::G_SMAX: {
394 case TargetOpcode::G_UMIN: {
403 case TargetOpcode::G_UMAX: {
412 case TargetOpcode::G_FCMP:
413 case TargetOpcode::G_ICMP: {
417 Opcode == TargetOpcode::G_FCMP) ==
423 case TargetOpcode::G_SEXT: {
431 case TargetOpcode::G_ASSERT_SEXT:
432 case TargetOpcode::G_SEXT_INREG: {
435 Known = Known.
sextInReg(
MI.getOperand(2).getImm());
438 case TargetOpcode::G_ANYEXT: {
444 case TargetOpcode::G_LOAD: {
452 case TargetOpcode::G_SEXTLOAD:
453 case TargetOpcode::G_ZEXTLOAD: {
460 Known = Opcode == TargetOpcode::G_SEXTLOAD
465 case TargetOpcode::G_ASHR: {
474 case TargetOpcode::G_LSHR: {
483 case TargetOpcode::G_SHL: {
492 case TargetOpcode::G_INTTOPTR:
493 case TargetOpcode::G_PTRTOINT:
498 case TargetOpcode::G_ZEXT:
499 case TargetOpcode::G_TRUNC: {
505 case TargetOpcode::G_ASSERT_ZEXT: {
509 unsigned SrcBitWidth =
MI.getOperand(2).getImm();
510 assert(SrcBitWidth &&
"SrcBitWidth can't be zero");
512 Known.
Zero |= (~InMask);
513 Known.
One &= (~Known.Zero);
516 case TargetOpcode::G_ASSERT_ALIGN: {
517 int64_t LogOfAlign =
Log2_64(
MI.getOperand(2).getImm());
526 case TargetOpcode::G_MERGE_VALUES: {
527 unsigned NumOps =
MI.getNumOperands();
530 for (
unsigned I = 0;
I != NumOps - 1; ++
I) {
533 DemandedElts,
Depth + 1);
538 case TargetOpcode::G_UNMERGE_VALUES: {
539 unsigned NumOps =
MI.getNumOperands();
540 Register SrcReg =
MI.getOperand(NumOps - 1).getReg();
548 for (; DstIdx != NumOps - 1 &&
MI.getOperand(DstIdx).
getReg() != R;
552 APInt SubDemandedElts = DemandedElts;
563 Known = std::move(SrcOpKnown);
568 case TargetOpcode::G_BSWAP: {
574 case TargetOpcode::G_BITREVERSE: {
580 case TargetOpcode::G_CTPOP: {
592 case TargetOpcode::G_UBFX: {
593 KnownBits SrcOpKnown, OffsetKnown, WidthKnown;
603 case TargetOpcode::G_SBFX: {
604 KnownBits SrcOpKnown, OffsetKnown, WidthKnown;
619 case TargetOpcode::G_UADDO:
620 case TargetOpcode::G_UADDE:
621 case TargetOpcode::G_SADDO:
622 case TargetOpcode::G_SADDE:
623 case TargetOpcode::G_USUBO:
624 case TargetOpcode::G_USUBE:
625 case TargetOpcode::G_SSUBO:
626 case TargetOpcode::G_SSUBE:
627 case TargetOpcode::G_UMULO:
628 case TargetOpcode::G_SMULO: {
629 if (
MI.getOperand(1).getReg() == R) {
639 case TargetOpcode::G_CTLZ:
640 case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
650 case TargetOpcode::G_SHUFFLE_VECTOR: {
651 APInt DemandedLHS, DemandedRHS;
656 DemandedElts, DemandedLHS, DemandedRHS))
677 case TargetOpcode::G_CONCAT_VECTORS: {
683 unsigned NumSubVectorElts =
688 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
705 ComputeKnownBitsCache[R] = Known;
721 computeKnownFPClass(R, DemandedElts, InterestedClasses, Known,
Depth);
724void GISelValueTracking::computeKnownFPClassForFPTrunc(
733 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
746void GISelValueTracking::computeKnownFPClass(
Register R,
747 const APInt &DemandedElts,
751 assert(Known.
isUnknown() &&
"should not be called with known information");
762 unsigned Opcode =
MI.getOpcode();
771 switch (Cst->getKind()) {
773 auto APF = Cst->getScalarValue();
775 Known.
SignBit = APF.isNegative();
780 bool SignBitAllZero =
true;
781 bool SignBitAllOne =
true;
783 for (
auto C : *Cst) {
786 SignBitAllZero =
false;
788 SignBitAllOne =
false;
791 if (SignBitAllOne != SignBitAllZero)
807 KnownNotFromFlags |=
fcNan;
809 KnownNotFromFlags |=
fcInf;
813 InterestedClasses &= ~KnownNotFromFlags;
815 auto ClearClassesFromFlags =
829 case TargetOpcode::G_FNEG: {
831 computeKnownFPClass(Val, DemandedElts, InterestedClasses, Known,
Depth + 1);
835 case TargetOpcode::G_SELECT: {
858 bool LookThroughFAbsFNeg = CmpLHS !=
LHS && CmpLHS !=
RHS;
859 std::tie(TestedValue, MaskIfTrue, MaskIfFalse) =
865 MaskIfTrue = TestedMask;
866 MaskIfFalse = ~TestedMask;
869 if (TestedValue == LHS) {
871 FilterLHS = MaskIfTrue;
872 }
else if (TestedValue == RHS) {
874 FilterRHS = MaskIfFalse;
878 computeKnownFPClass(LHS, DemandedElts, InterestedClasses & FilterLHS, Known,
882 computeKnownFPClass(RHS, DemandedElts, InterestedClasses & FilterRHS,
889 case TargetOpcode::G_FCOPYSIGN: {
890 Register Magnitude =
MI.getOperand(1).getReg();
895 computeKnownFPClass(Magnitude, DemandedElts, InterestedClasses, Known,
897 computeKnownFPClass(Sign, DemandedElts, InterestedClasses, KnownSign,
902 case TargetOpcode::G_FMA:
903 case TargetOpcode::G_STRICT_FMA:
904 case TargetOpcode::G_FMAD: {
920 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownAddend,
927 case TargetOpcode::G_FSQRT:
928 case TargetOpcode::G_STRICT_FSQRT: {
931 if (InterestedClasses &
fcNan)
936 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
951 case TargetOpcode::G_FABS: {
956 computeKnownFPClass(Val, DemandedElts, InterestedClasses, Known,
962 case TargetOpcode::G_FSIN:
963 case TargetOpcode::G_FCOS:
964 case TargetOpcode::G_FSINCOS: {
969 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
977 case TargetOpcode::G_FMAXNUM:
978 case TargetOpcode::G_FMINNUM:
979 case TargetOpcode::G_FMINNUM_IEEE:
980 case TargetOpcode::G_FMAXIMUM:
981 case TargetOpcode::G_FMINIMUM:
982 case TargetOpcode::G_FMAXNUM_IEEE:
983 case TargetOpcode::G_FMAXIMUMNUM:
984 case TargetOpcode::G_FMINIMUMNUM: {
989 computeKnownFPClass(LHS, DemandedElts, InterestedClasses, KnownLHS,
991 computeKnownFPClass(RHS, DemandedElts, InterestedClasses, KnownRHS,
995 Known = KnownLHS | KnownRHS;
998 if (NeverNaN && (Opcode == TargetOpcode::G_FMINNUM ||
999 Opcode == TargetOpcode::G_FMAXNUM ||
1000 Opcode == TargetOpcode::G_FMINIMUMNUM ||
1001 Opcode == TargetOpcode::G_FMAXIMUMNUM))
1004 if (Opcode == TargetOpcode::G_FMAXNUM ||
1005 Opcode == TargetOpcode::G_FMAXIMUMNUM ||
1006 Opcode == TargetOpcode::G_FMAXNUM_IEEE) {
1014 }
else if (Opcode == TargetOpcode::G_FMAXIMUM) {
1020 }
else if (Opcode == TargetOpcode::G_FMINNUM ||
1021 Opcode == TargetOpcode::G_FMINIMUMNUM ||
1022 Opcode == TargetOpcode::G_FMINNUM_IEEE) {
1030 }
else if (Opcode == TargetOpcode::G_FMINIMUM) {
1062 }
else if ((Opcode == TargetOpcode::G_FMAXIMUM ||
1063 Opcode == TargetOpcode::G_FMINIMUM) ||
1064 Opcode == TargetOpcode::G_FMAXIMUMNUM ||
1065 Opcode == TargetOpcode::G_FMINIMUMNUM ||
1066 Opcode == TargetOpcode::G_FMAXNUM_IEEE ||
1067 Opcode == TargetOpcode::G_FMINNUM_IEEE ||
1073 if ((Opcode == TargetOpcode::G_FMAXIMUM ||
1074 Opcode == TargetOpcode::G_FMAXNUM ||
1075 Opcode == TargetOpcode::G_FMAXIMUMNUM ||
1076 Opcode == TargetOpcode::G_FMAXNUM_IEEE) &&
1079 else if ((Opcode == TargetOpcode::G_FMINIMUM ||
1080 Opcode == TargetOpcode::G_FMINNUM ||
1081 Opcode == TargetOpcode::G_FMINIMUMNUM ||
1082 Opcode == TargetOpcode::G_FMINNUM_IEEE) &&
1089 case TargetOpcode::G_FCANONICALIZE: {
1092 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1133 case TargetOpcode::G_VECREDUCE_FMAX:
1134 case TargetOpcode::G_VECREDUCE_FMIN:
1135 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
1136 case TargetOpcode::G_VECREDUCE_FMINIMUM: {
1142 computeKnownFPClass(Val,
MI.getFlags(), InterestedClasses,
Depth + 1);
1148 case TargetOpcode::G_TRUNC:
1149 case TargetOpcode::G_FFLOOR:
1150 case TargetOpcode::G_FCEIL:
1151 case TargetOpcode::G_FRINT:
1152 case TargetOpcode::G_FNEARBYINT:
1153 case TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND:
1154 case TargetOpcode::G_INTRINSIC_ROUND: {
1162 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1179 case TargetOpcode::G_FEXP:
1180 case TargetOpcode::G_FEXP2:
1181 case TargetOpcode::G_FEXP10: {
1188 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1197 case TargetOpcode::G_FLOG:
1198 case TargetOpcode::G_FLOG2:
1199 case TargetOpcode::G_FLOG10: {
1215 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1232 case TargetOpcode::G_FPOWI: {
1241 if (ExponentKnownBits.
Zero[0]) {
1256 computeKnownFPClass(Val, DemandedElts,
fcNegative, KnownSrc,
Depth + 1);
1261 case TargetOpcode::G_FLDEXP:
1262 case TargetOpcode::G_STRICT_FLDEXP: {
1265 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1282 if ((InterestedClasses & ExpInfoMask) ==
fcNone)
1291 case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
1292 computeKnownFPClassForFPTrunc(
MI, DemandedElts, InterestedClasses, Known,
1296 case TargetOpcode::G_FADD:
1297 case TargetOpcode::G_STRICT_FADD:
1298 case TargetOpcode::G_FSUB:
1299 case TargetOpcode::G_STRICT_FSUB: {
1304 (Opcode == TargetOpcode::G_FADD ||
1305 Opcode == TargetOpcode::G_STRICT_FADD) &&
1307 bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1310 if (!WantNaN && !WantNegative && !WantNegZero)
1316 if (InterestedClasses &
fcNan)
1317 InterestedSrcs |=
fcInf;
1318 computeKnownFPClass(RHS, DemandedElts, InterestedSrcs, KnownRHS,
Depth + 1);
1323 (Opcode == TargetOpcode::G_FSUB ||
1324 Opcode == TargetOpcode::G_STRICT_FSUB)) {
1328 computeKnownFPClass(LHS, DemandedElts, InterestedSrcs, KnownLHS,
1336 if (Opcode == Instruction::FAdd) {
1363 case TargetOpcode::G_FMUL:
1364 case TargetOpcode::G_STRICT_FMUL: {
1378 computeKnownFPClass(RHS, DemandedElts, NeedForNan, KnownRHS,
Depth + 1);
1382 computeKnownFPClass(LHS, DemandedElts, NeedForNan, KnownLHS,
Depth + 1);
1409 case TargetOpcode::G_FDIV:
1410 case TargetOpcode::G_FREM: {
1416 if (Opcode == TargetOpcode::G_FDIV) {
1427 const bool WantNan = (InterestedClasses &
fcNan) !=
fcNone;
1429 const bool WantPositive = Opcode == TargetOpcode::G_FREM &&
1431 if (!WantNan && !WantNegative && !WantPositive)
1437 KnownRHS,
Depth + 1);
1439 bool KnowSomethingUseful =
1442 if (KnowSomethingUseful || WantPositive) {
1447 computeKnownFPClass(LHS, DemandedElts, InterestedClasses & InterestedLHS,
1448 KnownLHS,
Depth + 1);
1451 if (Opcode == Instruction::FDiv) {
1492 case TargetOpcode::G_FPEXT: {
1496 computeKnownFPClass(R, DemandedElts, InterestedClasses, Known,
Depth + 1);
1517 case TargetOpcode::G_FPTRUNC: {
1518 computeKnownFPClassForFPTrunc(
MI, DemandedElts, InterestedClasses, Known,
1522 case TargetOpcode::G_SITOFP:
1523 case TargetOpcode::G_UITOFP: {
1532 if (Opcode == TargetOpcode::G_UITOFP)
1538 if (InterestedClasses &
fcInf) {
1543 if (Opcode == TargetOpcode::G_SITOFP)
1557 case TargetOpcode::G_BUILD_VECTOR:
1558 case TargetOpcode::G_CONCAT_VECTORS: {
1567 bool NeedsElt = DemandedElts[
Idx];
1573 computeKnownFPClass(Src, Known, InterestedClasses,
Depth + 1);
1577 computeKnownFPClass(Src, Known2, InterestedClasses,
Depth + 1);
1589 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1604 if (CIdx && CIdx->ult(NumElts))
1606 return computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses, Known,
1612 case TargetOpcode::G_INSERT_VECTOR_ELT: {
1626 APInt DemandedVecElts = DemandedElts;
1627 bool NeedsElt =
true;
1629 if (CIdx && CIdx->ult(NumElts)) {
1630 DemandedVecElts.
clearBit(CIdx->getZExtValue());
1631 NeedsElt = DemandedElts[CIdx->getZExtValue()];
1636 computeKnownFPClass(Elt, Known, InterestedClasses,
Depth + 1);
1645 if (!DemandedVecElts.
isZero()) {
1647 computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses, Known2,
1654 case TargetOpcode::G_SHUFFLE_VECTOR: {
1658 APInt DemandedLHS, DemandedRHS;
1661 DemandedLHS = DemandedRHS = DemandedElts;
1664 DemandedElts, DemandedLHS,
1671 if (!!DemandedLHS) {
1673 computeKnownFPClass(LHS, DemandedLHS, InterestedClasses, Known,
1683 if (!!DemandedRHS) {
1686 computeKnownFPClass(RHS, DemandedRHS, InterestedClasses, Known2,
1692 case TargetOpcode::COPY: {
1695 if (!Src.isVirtual())
1698 computeKnownFPClass(Src, DemandedElts, InterestedClasses, Known,
Depth + 1);
1709 computeKnownFPClass(R, DemandedElts, InterestedClasses, KnownClasses,
Depth);
1710 return KnownClasses;
1716 computeKnownFPClass(R, Known, InterestedClasses,
Depth);
1724 InterestedClasses &= ~fcNan;
1726 InterestedClasses &= ~fcInf;
1729 computeKnownFPClass(R, DemandedElts, InterestedClasses,
Depth);
1732 Result.KnownFPClasses &= ~fcNan;
1734 Result.KnownFPClasses &= ~fcInf;
1741 APInt DemandedElts =
1743 return computeKnownFPClass(R, DemandedElts, Flags, InterestedClasses,
Depth);
1747unsigned GISelValueTracking::computeNumSignBitsMin(
Register Src0,
Register Src1,
1748 const APInt &DemandedElts,
1752 if (Src1SignBits == 1)
1769 case TargetOpcode::G_SEXTLOAD:
1772 case TargetOpcode::G_ZEXTLOAD:
1785 const APInt &DemandedElts,
1788 unsigned Opcode =
MI.getOpcode();
1790 if (Opcode == TargetOpcode::G_CONSTANT)
1791 return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
1809 unsigned FirstAnswer = 1;
1811 case TargetOpcode::COPY: {
1813 if (Src.getReg().isVirtual() && Src.getSubReg() == 0 &&
1821 case TargetOpcode::G_SEXT: {
1827 case TargetOpcode::G_ASSERT_SEXT:
1828 case TargetOpcode::G_SEXT_INREG: {
1831 unsigned SrcBits =
MI.getOperand(2).getImm();
1832 unsigned InRegBits = TyBits - SrcBits + 1;
1836 case TargetOpcode::G_LOAD: {
1843 case TargetOpcode::G_SEXTLOAD: {
1858 case TargetOpcode::G_ZEXTLOAD: {
1873 case TargetOpcode::G_AND:
1874 case TargetOpcode::G_OR:
1875 case TargetOpcode::G_XOR: {
1877 unsigned Src1NumSignBits =
1879 if (Src1NumSignBits != 1) {
1881 unsigned Src2NumSignBits =
1883 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits);
1887 case TargetOpcode::G_ASHR: {
1892 FirstAnswer = std::min<uint64_t>(FirstAnswer + *
C, TyBits);
1895 case TargetOpcode::G_TRUNC: {
1903 if (NumSrcSignBits > (NumSrcBits - DstTyBits))
1904 return NumSrcSignBits - (NumSrcBits - DstTyBits);
1907 case TargetOpcode::G_SELECT: {
1908 return computeNumSignBitsMin(
MI.getOperand(2).getReg(),
1909 MI.getOperand(3).getReg(), DemandedElts,
1912 case TargetOpcode::G_SMIN:
1913 case TargetOpcode::G_SMAX:
1914 case TargetOpcode::G_UMIN:
1915 case TargetOpcode::G_UMAX:
1917 return computeNumSignBitsMin(
MI.getOperand(1).getReg(),
1918 MI.getOperand(2).getReg(), DemandedElts,
1920 case TargetOpcode::G_SADDO:
1921 case TargetOpcode::G_SADDE:
1922 case TargetOpcode::G_UADDO:
1923 case TargetOpcode::G_UADDE:
1924 case TargetOpcode::G_SSUBO:
1925 case TargetOpcode::G_SSUBE:
1926 case TargetOpcode::G_USUBO:
1927 case TargetOpcode::G_USUBE:
1928 case TargetOpcode::G_SMULO:
1929 case TargetOpcode::G_UMULO: {
1933 if (
MI.getOperand(1).getReg() == R) {
1941 case TargetOpcode::G_FCMP:
1942 case TargetOpcode::G_ICMP: {
1943 bool IsFP = Opcode == TargetOpcode::G_FCMP;
1953 case TargetOpcode::G_BUILD_VECTOR: {
1955 FirstAnswer = TyBits;
1956 APInt SingleDemandedElt(1, 1);
1958 if (!DemandedElts[
I])
1963 FirstAnswer = std::min(FirstAnswer, Tmp2);
1966 if (FirstAnswer == 1)
1971 case TargetOpcode::G_CONCAT_VECTORS: {
1974 FirstAnswer = TyBits;
1977 unsigned NumSubVectorElts =
1981 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
1986 FirstAnswer = std::min(FirstAnswer, Tmp2);
1989 if (FirstAnswer == 1)
1994 case TargetOpcode::G_SHUFFLE_VECTOR: {
1997 APInt DemandedLHS, DemandedRHS;
2001 DemandedElts, DemandedLHS, DemandedRHS))
2007 if (FirstAnswer == 1)
2009 if (!!DemandedRHS) {
2012 FirstAnswer = std::min(FirstAnswer, Tmp2);
2016 case TargetOpcode::G_SPLAT_VECTOR: {
2021 if (NumSrcSignBits > (NumSrcBits - TyBits))
2022 return NumSrcSignBits - (NumSrcBits - TyBits);
2025 case TargetOpcode::G_INTRINSIC:
2026 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
2027 case TargetOpcode::G_INTRINSIC_CONVERGENT:
2028 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
2033 FirstAnswer = std::max(FirstAnswer, NumBits);
2053 Mask <<= Mask.getBitWidth() - TyBits;
2054 return std::max(FirstAnswer, Mask.countl_one());
2059 APInt DemandedElts =
2068 unsigned Opcode =
MI.getOpcode();
2073 if (Opcode == TargetOpcode::G_CONSTANT) {
2074 const APInt &ShAmt =
MI.getOperand(1).getCImm()->getValue();
2076 return std::nullopt;
2080 if (Opcode == TargetOpcode::G_BUILD_VECTOR) {
2081 const APInt *MinAmt =
nullptr, *MaxAmt =
nullptr;
2082 for (
unsigned I = 0, E =
MI.getNumOperands() - 1;
I != E; ++
I) {
2083 if (!DemandedElts[
I])
2086 if (
Op->getOpcode() != TargetOpcode::G_CONSTANT) {
2087 MinAmt = MaxAmt =
nullptr;
2091 const APInt &ShAmt =
Op->getOperand(1).getCImm()->getValue();
2093 return std::nullopt;
2094 if (!MinAmt || MinAmt->
ugt(ShAmt))
2096 if (!MaxAmt || MaxAmt->ult(ShAmt))
2099 assert(((!MinAmt && !MaxAmt) || (MinAmt && MaxAmt)) &&
2100 "Failed to find matching min/max shift amounts");
2101 if (MinAmt && MaxAmt)
2111 return std::nullopt;
2116 if (std::optional<ConstantRange> AmtRange =
2118 return AmtRange->getUnsignedMin().getZExtValue();
2119 return std::nullopt;
2137 Info = std::make_unique<GISelValueTracking>(MF, MaxDepth);
2162 if (!MO.isReg() || MO.getReg().isPhysical())
2165 if (!
MRI.getType(Reg).isValid())
2167 KnownBits Known = VTA.getKnownBits(Reg);
2168 unsigned SignedBits = VTA.computeNumSignBits(Reg);
2169 OS <<
" " << MO <<
" KnownBits:" << Known <<
" SignBits:" << SignedBits
unsigned const MachineRegisterInfo * MRI
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ATTRIBUTE_UNUSED
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Utilities for dealing with flags related to floating point properties and mode controls.
#define DEBUG_TYPE
Provides analysis for querying information about KnownBits during GISel passes.
static unsigned computeNumSignBitsFromRangeMetadata(const GAnyLoad *Ld, unsigned TyBits)
Compute the known number of sign bits with attached range metadata in the memory operand.
static LLVM_ATTRIBUTE_UNUSED void dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth)
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Implement a low-level type suitable for MachineInstr level instruction selection.
Contains matchers for matching SSA Machine Instructions.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file describes how to lower LLVM code to machine code.
static bool outputDenormalIsIEEEOrPosZero(const Function &F, const Type *Ty)
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
Class for arbitrary precision integers.
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.
void setBitsFrom(unsigned loBit)
Set the top bits starting from loBit.
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.
void clearLowBits(unsigned loBits)
Set bottom loBits bits to 0.
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.
void setAllBits()
Set every bit to 1.
APInt shl(unsigned shiftAmt) const
Left-shift function.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
void setLowBits(unsigned loBits)
Set the bottom loBits bits.
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.
A container for analyses that lazily runs them and caches their results.
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 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 APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
This class represents an Operation in the Expression.
bool isNonIntegralAddressSpace(unsigned AddrSpace) const
Represents any generic load, including sign/zero extending variants.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
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)
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)
APInt getKnownOnes(Register R)
APInt getKnownZeroes(Register R)
virtual void computeKnownBitsImpl(Register R, KnownBits &Known, const APInt &DemandedElts, unsigned Depth=0)
Represents an insert vector element.
Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
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
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr unsigned getAddressSpace() const
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
constexpr LLT getScalarType() const
TypeSize getValue() const
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
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.
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.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
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.
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual Align computeKnownAlignForTargetInstr(GISelValueTracking &Analysis, Register R, const MachineRegisterInfo &MRI, unsigned Depth=0) const
Determine the known alignment for the pointer value R.
virtual void computeKnownBitsForFrameIndex(int FIOp, KnownBits &Known, const MachineFunction &MF) const
Determine which of the bits of FrameIndex FIOp are known to be 0.
virtual unsigned computeNumSignBitsForTargetInstr(GISelValueTracking &Analysis, Register R, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const
This method can be implemented by targets that want to expose additional information about sign bits ...
virtual void computeKnownBitsForTargetInstr(GISelValueTracking &Analysis, Register R, KnownBits &Known, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
virtual void computeKnownFPClassForTargetInstr(GISelValueTracking &Analysis, Register R, KnownFPClass &Known, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
operand_type_match m_Reg()
operand_type_match m_Pred()
bind_ty< FPClassTest > m_FPClassTest(FPClassTest &T)
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)
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 > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
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 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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
constexpr unsigned BitWidth
static uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo)
const char * toString(DWARFSectionKind Kind)
LLVM_ABI void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, KnownBits &Known)
Compute known bits from the range metadata.
static LLVM_ABI bool isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst)
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...
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
constexpr bool outputsAreZero() const
Return true if output denormals should be flushed to 0.
@ PositiveZero
Denormals are flushed to positive zero.
@ IEEE
IEEE-754 denormal numbers preserved.
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getIEEE()
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
KnownBits anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
LLVM_ABI KnownBits sextInReg(unsigned SrcBitWidth) const
Return known bits for a in-register sign extension of the value we're tracking.
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.
static LLVM_ABI KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)
Compute known bits for ashr(LHS, RHS).
bool isUnknown() const
Returns true if we don't know any bits.
KnownBits trunc(unsigned BitWidth) const
Return known bits for a truncation of the value we're tracking.
KnownBits byteSwap() const
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
KnownBits reverseBits() const
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).
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
static LLVM_ABI KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)
Compute known bits for lshr(LHS, RHS).
KnownBits extractBits(unsigned NumBits, unsigned BitPosition) const
Return a subset of the known bits from [bitPosition,bitPosition+numBits).
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.
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false)
Compute knownbits resulting from addition of LHS and RHS.
KnownBits zextOrTrunc(unsigned BitWidth) const
Return known bits for a zero extension or truncation of the value we're tracking.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
static LLVM_ABI KnownBits smin(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits for smin(LHS, RHS).
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isNegative() const
Returns true if this value is known to be negative.
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.
void insertBits(const KnownBits &SubBits, unsigned BitPosition)
Insert the bits from a smaller known bits starting at bitPosition.
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
KnownBits anyext(unsigned BitWidth) const
Return known bits for an "any" extension of the value we're tracking, where we don't know anything ab...
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).
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool cannotBeOrderedGreaterThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never greater tha...
static constexpr FPClassTest OrderedGreaterThanZeroMask
static constexpr FPClassTest OrderedLessThanZeroMask
void knownNot(FPClassTest RuleOut)
void copysign(const KnownFPClass &Sign)
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a zero.
bool isKnownNeverPosZero() const
Return true if it's known this can never be a literal positive zero.
std::optional< bool > SignBit
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
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.
bool isKnownNeverNegZero() const
Return true if it's known this can never be a negative zero.
void propagateNaN(const KnownFPClass &Src, bool PreserveSign=false)
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
void signBitMustBeOne()
Assume the sign bit is one.
void signBitMustBeZero()
Assume the sign bit is zero.
LLVM_ABI bool isKnownNeverLogicalPosZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a positive zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
LLVM_ABI bool isKnownNeverLogicalNegZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a negative zero.