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,
1329 MRI.getType(
MI.getOperand(0).getReg()).getScalarType());
1330 const fltSemantics &SrcSem =
1334 MF.getDenormalMode(DstSem),
1335 MF.getDenormalMode(SrcSem));
1338void GISelValueTracking::computeKnownFPClass(
Register R,
1339 const APInt &DemandedElts,
1343 assert(
Known.isUnknown() &&
"should not be called with known information");
1345 if (!DemandedElts) {
1353 MachineInstr &
MI = *MRI.getVRegDef(R);
1354 unsigned Opcode =
MI.getOpcode();
1355 LLT DstTy = MRI.getType(R);
1363 switch (Cst->getKind()) {
1365 Known = KnownFPClass(Cst->getScalarValue());
1371 for (
const APFloat &
C : *Cst)
1372 Known |= KnownFPClass(
C);
1387 KnownNotFromFlags |=
fcNan;
1389 KnownNotFromFlags |=
fcInf;
1393 InterestedClasses &= ~KnownNotFromFlags;
1396 [=, &
Known] {
Known.knownNot(KnownNotFromFlags); });
1406 TL.computeKnownFPClassForTargetInstr(*
this, R,
Known, DemandedElts, MRI,
1409 case TargetOpcode::G_FNEG: {
1411 computeKnownFPClass(Val, DemandedElts, InterestedClasses,
Known,
Depth + 1);
1415 case TargetOpcode::G_SELECT: {
1438 bool LookThroughFAbsFNeg = CmpLHS !=
LHS && CmpLHS !=
RHS;
1439 std::tie(TestedValue, MaskIfTrue, MaskIfFalse) =
1445 MaskIfTrue = TestedMask;
1446 MaskIfFalse = ~TestedMask;
1449 if (TestedValue ==
LHS) {
1451 FilterLHS = MaskIfTrue;
1452 }
else if (TestedValue ==
RHS) {
1454 FilterRHS = MaskIfFalse;
1457 KnownFPClass Known2;
1458 computeKnownFPClass(
LHS, DemandedElts, InterestedClasses & FilterLHS,
Known,
1460 Known.setKnownFPClasses(
Known.getKnownFPClasses() & FilterLHS);
1462 computeKnownFPClass(
RHS, DemandedElts, InterestedClasses & FilterRHS,
1469 case TargetOpcode::G_FCOPYSIGN: {
1470 Register Magnitude =
MI.getOperand(1).getReg();
1473 KnownFPClass KnownSign;
1475 computeKnownFPClass(Magnitude, DemandedElts, InterestedClasses,
Known,
1477 computeKnownFPClass(Sign, DemandedElts, InterestedClasses, KnownSign,
1479 Known.copysign(KnownSign);
1482 case TargetOpcode::G_FMA:
1483 case TargetOpcode::G_FMAD: {
1487 const bool IsFMA = Opcode == TargetOpcode::G_FMA;
1497 FPClassTest InterestedSquared = InterestedClasses;
1501 if (InterestedClasses &
fcQNan) {
1506 KnownFPClass KnownSrc, KnownAddend;
1507 computeKnownFPClass(
C, DemandedElts, InterestedAddend, KnownAddend,
1509 computeKnownFPClass(
A, DemandedElts, InterestedSquared, KnownSrc,
1511 if (KnownNotFromFlags) {
1512 KnownSrc.
knownNot(KnownNotFromFlags);
1513 KnownAddend.
knownNot(KnownNotFromFlags);
1516 : KnownFPClass::fmuladd_square(KnownSrc, KnownAddend,
Mode);
1518 KnownFPClass KnownSrc[3];
1519 computeKnownFPClass(
A, DemandedElts, InterestedClasses, KnownSrc[0],
1521 if (KnownSrc[0].isUnknown())
1523 computeKnownFPClass(
B, DemandedElts, InterestedClasses, KnownSrc[1],
1525 if (KnownSrc[1].isUnknown())
1527 computeKnownFPClass(
C, DemandedElts, InterestedClasses, KnownSrc[2],
1529 if (KnownSrc[2].isUnknown())
1531 if (KnownNotFromFlags) {
1532 KnownSrc[0].
knownNot(KnownNotFromFlags);
1533 KnownSrc[1].
knownNot(KnownNotFromFlags);
1534 KnownSrc[2].
knownNot(KnownNotFromFlags);
1538 : KnownFPClass::fmuladd(KnownSrc[0], KnownSrc[1], KnownSrc[2],
1543 case TargetOpcode::G_FSQRT:
1544 case TargetOpcode::G_STRICT_FSQRT: {
1545 KnownFPClass KnownSrc;
1547 if (InterestedClasses &
fcQNan)
1550 if (InterestedClasses &
fcZero)
1554 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1563 case TargetOpcode::G_FABS: {
1568 computeKnownFPClass(Val, DemandedElts, InterestedClasses,
Known,
1574 case TargetOpcode::G_FATAN2: {
1592 KnownFPClass KnownY, KnownX;
1593 computeKnownFPClass(
Y, DemandedElts, InterestedY, KnownY,
Depth + 1);
1594 computeKnownFPClass(
X, DemandedElts, InterestedX, KnownX,
Depth + 1);
1600 case TargetOpcode::G_FSINH: {
1602 KnownFPClass KnownSrc;
1603 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1608 case TargetOpcode::G_FCOSH: {
1610 KnownFPClass KnownSrc;
1611 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1616 case TargetOpcode::G_FTANH: {
1618 KnownFPClass KnownSrc;
1619 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1624 case TargetOpcode::G_FASIN: {
1626 KnownFPClass KnownSrc;
1627 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1632 case TargetOpcode::G_FACOS: {
1634 KnownFPClass KnownSrc;
1635 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1640 case TargetOpcode::G_FATAN: {
1642 KnownFPClass KnownSrc;
1643 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1648 case TargetOpcode::G_FTAN: {
1650 KnownFPClass KnownSrc;
1651 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1656 case TargetOpcode::G_FSIN:
1657 case TargetOpcode::G_FCOS: {
1660 KnownFPClass KnownSrc;
1661 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1664 : KnownFPClass::sin(KnownSrc);
1667 case TargetOpcode::G_FSINCOS: {
1670 KnownFPClass KnownSrc;
1671 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
1673 if (R ==
MI.getOperand(0).getReg())
1679 case TargetOpcode::G_FMAXNUM:
1680 case TargetOpcode::G_FMINNUM:
1681 case TargetOpcode::G_FMINNUM_IEEE:
1682 case TargetOpcode::G_FMAXIMUM:
1683 case TargetOpcode::G_FMINIMUM:
1684 case TargetOpcode::G_FMAXNUM_IEEE:
1685 case TargetOpcode::G_FMAXIMUMNUM:
1686 case TargetOpcode::G_FMINIMUMNUM: {
1689 KnownFPClass KnownLHS, KnownRHS;
1691 computeKnownFPClass(
LHS, DemandedElts, InterestedClasses, KnownLHS,
1693 computeKnownFPClass(
RHS, DemandedElts, InterestedClasses, KnownRHS,
1698 case TargetOpcode::G_FMINIMUM:
1701 case TargetOpcode::G_FMAXIMUM:
1704 case TargetOpcode::G_FMINIMUMNUM:
1707 case TargetOpcode::G_FMAXIMUMNUM:
1710 case TargetOpcode::G_FMINNUM:
1711 case TargetOpcode::G_FMINNUM_IEEE:
1714 case TargetOpcode::G_FMAXNUM:
1715 case TargetOpcode::G_FMAXNUM_IEEE:
1727 case TargetOpcode::G_FCANONICALIZE: {
1729 KnownFPClass KnownSrc;
1730 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1735 DenormalMode DenormMode = MF->getDenormalMode(FPType);
1739 case TargetOpcode::G_VECREDUCE_FMAX:
1740 case TargetOpcode::G_VECREDUCE_FMIN:
1741 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
1742 case TargetOpcode::G_VECREDUCE_FMINIMUM:
1743 case TargetOpcode::G_VECREDUCE_FMAXIMUMNUM:
1744 case TargetOpcode::G_VECREDUCE_FMINIMUMNUM: {
1750 computeKnownFPClass(Val,
MI.getFlags(), InterestedClasses,
Depth + 1);
1752 if (!
Known.isKnownNeverNaN())
1753 Known.setSignBit(std::nullopt);
1756 case TargetOpcode::G_FFLOOR:
1757 case TargetOpcode::G_FCEIL:
1758 case TargetOpcode::G_FRINT:
1759 case TargetOpcode::G_FNEARBYINT:
1760 case TargetOpcode::G_INTRINSIC_ROUND:
1761 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1762 case TargetOpcode::G_INTRINSIC_TRUNC: {
1764 KnownFPClass KnownSrc;
1775 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
1779 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1783 case TargetOpcode::G_INTRINSIC_TRUNC:
1786 case TargetOpcode::G_FFLOOR:
1789 case TargetOpcode::G_FCEIL:
1798 case TargetOpcode::G_FEXP:
1799 case TargetOpcode::G_FEXP2:
1800 case TargetOpcode::G_FEXP10: {
1802 KnownFPClass KnownSrc;
1803 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1808 case TargetOpcode::G_FLOG:
1809 case TargetOpcode::G_FLOG2:
1810 case TargetOpcode::G_FLOG10: {
1834 KnownFPClass KnownSrc;
1835 if (InterestedSrcs !=
fcNone)
1836 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1841 DenormalMode
Mode = MF->getDenormalMode(FltSem);
1846 case TargetOpcode::G_FPOW: {
1847 const bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1849 if (!WantNaN && !WantNegative)
1858 InterestedRHS |=
fcNan;
1867 KnownFPClass KnownLHS;
1868 computeKnownFPClass(
MI.getOperand(1).getReg(), DemandedElts, InterestedLHS,
1869 KnownLHS,
Depth + 1);
1876 KnownFPClass KnownRHS;
1877 computeKnownFPClass(
MI.getOperand(2).getReg(), DemandedElts, InterestedRHS,
1878 KnownRHS,
Depth + 1);
1882 case TargetOpcode::G_FPOWI: {
1887 LLT ExpTy = MRI.getType(Exp);
1889 Exp, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1892 if (InterestedClasses &
fcNan)
1893 InterestedSrcs |=
fcNan;
1894 if (!ExponentKnownBits.
isZero()) {
1895 if (InterestedClasses &
fcInf)
1901 KnownFPClass KnownSrc;
1902 if (InterestedSrcs !=
fcNone) {
1904 computeKnownFPClass(Val, DemandedElts, InterestedSrcs, KnownSrc,
1911 case TargetOpcode::G_FLDEXP: {
1913 KnownFPClass KnownSrc;
1914 computeKnownFPClass(Val, DemandedElts, InterestedClasses, KnownSrc,
1922 LLT ExpTy = MRI.getType(ExpReg);
1924 ExpReg, ExpTy.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
1929 DenormalMode
Mode = MF->getDenormalMode(Flt);
1933 case TargetOpcode::G_FADD:
1934 case TargetOpcode::G_FSUB: {
1937 bool IsAdd = Opcode == TargetOpcode::G_FADD;
1941 bool WantNaN = (InterestedClasses &
fcNan) !=
fcNone;
1944 if (!WantNaN && !WantNegative && !WantNegZero) {
1954 if (InterestedClasses &
fcNan)
1955 InterestedSrcs |=
fcInf;
1959 KnownFPClass KnownSelf;
1960 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSelf,
1966 KnownFPClass KnownLHS, KnownRHS;
1967 computeKnownFPClass(
RHS, DemandedElts, InterestedSrcs, KnownRHS,
Depth + 1);
1971 WantNegZero || !IsAdd) {
1974 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownLHS,
1984 case TargetOpcode::G_FMUL: {
1992 KnownFPClass KnownSrc;
1999 KnownFPClass KnownLHS;
2003 KnownFPClass KnownLHS, KnownRHS;
2019 case TargetOpcode::G_FDIV: {
2020 const bool WantNan = (InterestedClasses &
fcNan) !=
fcNone;
2035 KnownFPClass KnownSrc;
2036 computeKnownFPClass(
LHS, DemandedElts,
2045 if (!WantNan && !WantNegative && !WantPositive)
2048 KnownFPClass KnownLHS, KnownRHS;
2051 bool KnowSomethingUseful =
2056 if (KnowSomethingUseful)
2062 case TargetOpcode::G_FREM: {
2067 if (InterestedClasses &
fcNan) {
2095 FPClassTest InterestedSrcs = InterestedLHS | InterestedRHS;
2096 KnownFPClass KnownSrc;
2097 if (InterestedSrcs !=
fcNone)
2098 computeKnownFPClass(
LHS, DemandedElts, InterestedSrcs, KnownSrc,
2104 KnownFPClass KnownLHS;
2105 if (InterestedLHS !=
fcNone)
2106 computeKnownFPClass(
LHS, DemandedElts, InterestedLHS, KnownLHS,
2109 KnownFPClass KnownRHS;
2112 computeKnownFPClass(
RHS, DemandedElts, InterestedRHS, KnownRHS,
2119 case TargetOpcode::G_FFREXP: {
2121 if (R !=
MI.getOperand(0).getReg())
2140 KnownFPClass KnownSrc;
2141 computeKnownFPClass(Src, DemandedElts, InterestedSrcs, KnownSrc,
Depth + 1);
2147 case TargetOpcode::G_FPEXT: {
2149 KnownFPClass KnownSrc;
2150 computeKnownFPClass(Src, DemandedElts, InterestedClasses, KnownSrc,
2159 MF->getDenormalMode(DstSem),
2160 MF->getDenormalMode(SrcSem));
2163 case TargetOpcode::G_FPTRUNC:
2164 case TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND: {
2165 computeKnownFPClassForFPTrunc(
MI, DemandedElts, InterestedClasses,
Known,
2169 case TargetOpcode::G_SITOFP:
2170 case TargetOpcode::G_UITOFP: {
2181 if (Opcode == TargetOpcode::G_UITOFP)
2182 Known.signBitMustBeZero();
2189 LLT Ty = MRI.getType(Val);
2191 Val, Ty.
isVector() ? DemandedElts : APInt(1, 1),
Depth + 1);
2197 if (Opcode == TargetOpcode::G_SITOFP) {
2202 Known.signBitMustBeZero();
2204 Known.signBitMustBeOne();
2207 if (InterestedClasses &
fcInf) {
2214 if (Opcode == TargetOpcode::G_UITOFP)
2228 case TargetOpcode::G_BUILD_VECTOR:
2229 case TargetOpcode::G_CONCAT_VECTORS: {
2236 for (
unsigned Idx = 0;
Idx <
Merge.getNumSources(); ++
Idx) {
2238 bool NeedsElt = DemandedElts[
Idx];
2244 computeKnownFPClass(Src,
Known, InterestedClasses,
Depth + 1);
2247 KnownFPClass Known2;
2248 computeKnownFPClass(Src, Known2, InterestedClasses,
Depth + 1);
2253 if (
Known.isUnknown())
2260 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
2270 LLT VecTy = MRI.getType(Vec);
2275 if (CIdx && CIdx->ult(NumElts))
2277 return computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses,
Known,
2283 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2289 LLT VecTy = MRI.getType(Vec);
2297 APInt DemandedVecElts = DemandedElts;
2298 bool NeedsElt =
true;
2300 if (CIdx && CIdx->ult(NumElts)) {
2301 DemandedVecElts.
clearBit(CIdx->getZExtValue());
2302 NeedsElt = DemandedElts[CIdx->getZExtValue()];
2307 computeKnownFPClass(Elt,
Known, InterestedClasses,
Depth + 1);
2309 if (
Known.isUnknown())
2316 if (!DemandedVecElts.
isZero()) {
2317 KnownFPClass Known2;
2318 computeKnownFPClass(Vec, DemandedVecElts, InterestedClasses, Known2,
2325 case TargetOpcode::G_SHUFFLE_VECTOR: {
2329 APInt DemandedLHS, DemandedRHS;
2331 assert(DemandedElts == APInt(1, 1));
2332 DemandedLHS = DemandedRHS = DemandedElts;
2334 unsigned NumElts = MRI.getType(Shuf.
getSrc1Reg()).getNumElements();
2336 DemandedLHS, DemandedRHS)) {
2342 if (!!DemandedLHS) {
2344 computeKnownFPClass(
LHS, DemandedLHS, InterestedClasses,
Known,
2348 if (
Known.isUnknown())
2354 if (!!DemandedRHS) {
2355 KnownFPClass Known2;
2357 computeKnownFPClass(
RHS, DemandedRHS, InterestedClasses, Known2,
2363 case TargetOpcode::G_PHI: {
2372 for (
unsigned Idx = 1;
Idx <
MI.getNumOperands();
Idx += 2) {
2373 const MachineOperand &Src =
MI.getOperand(Idx);
2376 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses,
Known,
2380 KnownFPClass Known2;
2381 computeKnownFPClass(SrcReg, DemandedElts, InterestedClasses, Known2,
2385 if (
Known.isUnknown())
2390 case TargetOpcode::G_FREEZE: {
2393 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
2398 case TargetOpcode::COPY: {
2401 if (!Src.isVirtual())
2404 computeKnownFPClass(Src, DemandedElts, InterestedClasses,
Known,
Depth + 1);
2415 computeKnownFPClass(R, DemandedElts, InterestedClasses, KnownClasses,
Depth);
2416 return KnownClasses;
2422 computeKnownFPClass(R,
Known, InterestedClasses,
Depth);
2430 InterestedClasses &=
~fcNan;
2432 InterestedClasses &=
~fcInf;
2435 computeKnownFPClass(R, DemandedElts, InterestedClasses,
Depth);
2438 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcNan);
2440 Result.setKnownFPClasses(Result.getKnownFPClasses() & ~
fcInf);
2446 LLT Ty = MRI.getType(R);
2447 APInt DemandedElts =
2449 return computeKnownFPClass(R, DemandedElts, Flags, InterestedClasses,
Depth);
2464 switch (
DefMI->getOpcode()) {
2467 case TargetOpcode::G_FADD:
2468 case TargetOpcode::G_STRICT_FADD:
2469 case TargetOpcode::G_FSUB:
2470 case TargetOpcode::G_STRICT_FSUB:
2471 case TargetOpcode::G_FMUL:
2472 case TargetOpcode::G_STRICT_FMUL:
2473 case TargetOpcode::G_FDIV:
2474 case TargetOpcode::G_FREM:
2475 case TargetOpcode::G_FMA:
2476 case TargetOpcode::G_STRICT_FMA:
2477 case TargetOpcode::G_FMAD:
2478 case TargetOpcode::G_FSQRT:
2479 case TargetOpcode::G_STRICT_FSQRT:
2483 case TargetOpcode::G_FSIN:
2484 case TargetOpcode::G_FCOS:
2485 case TargetOpcode::G_FSINCOS:
2486 case TargetOpcode::G_FTAN:
2487 case TargetOpcode::G_FASIN:
2488 case TargetOpcode::G_FACOS:
2489 case TargetOpcode::G_FATAN:
2490 case TargetOpcode::G_FATAN2:
2491 case TargetOpcode::G_FSINH:
2492 case TargetOpcode::G_FCOSH:
2493 case TargetOpcode::G_FTANH:
2494 case TargetOpcode::G_FEXP:
2495 case TargetOpcode::G_FEXP2:
2496 case TargetOpcode::G_FEXP10:
2497 case TargetOpcode::G_FLOG:
2498 case TargetOpcode::G_FLOG2:
2499 case TargetOpcode::G_FLOG10:
2500 case TargetOpcode::G_FPOW:
2501 case TargetOpcode::G_FPOWI:
2502 case TargetOpcode::G_FLDEXP:
2503 case TargetOpcode::G_STRICT_FLDEXP:
2504 case TargetOpcode::G_FFREXP:
2505 case TargetOpcode::G_INTRINSIC_TRUNC:
2506 case TargetOpcode::G_INTRINSIC_ROUND:
2507 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
2508 case TargetOpcode::G_FFLOOR:
2509 case TargetOpcode::G_FCEIL:
2510 case TargetOpcode::G_FRINT:
2511 case TargetOpcode::G_FNEARBYINT:
2512 case TargetOpcode::G_FPEXT:
2513 case TargetOpcode::G_FPTRUNC:
2514 case TargetOpcode::G_FCANONICALIZE:
2515 case TargetOpcode::G_FMINNUM:
2516 case TargetOpcode::G_FMAXNUM:
2517 case TargetOpcode::G_FMINNUM_IEEE:
2518 case TargetOpcode::G_FMAXNUM_IEEE:
2519 case TargetOpcode::G_FMINIMUM:
2520 case TargetOpcode::G_FMAXIMUM:
2521 case TargetOpcode::G_FMINIMUMNUM:
2522 case TargetOpcode::G_FMAXIMUMNUM:
2538 return Known.isKnownNeverLogicalZero(
2543unsigned GISelValueTracking::computeNumSignBitsMin(
Register Src0,
Register Src1,
2544 const APInt &DemandedElts,
2548 if (Src1SignBits == 1)
2558 const MDNode *Ranges = Ld->getRanges();
2564 switch (Ld->getOpcode()) {
2565 case TargetOpcode::G_SEXTLOAD:
2568 case TargetOpcode::G_ZEXTLOAD:
2581 const APInt &DemandedElts,
2584 unsigned Opcode =
MI.getOpcode();
2586 if (Opcode == TargetOpcode::G_CONSTANT)
2587 return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
2595 LLT DstTy = MRI.getType(R);
2605 unsigned FirstAnswer = 1;
2607 case TargetOpcode::COPY: {
2609 if (Src.getReg().isVirtual() && Src.getSubReg() == 0 &&
2610 MRI.getType(Src.getReg()).isValid()) {
2617 case TargetOpcode::G_FREEZE: {
2623 case TargetOpcode::G_SEXT: {
2625 LLT SrcTy = MRI.getType(Src);
2626 unsigned Tmp = TyBits - SrcTy.getScalarSizeInBits();
2629 case TargetOpcode::G_ASSERT_SEXT:
2630 case TargetOpcode::G_SEXT_INREG: {
2633 unsigned SrcBits =
MI.getOperand(2).getImm();
2634 unsigned InRegBits = TyBits - SrcBits + 1;
2638 case TargetOpcode::G_LOAD: {
2645 case TargetOpcode::G_SEXTLOAD: {
2660 case TargetOpcode::G_ZEXTLOAD: {
2675 case TargetOpcode::G_AND:
2676 case TargetOpcode::G_OR:
2677 case TargetOpcode::G_XOR: {
2679 unsigned Src1NumSignBits =
2681 if (Src1NumSignBits != 1) {
2683 unsigned Src2NumSignBits =
2685 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits);
2689 case TargetOpcode::G_ASHR: {
2694 FirstAnswer = std::min<uint64_t>(FirstAnswer + *
C, TyBits);
2697 case TargetOpcode::G_SHL: {
2700 if (std::optional<ConstantRange> ShAmtRange =
2702 uint64_t MaxShAmt = ShAmtRange->getUnsignedMax().getZExtValue();
2703 uint64_t MinShAmt = ShAmtRange->getUnsignedMin().getZExtValue();
2713 if (ExtOpc == TargetOpcode::G_SEXT || ExtOpc == TargetOpcode::G_ZEXT ||
2714 ExtOpc == TargetOpcode::G_ANYEXT) {
2715 LLT ExtTy = MRI.getType(Src1);
2717 LLT ExtendeeTy = MRI.getType(Extendee);
2721 if (SizeDiff <= MinShAmt) {
2725 return Tmp - MaxShAmt;
2731 return Tmp - MaxShAmt;
2735 case TargetOpcode::G_ROTL:
2736 case TargetOpcode::G_ROTR: {
2745 case TargetOpcode::G_SAVGFLOOR:
2746 case TargetOpcode::G_SAVGCEIL: {
2749 FirstAnswer = computeNumSignBitsMin(Src1, Src2, DemandedElts,
Depth + 1);
2752 case TargetOpcode::G_SREM: {
2760 case TargetOpcode::G_TRUNC: {
2762 LLT SrcTy = MRI.getType(Src);
2767 if (NumSrcSignBits > (NumSrcBits - TyBits))
2768 return NumSrcSignBits - (NumSrcBits - TyBits);
2771 case TargetOpcode::G_SELECT: {
2772 return computeNumSignBitsMin(
MI.getOperand(2).getReg(),
2773 MI.getOperand(3).getReg(), DemandedElts,
2776 case TargetOpcode::G_SMIN:
2777 case TargetOpcode::G_SMAX:
2778 case TargetOpcode::G_UMIN:
2779 case TargetOpcode::G_UMAX:
2781 return computeNumSignBitsMin(
MI.getOperand(1).getReg(),
2782 MI.getOperand(2).getReg(), DemandedElts,
2784 case TargetOpcode::G_SADDO:
2785 case TargetOpcode::G_SADDE:
2786 case TargetOpcode::G_UADDO:
2787 case TargetOpcode::G_UADDE:
2788 case TargetOpcode::G_SSUBO:
2789 case TargetOpcode::G_SSUBE:
2790 case TargetOpcode::G_USUBO:
2791 case TargetOpcode::G_USUBE:
2792 case TargetOpcode::G_SMULO:
2793 case TargetOpcode::G_UMULO: {
2797 if (
MI.getOperand(1).getReg() == R) {
2798 if (TL.getBooleanContents(DstTy.
isVector(),
false) ==
2805 case TargetOpcode::G_SUB: {
2807 unsigned Src2NumSignBits =
2809 if (Src2NumSignBits == 1)
2819 if ((Known2.
Zero | 1).isAllOnes())
2826 FirstAnswer = Src2NumSignBits;
2833 unsigned Src1NumSignBits =
2835 if (Src1NumSignBits == 1)
2840 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2843 case TargetOpcode::G_ADD: {
2845 unsigned Src2NumSignBits =
2847 if (Src2NumSignBits <= 2)
2851 unsigned Src1NumSignBits =
2853 if (Src1NumSignBits == 1)
2862 if ((Known1.
Zero | 1).isAllOnes())
2868 FirstAnswer = Src1NumSignBits;
2877 FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
2880 case TargetOpcode::G_MUL: {
2881 unsigned Src2NumSignBits =
2883 if (Src2NumSignBits == 1)
2885 unsigned Src1NumSignBits =
2887 if (Src1NumSignBits == 1)
2891 unsigned OutValidBits =
2892 (TyBits - Src1NumSignBits + 1) + (TyBits - Src2NumSignBits + 1);
2893 if (OutValidBits <= TyBits)
2894 FirstAnswer = TyBits - OutValidBits + 1;
2897 case TargetOpcode::G_FCMP:
2898 case TargetOpcode::G_ICMP: {
2899 bool IsFP = Opcode == TargetOpcode::G_FCMP;
2902 auto BC = TL.getBooleanContents(DstTy.
isVector(), IsFP);
2909 case TargetOpcode::G_UNMERGE_VALUES: {
2910 unsigned NumOps =
MI.getNumOperands();
2912 LLT SrcTy = MRI.getType(SrcReg);
2914 if ((SrcTy.isVector() && SrcTy.getScalarType() != DstTy.
getScalarType()) ||
2915 (SrcTy.isScalar() && DstTy.
isVector()))
2919 unsigned DstIdx =
MI.findRegisterDefOperandIdx(R,
nullptr);
2921 APInt SubDemandedElts = DemandedElts;
2923 if (SrcTy.isVector()) {
2925 DemandedElts.
zext(SrcTy.getNumElements()).
shl(DstIdx * DstLanes);
2928 unsigned SrcOpKnown =
2930 if (SrcTy.isVector()) {
2931 FirstAnswer = SrcOpKnown;
2932 }
else if (SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 2) * TyBits) {
2933 FirstAnswer = SrcOpKnown >= (
MI.getNumOperands() - DstIdx - 1) * TyBits
2935 : SrcOpKnown % TyBits;
2939 case TargetOpcode::G_BUILD_VECTOR: {
2941 FirstAnswer = TyBits;
2942 APInt SingleDemandedElt(1, 1);
2944 if (!DemandedElts[
I])
2949 FirstAnswer = std::min(FirstAnswer, Tmp2);
2952 if (FirstAnswer == 1)
2957 case TargetOpcode::G_CONCAT_VECTORS: {
2958 if (MRI.getType(
MI.getOperand(0).getReg()).isScalableVector())
2960 FirstAnswer = TyBits;
2963 unsigned NumSubVectorElts =
2964 MRI.getType(
MI.getOperand(1).getReg()).getNumElements();
2967 DemandedElts.
extractBits(NumSubVectorElts,
I * NumSubVectorElts);
2972 FirstAnswer = std::min(FirstAnswer, Tmp2);
2975 if (FirstAnswer == 1)
2980 case TargetOpcode::G_VECTOR_COMPRESS: {
2984 Register PassThru =
MI.getOperand(3).getReg();
2993 FirstAnswer = std::min(Tmp, Tmp2);
2996 case TargetOpcode::G_INSERT_VECTOR_ELT: {
2998 Register InVec = Insert.getVectorReg();
2999 Register InVal = Insert.getElementReg();
3000 LLT VecVT = MRI.getType(InVec);
3006 bool DemandedVal =
true;
3007 APInt DemandedVecElts = DemandedElts;
3011 if (ConstEltNo && ConstEltNo->ult(NumElts)) {
3012 unsigned EltIdx = ConstEltNo->getZExtValue();
3013 DemandedVal = !!DemandedElts[EltIdx];
3018 unsigned Tmp = TyBits;
3021 if (MRI.getType(InVal).getSizeInBits() != TyBits)
3024 Tmp = std::min(Tmp, ValSignBits);
3026 if (!!DemandedVecElts) {
3027 unsigned VecSignBits =
3029 Tmp = std::min(Tmp, VecSignBits);
3033 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
3037 LLT VecVT = MRI.getType(InVec);
3042 APInt DemandedSrcElts =
3043 ConstEltNo && ConstEltNo->ult(NumSrcElts)
3048 case TargetOpcode::G_EXTRACT_SUBVECTOR: {
3051 LLT SrcTy = MRI.getType(SrcReg);
3052 APInt DemandedSrcElts;
3053 if (SrcTy.isScalableVector()) {
3054 DemandedSrcElts =
APInt(1, 1);
3056 uint64_t Idx =
MI.getOperand(2).getImm();
3057 unsigned NumSrcElts = SrcTy.getNumElements();
3058 DemandedSrcElts = DemandedElts.
zext(NumSrcElts).
shl(Idx);
3062 case TargetOpcode::G_SHUFFLE_VECTOR: {
3065 APInt DemandedLHS, DemandedRHS;
3067 unsigned NumElts = MRI.getType(Src1).getNumElements();
3069 DemandedElts, DemandedLHS, DemandedRHS))
3075 if (FirstAnswer == 1)
3077 if (!!DemandedRHS) {
3080 FirstAnswer = std::min(FirstAnswer, Tmp2);
3084 case TargetOpcode::G_SPLAT_VECTOR: {
3088 unsigned NumSrcBits = MRI.getType(Src).getSizeInBits();
3089 if (NumSrcSignBits > (NumSrcBits - TyBits))
3090 return NumSrcSignBits - (NumSrcBits - TyBits);
3093 case TargetOpcode::G_INTRINSIC:
3094 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
3095 case TargetOpcode::G_INTRINSIC_CONVERGENT:
3096 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
3099 TL.computeNumSignBitsForTargetInstr(*
this, R, DemandedElts, MRI,
Depth);
3101 FirstAnswer = std::max(FirstAnswer, NumBits);
3109 return std::max(FirstAnswer,
Known.countMinSignBits());
3113 LLT Ty = MRI.getType(R);
3114 APInt DemandedElts =
3123 unsigned Opcode =
MI.getOpcode();
3125 LLT Ty = MRI.getType(R);
3126 unsigned BitWidth = Ty.getScalarSizeInBits();
3128 if (Opcode == TargetOpcode::G_CONSTANT) {
3129 const APInt &ShAmt =
MI.getOperand(1).getCImm()->getValue();
3131 return std::nullopt;
3135 if (Opcode == TargetOpcode::G_BUILD_VECTOR) {
3136 const APInt *MinAmt =
nullptr, *MaxAmt =
nullptr;
3137 for (
unsigned I = 0, E =
MI.getNumOperands() - 1;
I != E; ++
I) {
3138 if (!DemandedElts[
I])
3141 if (
Op->getOpcode() != TargetOpcode::G_CONSTANT) {
3142 MinAmt = MaxAmt =
nullptr;
3146 const APInt &ShAmt =
Op->getOperand(1).getCImm()->getValue();
3148 return std::nullopt;
3149 if (!MinAmt || MinAmt->
ugt(ShAmt))
3151 if (!MaxAmt || MaxAmt->ult(ShAmt))
3154 assert(((!MinAmt && !MaxAmt) || (MinAmt && MaxAmt)) &&
3155 "Failed to find matching min/max shift amounts");
3156 if (MinAmt && MaxAmt)
3166 return std::nullopt;
3171 if (std::optional<ConstantRange> AmtRange =
3173 return AmtRange->getUnsignedMin().getZExtValue();
3174 return std::nullopt;
3192 Info = std::make_unique<GISelValueTracking>(MF, MaxDepth);
3204 return Result(MF, MaxDepth);
3210 bool PrintFPClass) {
3220 if (!MO.isReg() || MO.getReg().isPhysical())
3223 if (!
MRI.getType(
Reg).isValid())
3228 <<
" SignBitKnown:";
3236 unsigned SignedBits = VTA.computeNumSignBits(
Reg);
3237 bool IsKnownNeverZero = VTA.isKnownNeverZero(
Reg);
3238 OS <<
" " << MO <<
" KnownBits:" <<
Known
3239 <<
" SignBits:" << SignedBits
3240 <<
" 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)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
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
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
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmul.
static LLVM_ABI KnownFPClass ceil(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ceil.
static LLVM_ABI KnownFPClass fadd_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd x, x.
static KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fsub.
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
static LLVM_ABI KnownFPClass atan2(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for atan2.
static LLVM_ABI KnownFPClass atan(const KnownFPClass &Src)
Report known values for atan.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy, DenormalMode DstMode, DenormalMode SrcMode)
Propagate known class for fpext.
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy, DenormalMode DstMode, DenormalMode SrcMode)
Propagate known class for fptrunc and fptrunc_round.
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.
void knownNot(FPClassMask RuleOut)
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 ...
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
static KnownFPClass getEmpty()
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for rounding intrinsics (rint, nearbyint, round, roundeven).
static LLVM_ABI KnownFPClass fma(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma.
static LLVM_ABI KnownFPClass tan(const KnownFPClass &Src)
Report known values for tan.
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.
bool isKnownNever(FPClassMask Mask) const
Return true if it's known this can never be one of the mask entries.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
static LLVM_ABI KnownFPClass trunc(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for trunc.
static LLVM_ABI KnownFPClass fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma squared, squared, addend.
static LLVM_ABI KnownFPClass acos(const KnownFPClass &Src)
Report known values for acos.
static LLVM_ABI KnownFPClass log(const KnownFPClass &Src, DenormalMode Mode, bool IsMultiUnitFPType)
Propagate known class for log/log2/log10.
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem x, x.
static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src, const KnownBits &N)
Propagate known class for powi.
static LLVM_ABI KnownFPClass floor(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for floor.
static LLVM_ABI KnownFPClass pow(const KnownFPClass &LHS, const KnownFPClass &RHS)
Propagate known class for pow.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const APInt &ConstantRangeMin, const APInt &ConstantRangeMax, const fltSemantics &Flt, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ldexp, assuming the exponent is known to be within [ConstantRangeMin,...
static LLVM_ABI KnownFPClass sinh(const KnownFPClass &Src)
Report known values for sinh.
static LLVM_ABI KnownFPClass tanh(const KnownFPClass &Src)
Report known values for tanh.
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,...
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.