79 #define DEBUG_TYPE "dagcombine" 81 STATISTIC(NodesCombined ,
"Number of dag nodes combined");
82 STATISTIC(PreIndexedNodes ,
"Number of pre-indexed nodes created");
83 STATISTIC(PostIndexedNodes,
"Number of post-indexed nodes created");
84 STATISTIC(OpsNarrowed ,
"Number of load/op/store narrowed");
85 STATISTIC(LdStFP2Int ,
"Number of fp load/store pairs transformed to int");
86 STATISTIC(SlicedLoads,
"Number of load sliced");
87 STATISTIC(NumFPLogicOpsConv,
"Number of logic ops converted to fp ops");
91 cl::desc(
"Enable DAG combiner's use of IR alias analysis"));
95 cl::desc(
"Enable DAG combiner's use of TBAA"));
100 cl::desc(
"Only use DAG-combiner alias analysis in this" 108 cl::desc(
"Bypass the profitability model of load slicing"),
113 cl::desc(
"DAG combiner may split indexing from loads"));
122 bool LegalOperations =
false;
123 bool LegalTypes =
false;
153 void AddUsersToWorklist(
SDNode *
N) {
164 OptLevel(OL), AA(AA) {
167 MaximumLegalStoreInBits = 0;
171 VT.getSizeInBits() >= MaximumLegalStoreInBits)
172 MaximumLegalStoreInBits = VT.getSizeInBits();
177 void AddToWorklist(
SDNode *N) {
179 "Deleted Node added to Worklist");
186 if (WorklistMap.
insert(std::make_pair(N, Worklist.
size())).second)
191 void removeFromWorklist(
SDNode *N) {
192 CombinedNodes.
erase(N);
194 auto It = WorklistMap.
find(N);
195 if (It == WorklistMap.
end())
199 Worklist[It->second] =
nullptr;
200 WorklistMap.
erase(It);
203 void deleteAndRecombine(
SDNode *N);
204 bool recursivelyDeleteUnusedNodes(
SDNode *N);
212 return CombineTo(N, &Res, 1, AddTo);
219 return CombineTo(N, To, 2, AddTo);
225 unsigned MaximumLegalStoreInBits;
233 return SimplifyDemandedBits(Op, Demanded);
239 bool SimplifyDemandedVectorElts(
SDValue Op) {
242 return SimplifyDemandedVectorElts(Op, Demanded);
245 bool SimplifyDemandedBits(
SDValue Op,
const APInt &Demanded);
246 bool SimplifyDemandedVectorElts(
SDValue Op,
const APInt &Demanded,
247 bool AssumeSingleUse =
false);
249 bool CombineToPreIndexedLoadStore(
SDNode *N);
250 bool CombineToPostIndexedLoadStore(
SDNode *N);
252 bool SliceUpLoad(
SDNode *N);
422 bool NotExtCompare =
false);
423 SDValue convertSelectOfFPConstantsToLoadOffset(
433 const SDLoc &DL,
bool foldBooleans);
438 bool isOneUseSetCC(
SDValue N)
const;
446 SDValue combineInsertEltToShuffle(
SDNode *N,
unsigned InsIndex);
461 bool DemandHighBits =
true);
465 unsigned PosOpcode,
unsigned NegOpcode,
478 SDValue VecIn2,
unsigned LeftIdx);
512 int64_t OffsetFromBase;
515 : MemNode(N), OffsetFromBase(Offset) {}
522 bool isMulAddWithConstProfitable(
SDNode *MulNode,
530 EVT LoadResultTy,
EVT &ExtVT);
535 EVT &MemVT,
unsigned ShAmt = 0);
556 EVT MemVT,
unsigned NumStores,
557 bool IsConstantSrc,
bool UseVector,
573 bool checkMergeStoreCandidatesForDependencies(
595 bool hasOperation(
unsigned Opcode,
EVT VT) {
609 EVT getShiftAmountTy(
EVT LHSTy) {
616 bool isTypeLegal(
const EVT &VT) {
617 if (!LegalTypes)
return true;
622 EVT getSetCCResultType(
EVT VT)
const {
637 explicit WorklistRemover(DAGCombiner &dc)
638 :
SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
641 DC.removeFromWorklist(N);
652 ((DAGCombiner*)
DC)->AddToWorklist(N);
657 return ((DAGCombiner*)
DC)->CombineTo(N, &To[0], To.
size(), AddTo);
662 return ((DAGCombiner*)
DC)->CombineTo(N, Res, AddTo);
667 return ((DAGCombiner*)
DC)->CombineTo(N, Res0, Res1, AddTo);
672 return ((DAGCombiner*)
DC)->CommitTargetLoweringOpt(TLO);
679 void DAGCombiner::deleteAndRecombine(
SDNode *N) {
680 removeFromWorklist(N);
700 unsigned Depth = 0) {
713 if (
Depth > 6)
return 0;
716 default:
return false;
718 if (!LegalOperations)
743 if (!Options->NoSignedZerosFPMath &&
770 bool LegalOperations,
unsigned Depth = 0) {
775 assert(
Depth <= 6 &&
"GetNegatedExpression doesn't match isNegatibleForFree");
782 APFloat V = cast<ConstantFPSDNode>(
Op)->getValueAPF();
794 LegalOperations,
Depth+1),
799 LegalOperations,
Depth+1),
818 LegalOperations,
Depth+1),
825 LegalOperations,
Depth+1), Flags);
831 LegalOperations,
Depth+1));
835 LegalOperations,
Depth+1),
881 bool DAGCombiner::isOneUseSetCC(
SDValue N)
const {
891 if (isa<ConstantFPSDNode>(N))
903 return !(Const->isOpaque() && NoOpaques);
948 AddToWorklist(OpNode.
getNode());
968 AddToWorklist(OpNode.
getNode());
983 dbgs() <<
" and " << NumTo - 1 <<
" other values\n");
984 for (
unsigned i = 0, e = NumTo; i != e; ++i)
985 assert((!To[i].getNode() ||
987 "Cannot combine value to value of different type!");
989 WorklistRemover DeadNodes(*
this);
993 for (
unsigned i = 0, e = NumTo; i != e; ++i) {
994 if (To[i].getNode()) {
995 AddToWorklist(To[i].getNode());
996 AddUsersToWorklist(To[i].getNode());
1005 deleteAndRecombine(N);
1013 WorklistRemover DeadNodes(*
this);
1029 bool DAGCombiner::SimplifyDemandedBits(
SDValue Op,
const APInt &Demanded) {
1044 CommitTargetLoweringOpt(TLO);
1051 bool DAGCombiner::SimplifyDemandedVectorElts(
SDValue Op,
const APInt &Demanded,
1052 bool AssumeSingleUse) {
1054 APInt KnownUndef, KnownZero;
1056 0, AssumeSingleUse))
1068 CommitTargetLoweringOpt(TLO);
1072 void DAGCombiner::ReplaceLoadWithPromotedLoad(
SDNode *
Load,
SDNode *ExtLoad) {
1079 WorklistRemover DeadNodes(*
this);
1082 deleteAndRecombine(Load);
1083 AddToWorklist(Trunc.
getNode());
1114 return DAG.
getNode(ExtOpc, DL, PVT, Op);
1128 bool Replace =
false;
1129 SDValue NewOp = PromoteOperand(Op, PVT, Replace);
1132 AddToWorklist(NewOp.
getNode());
1143 bool Replace =
false;
1144 SDValue NewOp = PromoteOperand(Op, PVT, Replace);
1147 AddToWorklist(NewOp.
getNode());
1158 if (!LegalOperations)
1175 assert(PVT != VT &&
"Don't know what type to promote to!");
1179 bool Replace0 =
false;
1181 SDValue NN0 = PromoteOperand(N0, PVT, Replace0);
1183 bool Replace1 =
false;
1185 SDValue NN1 = PromoteOperand(N1, PVT, Replace1);
1194 Replace1 &= (N0 != N1) && !N1->
hasOneUse();
1223 if (!LegalOperations)
1240 assert(PVT != VT &&
"Don't know what type to promote to!");
1244 bool Replace =
false;
1248 N0 = SExtPromoteOperand(N0, PVT);
1250 N0 = ZExtPromoteOperand(N0, PVT);
1252 N0 = PromoteOperand(N0, PVT, Replace);
1273 if (!LegalOperations)
1290 assert(PVT != VT &&
"Don't know what type to promote to!");
1300 bool DAGCombiner::PromoteLoad(
SDValue Op) {
1301 if (!LegalOperations)
1321 assert(PVT != VT &&
"Don't know what type to promote to!");
1336 WorklistRemover DeadNodes(*
this);
1339 deleteAndRecombine(N);
1340 AddToWorklist(Result.
getNode());
1352 bool DAGCombiner::recursivelyDeleteUnusedNodes(
SDNode *N) {
1365 Nodes.
insert(ChildN.getNode());
1367 removeFromWorklist(N);
1372 }
while (!Nodes.
empty());
1388 AddToWorklist(&Node);
1396 while (!WorklistMap.
empty()) {
1403 bool GoodWorklistEntry = WorklistMap.
erase(N);
1404 (void)GoodWorklistEntry;
1405 assert(GoodWorklistEntry &&
1406 "Found a worklist entry without a corresponding map entry!");
1411 if (recursivelyDeleteUnusedNodes(N))
1414 WorklistRemover DeadNodes(*
this);
1420 bool NIsValid = DAG.
LegalizeOp(N, UpdatedNodes);
1422 for (
SDNode *LN : UpdatedNodes) {
1424 AddUsersToWorklist(LN);
1437 if (!CombinedNodes.
count(ChildN.getNode()))
1438 AddToWorklist(ChildN.getNode());
1451 if (RV.getNode() ==
N)
1456 "Node was deleted but visit returned new node!");
1469 AddToWorklist(RV.getNode());
1470 AddUsersToWorklist(RV.getNode());
1476 recursivelyDeleteUnusedNodes(N);
1519 case ISD::OR:
return visitOR(N);
1527 case ISD::FSHR:
return visitFunnelShift(N);
1605 "Node was deleted but visit returned NULL!");
1612 DagCombineInfo(DAG, Level,
false,
this);
1628 RV = PromoteIntBinOp(
SDValue(N, 0));
1633 RV = PromoteIntShiftOp(
SDValue(N, 0));
1638 RV = PromoteExtend(
SDValue(N, 0));
1641 if (PromoteLoad(
SDValue(N, 0)))
1655 if (N0 != N1 && (isa<ConstantSDNode>(N0) || !isa<ConstantSDNode>(N1))) {
1675 for (
unsigned i = 1; i < NumOps-1; ++i)
1699 bool Changed =
false;
1706 for (
unsigned i = 0; i < TFs.
size(); ++i) {
1750 bool DidPruneOps =
false;
1752 unsigned NumLeftToConsider = 0;
1753 for (
const SDValue &Op : Ops) {
1758 auto AddToWorklist = [&](
unsigned CurIdx,
SDNode *
Op,
unsigned OpNumber) {
1761 if (SeenOps.
count(Op) != 0) {
1764 unsigned OrigOpNumber = 0;
1765 while (OrigOpNumber < Ops.size() && Ops[OrigOpNumber].getNode() !=
Op)
1767 assert((OrigOpNumber != Ops.size()) &&
1768 "expected to find TokenFactor Operand");
1770 for (
unsigned i = CurIdx + 1; i < Worklist.
size(); ++i) {
1771 if (Worklist[i].
second == OrigOpNumber) {
1772 Worklist[i].second = OpNumber;
1775 OpWorkCount[OpNumber] += OpWorkCount[OrigOpNumber];
1776 OpWorkCount[OrigOpNumber] = 0;
1777 NumLeftToConsider--;
1780 if (SeenChains.
insert(Op).second) {
1781 OpWorkCount[OpNumber]++;
1782 Worklist.
push_back(std::make_pair(Op, OpNumber));
1786 for (
unsigned i = 0; i < Worklist.
size() && i < 1024; ++i) {
1788 if (NumLeftToConsider <= 1)
1790 auto CurNode = Worklist[i].first;
1791 auto CurOpNumber = Worklist[i].second;
1792 assert((OpWorkCount[CurOpNumber] > 0) &&
1793 "Node should not appear in worklist");
1794 switch (CurNode->getOpcode()) {
1800 NumLeftToConsider++;
1804 AddToWorklist(i, Op.getNode(), CurOpNumber);
1808 AddToWorklist(i, CurNode->getOperand(0).getNode(), CurOpNumber);
1811 if (
auto *MemNode = dyn_cast<MemSDNode>(CurNode))
1812 AddToWorklist(i, MemNode->getChain().getNode(), CurOpNumber);
1815 OpWorkCount[CurOpNumber]--;
1816 if (OpWorkCount[CurOpNumber] == 0)
1817 NumLeftToConsider--;
1830 for (
const SDValue &Op : Ops) {
1831 if (SeenChains.
count(Op.getNode()) == 0)
1846 WorklistRemover DeadNodes(*
this);
1852 AddUsersToWorklist(N);
1860 deleteAndRecombine(N);
1868 return Const !=
nullptr && !Const->
isOpaque() ? Const :
nullptr;
1877 unsigned SelOpNo = 0;
1903 bool CanFoldNonConst =
1909 if (!CanFoldNonConst &&
1929 SDValue NewCT = SelOpNo ? DAG.
getNode(BinOpcode, DL, VT, CBO, CT)
1930 : DAG.
getNode(BinOpcode, DL, VT, CT, CBO);
1931 if (!CanFoldNonConst && !NewCT.
isUndef() &&
1936 SDValue NewCF = SelOpNo ? DAG.
getNode(BinOpcode, DL, VT, CBO, CF)
1937 : DAG.
getNode(BinOpcode, DL, VT, CF, CBO);
1938 if (!CanFoldNonConst && !NewCF.
isUndef() &&
1948 "Expecting add or sub");
1989 "Expecting add or sub");
2030 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
2077 if ((!LegalOperations ||
2096 if (
SDValue NewSel = foldBinOpIntoSelect(N))
2120 if (N1.getOpcode() ==
ISD::SUB && N1.getOperand(1).getOpcode() ==
ISD::ADD &&
2121 N0 == N1.getOperand(1).getOperand(0))
2123 N1.getOperand(1).getOperand(1));
2126 if (N1.getOpcode() ==
ISD::SUB && N1.getOperand(1).getOpcode() ==
ISD::ADD &&
2127 N0 == N1.getOperand(1).getOperand(1))
2129 N1.getOperand(1).getOperand(0));
2133 N1.getOperand(0).getOpcode() ==
ISD::SUB &&
2134 N0 == N1.getOperand(0).getOperand(1))
2135 return DAG.
getNode(N1.getOpcode(), DL, VT, N1.getOperand(0).getOperand(0),
2157 if (SimplifyDemandedBits(
SDValue(N, 0)))
2170 if (
SDValue Combined = visitADDLike(N0, N1, N))
2173 if (
SDValue Combined = visitADDLike(N1, N0, N))
2204 return DAG.
getNode(Opcode, DL, VT, N1, N0);
2223 bool Masked =
false;
2262 SDLoc DL(LocReference);
2311 DAG.
getVTList(VT, Carry.getValueType()), N0,
2366 if (!Const)
return false;
2370 return Const->
isOne();
2402 return CombineTo(N, N0, DAG.
getConstant(0, DL, CarryVT));
2414 return CombineTo(N, Sub,
2418 if (
SDValue Combined = visitUADDOLike(N0, N1, N))
2421 if (
SDValue Combined = visitUADDOLike(N1, N0, N))
2482 if (!LegalOperations ||
2491 EVT VT = N0.getValueType();
2493 AddToWorklist(CarryExt.
getNode());
2505 return CombineTo(N, Sub,
2509 if (
SDValue Combined = visitADDCARRYLike(N0, N1, CarryIn, N))
2512 if (
SDValue Combined = visitADDCARRYLike(N1, N0, CarryIn, N))
2554 Y.getOperand(0),
Y.getOperand(1),
2556 AddToWorklist(NewY.getNode());
2585 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
2604 if (
SDValue NewSel = foldBinOpIntoSelect(N))
2623 if (ShiftAmt && ShiftAmt->
getZExtValue() == BitWidth - 1) {
2658 if (N0.getOpcode() ==
ISD::ADD && N0.getOperand(0) == N1)
2662 if (N0.getOpcode() ==
ISD::ADD && N0.getOperand(1) == N1)
2677 (N0.getOperand(1).getOpcode() ==
ISD::SUB ||
2678 N0.getOperand(1).getOpcode() ==
ISD::ADD) &&
2679 N0.getOperand(1).getOperand(0) == N1)
2680 return DAG.
getNode(N0.getOperand(1).getOpcode(), DL, VT, N0.getOperand(0),
2681 N0.getOperand(1).getOperand(1));
2684 if (N0.getOpcode() ==
ISD::ADD && N0.getOperand(1).getOpcode() ==
ISD::ADD &&
2685 N0.getOperand(1).getOperand(1) == N1)
2687 N0.getOperand(1).getOperand(0));
2690 if (N0.getOpcode() ==
ISD::SUB && N0.getOperand(1).getOpcode() ==
ISD::SUB &&
2691 N0.getOperand(1).getOperand(1) == N1)
2693 N0.getOperand(1).getOperand(0));
2736 if ((X0 == S0 && X1 == N1) || (X0 == N1 && X1 == S0)) {
2737 unsigned OpSizeInBits = VT.getScalarSizeInBits();
2739 if (
C->getAPIntValue() == (OpSizeInBits - 1))
2755 if (GA->getGlobal() == GB->getGlobal())
2756 return DAG.
getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
2871 return CombineTo(N, N0, DAG.
getConstant(0, DL, CarryVT));
2900 if (!LegalOperations ||
2917 bool N0IsConst =
false;
2918 bool N1IsConst =
false;
2919 bool N1IsOpaqueConst =
false;
2920 bool N0IsOpaqueConst =
false;
2921 APInt ConstValue0, ConstValue1;
2924 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
2931 "Splat APInt should be element width");
2934 "Splat APInt should be element width");
2936 N0IsConst = isa<ConstantSDNode>(N0);
2938 ConstValue0 = cast<ConstantSDNode>(N0)->getAPIntValue();
2939 N0IsOpaqueConst = cast<ConstantSDNode>(N0)->isOpaque();
2941 N1IsConst = isa<ConstantSDNode>(N1);
2943 ConstValue1 = cast<ConstantSDNode>(N1)->getAPIntValue();
2944 N1IsOpaqueConst = cast<ConstantSDNode>(N1)->isOpaque();
2949 if (N0IsConst && N1IsConst && !N0IsOpaqueConst && !N1IsOpaqueConst)
2964 if (
SDValue NewSel = foldBinOpIntoSelect(N))
2978 SDValue LogBase2 = BuildLogBase2(N1, DL);
2984 if (N1IsConst && !N1IsOpaqueConst && (-ConstValue1).isPowerOf2()) {
2985 unsigned Log2Val = (-ConstValue1).logBase2();
3009 if ((MulC - 1).isPowerOf2())
3011 else if ((MulC + 1).isPowerOf2())
3015 unsigned ShAmt = MathOp ==
ISD::ADD ? (MulC - 1).logBase2()
3016 : (MulC + 1).logBase2();
3018 "Not expecting multiply-by-constant that could have simplified");
3041 SDValue Sh(
nullptr, 0),
Y(
nullptr, 0);
3064 isMulAddWithConstProfitable(N, N0, N1))
3086 default:
return false;
3087 case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
3088 case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
3089 case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
3090 case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
3091 case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
3121 unsigned OtherOpcode = 0;
3145 if ((UserOpc == Opcode || UserOpc == OtherOpcode || UserOpc == DivRemOpc) &&
3149 if (UserOpc == OtherOpcode) {
3151 combined = DAG.
getNode(DivRemOpc,
SDLoc(Node), VTs, Op0, Op1);
3152 }
else if (UserOpc == DivRemOpc) {
3155 assert(UserOpc == Opcode);
3160 CombineTo(User, combined);
3162 CombineTo(User, combined.
getValue(1));
3183 if (DAG.
isUndef(Opc, {N0, N1}))
3218 EVT CCVT = getSetCCResultType(VT);
3222 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
3244 if (
SDValue NewSel = foldBinOpIntoSelect(N))
3252 if (
SDValue V = visitSDIVLike(N0, N1, N)) {
3261 CombineTo(RemNode, Sub);
3280 EVT CCVT = getSetCCResultType(VT);
3286 if (
C->isNullValue() ||
C->isOpaque())
3288 if (
C->getAPIntValue().isPowerOf2())
3290 if ((-
C->getAPIntValue()).isPowerOf2())
3301 if (
SDValue Res = BuildSDIVPow2(N))
3316 AddToWorklist(Sign.
getNode());
3320 AddToWorklist(Srl.getNode());
3322 AddToWorklist(Add.getNode());
3324 AddToWorklist(Sra.getNode());
3333 Sra = DAG.
getSelect(DL, VT, IsOneOrAllOnes, N0, Sra);
3352 if (
SDValue Op = BuildSDIV(N))
3362 EVT CCVT = getSetCCResultType(VT);
3366 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
3387 if (
SDValue NewSel = foldBinOpIntoSelect(N))
3390 if (
SDValue V = visitUDIVLike(N0, N1, N)) {
3399 CombineTo(RemNode, Sub);
3422 SDValue LogBase2 = BuildLogBase2(N1, DL);
3423 AddToWorklist(LogBase2.
getNode());
3427 AddToWorklist(Trunc.getNode());
3436 SDValue LogBase2 = BuildLogBase2(N10, DL);
3437 AddToWorklist(LogBase2.
getNode());
3441 AddToWorklist(Trunc.
getNode());
3443 AddToWorklist(Add.getNode());
3452 if (
SDValue Op = BuildUDIV(N))
3464 EVT CCVT = getSetCCResultType(VT);
3483 if (
SDValue NewSel = foldBinOpIntoSelect(N))
3519 isSigned ? visitSDIVLike(N0, N1, N) : visitUDIVLike(N0, N1, N);
3525 CombineTo(DivNode, OptimizedDiv);
3528 AddToWorklist(OptimizedDiv.
getNode());
3536 return DivRem.getValue(1);
3617 SDValue LogBase2 = BuildLogBase2(N1, DL);
3648 SDValue DAGCombiner::SimplifyNodeWithTwoResults(
SDNode *N,
unsigned LoOp,
3652 if (!HiExists && (!LegalOperations ||
3655 return CombineTo(N, Res, Res);
3660 if (!LoExists && (!LegalOperations ||
3663 return CombineTo(N, Res, Res);
3667 if (LoExists && HiExists)
3675 if (LoOpt.getNode() && LoOpt.getNode() != Lo.
getNode() &&
3676 (!LegalOperations ||
3678 return CombineTo(N, LoOpt, LoOpt);
3685 if (HiOpt.getNode() && HiOpt != Hi &&
3686 (!LegalOperations ||
3688 return CombineTo(N, HiOpt, HiOpt);
3718 return CombineTo(N, Lo, Hi);
3749 return CombineTo(N, Lo, Hi);
3759 if (C2->getAPIntValue() == 2)
3769 if (C2->getAPIntValue() == 2)
3783 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
3821 SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(
SDNode *N) {
3827 LogicOpcode ==
ISD::XOR) &&
"Expected logic opcode");
3853 if ((VT.
isVector() || LegalOperations) &&
3863 return DAG.
getNode(HandOpcode, DL, VT, Logic);
3885 return DAG.
getNode(HandOpcode, DL, VT, Logic);
3906 return DAG.
getNode(HandOpcode, DL, VT, Logic);
3921 return DAG.
getNode(HandOpcode, DL, VT, Logic);
3938 auto *SVN0 = cast<ShuffleVectorSDNode>(N0);
3939 auto *SVN1 = cast<ShuffleVectorSDNode>(N1);
3941 "Inputs to shuffles are not the same type");
3947 if (!SVN0->hasOneUse() || !SVN1->hasOneUse() ||
3948 !SVN0->getMask().equals(SVN1->getMask()))
3984 SDValue LL, LR, RL, RR, N0CC, N1CC;
3985 if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
3986 !isSetCCEquivalent(N1, RL, RR, N1CC))
3990 "Unexpected operand types for bitwise logic op");
3993 "Unexpected operand types for setcc");
4000 if (LegalOperations || VT.getScalarType() !=
MVT::i1)
4001 if (VT != getSetCCResultType(OpVT))
4009 if (LR == RR && CC0 == CC1 && IsInteger) {
4014 bool AndEqZero = IsAnd && CC1 ==
ISD::SETEQ && IsZero;
4016 bool AndGtNeg1 = IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
4018 bool OrNeZero = !IsAnd && CC1 ==
ISD::SETNE && IsZero;
4020 bool OrLtZero = !IsAnd && CC1 ==
ISD::SETLT && IsZero;
4026 if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
4029 return DAG.
getSetCC(DL, VT, Or, LR, CC1);
4033 bool AndEqNeg1 = IsAnd && CC1 ==
ISD::SETEQ && IsNeg1;
4035 bool AndLtZero = IsAnd && CC1 ==
ISD::SETLT && IsZero;
4037 bool OrNeNeg1 = !IsAnd && CC1 ==
ISD::SETNE && IsNeg1;
4039 bool OrGtNeg1 = !IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
4045 if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
4048 return DAG.
getSetCC(DL, VT, And, LR, CC1);
4076 return DAG.
getSetCC(DL, VT, Or, Zero, CC1);
4081 if (LL == RR && LR == RL) {
4088 if (LL == RL && LR == RR) {
4092 (!LegalOperations ||
4095 return DAG.
getSetCC(DL, VT, LL, LR, NewCC);
4113 if (
SDValue V = foldLogicOfSetCCs(
true, N0, N1, DL))
4125 APInt SRLC = SRLI->getAPIntValue();
4138 CombineTo(N0.
getNode(), NewAdd);
4155 const APInt &AndMask = CAnd->getAPIntValue();
4168 (ShiftBits + MaskBits <= Size / 2) &&
4180 assert(MaskBits <= Size);
4201 EVT LoadResultTy,
EVT &ExtVT) {
4210 if (ExtVT == LoadedVT &&
4211 (!LegalOperations ||
4224 if (!LoadedVT.bitsGT(ExtVT) || !ExtVT.
isRound())
4227 if (LegalOperations &&
4237 bool DAGCombiner::isLegalNarrowLdSt(
LSBaseSDNode *LDST,
4270 if (isa<LoadSDNode>(LDST)) {
4277 if (LegalOperations &&
4299 assert(isa<StoreSDNode>(LDST) &&
"It is not a Load nor a Store SDNode");
4305 if (LegalOperations &&
4312 bool DAGCombiner::SearchForAndLoads(
SDNode *N,
4326 if (
auto *
C = dyn_cast<ConstantSDNode>(Op)) {
4329 NodesWithConsts.
insert(N);
4338 auto *Load = cast<LoadSDNode>(
Op);
4340 if (isAndLoadExtLoad(Mask, Load, Load->
getValueType(0), ExtVT) &&
4345 ExtVT.bitsGE(Load->getMemoryVT()))
4349 if (ExtVT.bitsLE(Load->getMemoryVT()))
4373 if (!SearchForAndLoads(Op.
getNode(), Loads, NodesWithConsts,
Mask,
4387 for (
unsigned i = 0, e = NodeToMask->
getNumValues(); i < e; ++i) {
4391 NodeToMask =
nullptr;
4397 assert(HasValue &&
"Node to be masked has no data result?");
4417 SDNode *FixupNode =
nullptr;
4418 if (SearchForAndLoads(N, Loads, NodesWithConsts, Mask, FixupNode)) {
4419 if (Loads.
size() == 0)
4431 SDValue(FixupNode, 0), MaskOp);
4438 for (
auto *LogicN : NodesWithConsts) {
4442 if (isa<ConstantSDNode>(Op0))
4452 for (
auto *Load : Loads) {
4460 SDValue NewLoad = ReduceLoadWidth(And.getNode());
4462 "Shouldn't be masking the load if it can't be narrowed");
4463 CombineTo(Load, NewLoad, NewLoad.
getValue(1));
4476 SDValue DAGCombiner::unfoldExtremeBitClearingToShifts(
SDNode *N) {
4487 unsigned OuterShift;
4488 unsigned InnerShift;
4490 auto matchMask = [&OuterShift, &InnerShift, &
Y](
SDValue M) ->
bool {
4493 OuterShift = M->getOpcode();
4502 Y = M->getOperand(1);
4509 else if (matchMask(N0))
4536 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
4559 if (N0C && N1C && !N1C->
isOpaque())
4574 if (
SDValue NewSel = foldBinOpIntoSelect(N))
4583 if (
SDValue Shuffle = XformToShuffleWithZero(N))
4588 return RHS->getAPIntValue().isSubsetOf(LHS->
getAPIntValue());
4608 CombineTo(N0.
getNode(), Zext);
4631 Constant =
C->getAPIntValue();
4633 APInt SplatValue, SplatUndef;
4634 unsigned SplatBitSize;
4636 bool IsSplat = Vector->isConstantSplat(SplatValue, SplatUndef,
4637 SplatBitSize, HasAnyUndefs);
4641 SplatValue |= SplatUndef;
4647 EVT VT = Vector->getValueType(0);
4653 if (BitWidth > SplatBitSize)
4654 for (SplatValue = SplatValue.
zextOrTrunc(BitWidth);
4655 SplatBitSize < BitWidth;
4656 SplatBitSize = SplatBitSize * 2)
4657 SplatValue |= SplatValue.
shl(SplatBitSize);
4661 if (SplatBitSize % BitWidth == 0) {
4663 for (
unsigned i = 0, n = SplatBitSize/BitWidth; i < n; ++i)
4683 default: B =
false;
break;
4689 if (B && Constant.isAllOnesValue()) {
4695 CombineTo(N, (N0.
getNode() ==
Load) ? NewLoad : N0);
4708 CombineTo(Load, To, 3,
true);
4724 if (
SDValue Res = ReduceLoadWidth(N)) {
4726 ? cast<LoadSDNode>(N0.
getOperand(0)) : cast<LoadSDNode>(N0);
4738 if (BackwardsPropagateMask(N, DAG)) {
4743 if (
SDValue Combined = visitANDLike(N0, N1, N))
4748 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(N))
4772 if (SimplifyDemandedBits(
SDValue(N, 0)))
4783 BitWidth - MemVT.getScalarSizeInBits())) &&
4803 BitWidth - MemVT.getScalarSizeInBits())) &&
4821 if (
SDValue Shifts = unfoldExtremeBitClearingToShifts(N))
4829 bool DemandHighBits) {
4830 if (!LegalOperations)
4840 bool LookPassAnd0 =
false;
4841 bool LookPassAnd1 =
false;
4856 LookPassAnd0 =
true;
4866 LookPassAnd1 =
true;
4880 if (N01C->
getZExtValue() != 8 || N11C->getZExtValue() != 8)
4892 LookPassAnd0 =
true;
4906 LookPassAnd1 =
true;
4915 if (DemandHighBits && OpSizeInBits > 16) {
4924 if (!LookPassAnd1 &&
4931 if (OpSizeInBits > 16) {
4935 getShiftAmountTy(VT)));
4968 unsigned MaskByteOffset;
4972 case 0xFF: MaskByteOffset = 0;
break;
4973 case 0xFF00: MaskByteOffset = 1;
break;
4982 case 0xFF0000: MaskByteOffset = 2;
break;
4983 case 0xFF000000: MaskByteOffset = 3;
break;
4988 if (MaskByteOffset == 0 || MaskByteOffset == 2) {
5008 if (MaskByteOffset != 0 && MaskByteOffset != 2)
5016 if (MaskByteOffset != 1 && MaskByteOffset != 3)
5023 if (Parts[MaskByteOffset])
5037 if (!LegalOperations)
5086 if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
5115 if (
SDValue V = foldLogicOfSetCCs(
false, N0, N1, DL))
5130 const APInt &LHSMask = N0O1C->getAPIntValue();
5131 const APInt &RHSMask = N1O1C->getAPIntValue();
5169 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
5188 if (isa<ShuffleVectorSDNode>(N0) &&
5189 isa<ShuffleVectorSDNode>(N1) &&
5197 if ((ZeroN00 != ZeroN01) && (ZeroN10 != ZeroN11)) {
5198 assert((!ZeroN00 || !ZeroN01) &&
"Both inputs zero!");
5199 assert((!ZeroN10 || !ZeroN11) &&
"Both inputs zero!");
5202 bool CanFold =
true;
5206 for (
int i = 0; i != NumElts; ++i) {
5208 int M1 = SV1->getMaskElt(i);
5211 bool M0Zero = M0 < 0 || (ZeroN00 == (M0 < NumElts));
5212 bool M1Zero = M1 < 0 || (ZeroN10 == (M1 < NumElts));
5216 if ((M0Zero && M1 < 0) || (M1Zero && M0 < 0)) {
5222 if (M0Zero == M1Zero) {
5227 assert((M0 >= 0 || M1 >= 0) &&
"Undef index!");
5233 Mask[i] = M1Zero ? M0 % NumElts : (M1 % NumElts) + NumElts;
5257 if (N0C && N1C && !N1C->
isOpaque())
5270 if (
SDValue NewSel = foldBinOpIntoSelect(N))
5277 if (
SDValue Combined = visitORLike(N0, N1, N))
5281 if (
SDValue BSwap = MatchBSwapHWord(N, N0, N1))
5283 if (
SDValue BSwap = MatchBSwapHWordLow(N, N0, N1))
5307 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(N))
5314 if (
SDValue Load = MatchLoadCombine(N))
5318 if (SimplifyDemandedBits(
SDValue(N, 0)))
5368 assert(OppShift && ExtractFrom &&
"Empty SDValue");
5371 "Existing shift must be valid as a rotate half");
5379 bool IsMulOrDiv =
false;
5382 auto SelectOpcode = [&](
unsigned NeededShift,
unsigned MulOrDivVariant) {
5383 IsMulOrDiv = ExtractFrom.
getOpcode() == MulOrDivVariant;
5384 if (!IsMulOrDiv && ExtractFrom.
getOpcode() != NeededShift)
5386 Opcode = NeededShift;
5414 !OppLHSCst || !OppLHSCst->getAPIntValue() ||
5415 !ExtractFromCst || !ExtractFromCst->getAPIntValue())
5424 APInt ExtractFromAmt = ExtractFromCst->getAPIntValue();
5425 APInt OppLHSAmt = OppLHSCst->getAPIntValue();
5440 if (Rem != 0 || ResultAmt != OppLHSAmt)
5446 if (OppLHSAmt != ExtractFromAmt - NeededShiftAmt.
zextOrTrunc(
5455 return DAG.
getNode(Opcode, DL, ResVT, OppShiftLHS, NewShiftNode);
5500 unsigned MaskLoBits = 0;
5505 if (NegC->getAPIntValue().getActiveBits() <= Bits &&
5526 if (PosC->getAPIntValue().getActiveBits() <= MaskLoBits &&
5566 return Width.
getLoBits(MaskLoBits) == 0;
5567 return Width == EltSize;
5577 SDValue InnerNeg,
unsigned PosOpcode,
5578 unsigned NegOpcode,
const SDLoc &DL) {
5589 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode, DL, VT, Shifted,
5590 HasPos ? Pos : Neg).
getNode();
5605 bool HasROTL = hasOperation(
ISD::ROTL, VT);
5606 bool HasROTR = hasOperation(
ISD::ROTR, VT);
5607 if (!HasROTL && !HasROTR)
return nullptr;
5629 if (!LHSShift && !RHSShift)
5644 RHSShift = NewRHSShift;
5649 LHSShift = NewLHSShift;
5652 if (!RHSShift || !LHSShift)
5680 return (LHS->
getAPIntValue() + RHS->getAPIntValue()) == EltSizeInBits;
5684 LHSShiftArg, HasROTL ? LHSShiftAmt : RHSShiftAmt);
5714 SDValue LExtOp0 = LHSShiftAmt;
5715 SDValue RExtOp0 = RHSShiftAmt;
5728 SDNode *TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
5733 SDNode *TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
5745 struct ByteProvider {
5750 unsigned ByteOffset = 0;
5752 ByteProvider() =
default;
5755 return ByteProvider(Load, ByteOffset);
5758 static ByteProvider getConstantZero() {
return ByteProvider(
nullptr, 0); }
5760 bool isConstantZero()
const {
return !
Load; }
5761 bool isMemory()
const {
return Load; }
5764 return Other.Load == Load && Other.ByteOffset == ByteOffset;
5768 ByteProvider(
LoadSDNode *Load,
unsigned ByteOffset)
5769 :
Load(Load), ByteOffset(ByteOffset) {}
5787 bool Root =
false) {
5797 if (BitWidth % 8 != 0)
5799 unsigned ByteWidth = BitWidth / 8;
5800 assert(Index < ByteWidth &&
"invalid index requested");
5812 if (LHS->isConstantZero())
5814 if (RHS->isConstantZero())
5823 uint64_t BitShift = ShiftOp->getZExtValue();
5824 if (BitShift % 8 != 0)
5826 uint64_t ByteShift = BitShift / 8;
5828 return Index < ByteShift
5829 ? ByteProvider::getConstantZero()
5838 if (NarrowBitWidth % 8 != 0)
5840 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
5842 if (Index >= NarrowByteWidth)
5852 auto L = cast<LoadSDNode>(Op.
getNode());
5853 if (L->isVolatile() || L->isIndexed())
5856 unsigned NarrowBitWidth = L->getMemoryVT().getSizeInBits();
5857 if (NarrowBitWidth % 8 != 0)
5859 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
5861 if (Index >= NarrowByteWidth)
5904 "Can only match load combining against OR nodes");
5910 unsigned ByteWidth = VT.getSizeInBits() / 8;
5919 std::function<unsigned(unsigned, unsigned)> LittleEndianByteAt = [](
5920 unsigned BW,
unsigned i) {
return i; };
5921 std::function<unsigned(unsigned, unsigned)> BigEndianByteAt = [](
5922 unsigned BW,
unsigned i) {
return BW - i - 1; };
5925 auto MemoryByteOffset = [&] (ByteProvider
P) {
5926 assert(
P.isMemory() &&
"Must be a memory byte provider");
5927 unsigned LoadBitWidth =
P.Load->getMemoryVT().getSizeInBits();
5928 assert(LoadBitWidth % 8 == 0 &&
5929 "can only analyze providers for individual bytes not bit");
5930 unsigned LoadByteWidth = LoadBitWidth / 8;
5931 return IsBigEndianTarget
5932 ? BigEndianByteAt(LoadByteWidth,
P.ByteOffset)
5933 : LittleEndianByteAt(LoadByteWidth,
P.ByteOffset);
5946 for (
unsigned i = 0; i < ByteWidth; i++) {
5948 if (!
P || !
P->isMemory())
5953 "Must be enforced by calculateByteProvider");
5960 else if (Chain != LChain)
5965 int64_t ByteOffsetFromBase = 0;
5972 ByteOffsetFromBase += MemoryByteOffset(*
P);
5973 ByteOffsets[i] = ByteOffsetFromBase;
5976 if (ByteOffsetFromBase < FirstOffset) {
5977 FirstByteProvider =
P;
5978 FirstOffset = ByteOffsetFromBase;
5983 assert(!Loads.
empty() &&
"All the bytes of the value must be loaded from " 5984 "memory, so there must be at least one load which produces the value");
5985 assert(Base &&
"Base address of the accessed memory location must be set");
5990 bool BigEndian =
true, LittleEndian =
true;
5991 for (
unsigned i = 0; i < ByteWidth; i++) {
5992 int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
5993 LittleEndian &= CurrentByteOffset == LittleEndianByteAt(ByteWidth, i);
5994 BigEndian &= CurrentByteOffset == BigEndianByteAt(ByteWidth, i);
5995 if (!BigEndian && !LittleEndian)
5998 assert((BigEndian != LittleEndian) &&
"should be either or");
5999 assert(FirstByteProvider &&
"must be set");
6003 if (MemoryByteOffset(*FirstByteProvider) != 0)
6005 LoadSDNode *FirstLoad = FirstByteProvider->Load;
6011 bool NeedsBswap = IsBigEndianTarget != BigEndian;
6024 if (!Allowed || !Fast)
6064 if (And.getOpcode() !=
ISD::AND || !And.hasOneUse())
6086 if (!matchAndXor(N0, 0, N1) && !matchAndXor(N0, 1, N1) &&
6087 !matchAndXor(N1, 0, N0) && !matchAndXor(N1, 1, N0))
6093 if (isa<ConstantSDNode>(M.
getNode()))
6127 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
6159 if (
SDValue NewSel = foldBinOpIntoSelect(N))
6172 if (!LegalOperations ||
6188 isSetCCEquivalent(N0.
getOperand(0), LHS, RHS, CC)){
6201 if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) {
6205 AddToWorklist(LHS.
getNode()); AddToWorklist(RHS.getNode());
6206 return DAG.
getNode(NewOpcode, DL, VT, LHS, RHS);
6213 if (isa<ConstantSDNode>(RHS) || isa<ConstantSDNode>(LHS)) {
6217 AddToWorklist(LHS.
getNode()); AddToWorklist(RHS.getNode());
6218 return DAG.
getNode(NewOpcode, DL, VT, LHS, RHS);
6225 AddToWorklist(NotX.
getNode());
6233 if (XorC && ShiftC) {
6237 if (ShiftAmt < BitWidth) {
6239 Ones = N0Opcode ==
ISD::SHL ? Ones.
shl(ShiftAmt) : Ones.
lshr(ShiftAmt);
6258 if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0)) {
6261 if (
C->getAPIntValue() == (OpSizeInBits - 1))
6297 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(N))
6301 if (
SDValue MM = unfoldMaskedMerge(N))
6305 if (SimplifyDemandedBits(
SDValue(N, 0)))
6325 bool HighBitSet =
false;
6345 if (!BinOpCst)
return SDValue();
6356 if ((!isShift || !isa<ConstantSDNode>(BinOpLHSVal->
getOperand(1))) &&
6371 if (BinOpRHSSignSet != HighBitSet)
6382 assert(isa<ConstantSDNode>(NewRHS) &&
"Folding was not successful!");
6393 SDValue DAGCombiner::distributeTruncateThroughAnd(
SDNode *N) {
6406 AddToWorklist(Trunc00.
getNode());
6407 AddToWorklist(Trunc01.
getNode());
6435 if (Cst->getAPIntValue().uge(Bitsize)) {
6436 uint64_t RotAmt = Cst->getAPIntValue().urem(Bitsize);
6456 bool SameSide = (N->
getOpcode() == NextOp);
6462 ISD::SREM, dl, ShiftVT, CombinedShift.getNode(),
6483 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
6510 if (N0C && N1C && !N1C->
isOpaque())
6513 if (
SDValue NewSel = foldBinOpIntoSelect(N))
6527 if (N1C && SimplifyDemandedBits(
SDValue(N, 0)))
6535 APInt c2 = RHS->getAPIntValue();
6537 return (c1 + c2).uge(OpSizeInBits);
6545 APInt c2 = RHS->getAPIntValue();
6547 return (c1 + c2).ult(OpSizeInBits);
6568 APInt c1 = N0Op0C1->getAPIntValue();
6574 if (c2.
uge(OpSizeInBits - InnerShiftSize)) {
6576 APInt Sum = c1 + c2;
6577 if (Sum.
uge(OpSizeInBits))
6596 uint64_t c1 = N0Op0C1->getZExtValue();
6605 AddToWorklist(NewSHL.
getNode());
6617 uint64_t C1 = N0C1->getZExtValue();
6635 uint64_t c1 = N0C1->getZExtValue();
6636 if (c1 < OpSizeInBits) {
6678 AddToWorklist(Shl0.
getNode());
6679 AddToWorklist(Shl1.
getNode());
6693 if (
SDValue NewSHL = visitShiftByConstant(N, N1C))
6716 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
6723 if (N0C && N1C && !N1C->
isOpaque())
6726 if (
SDValue NewSel = foldBinOpIntoSelect(N))
6737 if ((!LegalOperations ||
6747 EVT ShiftVT = N1.getValueType();
6753 APInt c2 = RHS->getAPIntValue();
6755 APInt Sum = c1 + c2;
6766 ShiftValue = ShiftValues[0];
6794 if ((ShiftAmt > 0) &&
6813 N1.getOperand(0).getOpcode() ==
ISD::AND) {
6814 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.getNode()))
6828 unsigned LargeShiftVal = LargeShift->getZExtValue();
6844 if (N1C && SimplifyDemandedBits(
SDValue(N, 0)))
6852 if (
SDValue NewSRA = visitShiftByConstant(N, N1C))
6869 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
6876 if (N0C && N1C && !N1C->
isOpaque())
6879 if (
SDValue NewSel = foldBinOpIntoSelect(N))
6892 APInt c2 = RHS->getAPIntValue();
6894 return (c1 + c2).uge(OpSizeInBits);
6902 APInt c2 = RHS->getAPIntValue();
6904 return (c1 + c2).ult(OpSizeInBits);
6918 uint64_t c1 = N001C->getZExtValue();
6924 if (c1 + OpSizeInBits == InnerShiftSize) {
6926 if (c1 + c2 >= InnerShiftSize)
6943 AddToWorklist(Mask.
getNode());
6961 getShiftAmountTy(SmallVT)));
6962 AddToWorklist(SmallShift.
getNode());
7024 if (N1C && SimplifyDemandedBits(
SDValue(N, 0)))
7028 if (
SDValue NewSRL = visitShiftByConstant(N, N1C))
7032 if (
SDValue NarrowLoad = ReduceLoadWidth(N))
7080 return IsFSHL ? N0 : N1;
7084 if (Cst->getAPIntValue().uge(BitWidth)) {
7085 uint64_t RotAmt = Cst->getAPIntValue().urem(BitWidth);
7096 if (N0 == N1 && hasOperation(RotOpc, VT))
7223 if (!(LHS == True && RHS == False) && !(LHS == False && RHS == True))
7239 return DAG.
getNode(IEEEOpcode, DL, VT, LHS, RHS);
7243 return DAG.
getNode(Opcode, DL, VT, LHS, RHS);
7254 return DAG.
getNode(IEEEOpcode, DL, VT, LHS, RHS);
7258 return DAG.
getNode(Opcode, DL, VT, LHS, RHS);
7286 if (CondVT ==
MVT::i1 && !LegalOperations) {
7287 if (C1->isNullValue() && C2->isOne()) {
7294 if (C1->isNullValue() && C2->isAllOnesValue()) {
7301 if (C1->isOne() && C2->isNullValue()) {
7307 if (C1->isAllOnesValue() && C2->isNullValue()) {
7318 if (C1->getAPIntValue() - 1 == C2->getAPIntValue()) {
7324 if (C1->getAPIntValue() + 1 == C2->getAPIntValue()) {
7349 C1->isNullValue() && C2->isOne()) {
7376 if (
SDValue V = foldSelectOfConstants(N))
7382 AddToWorklist(NOTNode.
getNode());
7388 AddToWorklist(NOTNode.
getNode());
7397 if (SimplifySelectOps(N, N1, N2))
7409 bool normalizeToSequence =
7418 if (normalizeToSequence || !InnerSelect.
use_empty())
7428 if (normalizeToSequence || !InnerSelect.
use_empty())
7440 if (!normalizeToSequence) {
7445 if (
SDValue Combined = visitANDLike(N0, N1_0, N))
7457 if (!normalizeToSequence) {
7462 if (
SDValue Combined = visitORLike(N0, N2_0, N))
7499 if (
C && NotC &&
C->getAPIntValue() == ~NotC->getAPIntValue()) {
7523 return SimplifySelect(DL, N0, N1, N2);
7543 return std::make_pair(Lo, Hi);
7570 for (
int i = 0; i < NumElems / 2; ++i) {
7574 if (BottomHalf ==
nullptr)
7575 BottomHalf = cast<ConstantSDNode>(Cond.
getOperand(i));
7582 for (
int i = NumElems / 2; i < NumElems; ++i) {
7586 if (TopHalf ==
nullptr)
7587 TopHalf = cast<ConstantSDNode>(Cond.
getOperand(i));
7592 assert(TopHalf && BottomHalf &&
7593 "One half of the selector was all UNDEFs and the other was all the " 7594 "same value. This should have been addressed before this function.");
7622 std::tie(MaskLo, MaskHi) =
SplitVSETCC(Mask.getNode(), DAG);
7632 EVT LoMemVT, HiMemVT;
7636 std::tie(DataLo, DataHi) = DAG.
SplitVector(Data, DL);
7648 SDValue OpsLo[] = { Chain, DataLo, MaskLo, BasePtr, IndexLo, Scale };
7655 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, BasePtr, IndexHi, Scale };
7681 std::tie(MaskLo, MaskHi) =
SplitVSETCC(Mask.getNode(), DAG);
7691 unsigned SecondHalfAlignment =
7692 (Alignment == VT.
getSizeInBits() / 8) ? Alignment / 2 : Alignment;
7694 EVT LoMemVT, HiMemVT;
7698 std::tie(DataLo, DataHi) = DAG.
SplitVector(Data, DL);
7705 Lo = DAG.
getMaskedStore(Chain, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO,
7718 Hi = DAG.
getMaskedStore(Chain, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO,
7722 AddToWorklist(Lo.getNode());
7754 std::tie(MaskLo, MaskHi) =
SplitVSETCC(Mask.getNode(), DAG);
7757 SDValue PassThruLo, PassThruHi;
7758 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, DL);
7767 EVT LoMemVT, HiMemVT;
7774 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Index, DL);
7781 SDValue OpsLo[] = { Chain, PassThruLo, MaskLo, BasePtr, IndexLo, Scale };
7785 SDValue OpsHi[] = { Chain, PassThruHi, MaskHi, BasePtr, IndexHi, Scale };
7803 SDValue RetOps[] = { GatherRes, Chain };
7828 std::tie(MaskLo, MaskHi) =
SplitVSETCC(Mask.getNode(), DAG);
7831 SDValue PassThruLo, PassThruHi;
7832 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, DL);
7844 unsigned SecondHalfAlignment =
7846 Alignment/2 : Alignment;
7848 EVT LoMemVT, HiMemVT;
7856 Lo = DAG.
getMaskedLoad(LoVT, DL, Chain, Ptr, MaskLo, PassThruLo, LoMemVT,
7868 Hi = DAG.
getMaskedLoad(HiVT, DL, Chain, Ptr, MaskHi, PassThruHi, HiMemVT,
7871 AddToWorklist(Lo.getNode());
7885 SDValue RetOps[] = { LoadRes, Chain };
7907 bool AllAddOne =
true;
7908 bool AllSubOne =
true;
7910 for (
unsigned i = 0; i != Elts; ++i) {
7916 const APInt &C1 = cast<ConstantSDNode>(N1Elt)->getAPIntValue();
7917 const APInt &C2 = cast<ConstantSDNode>(N2Elt)->getAPIntValue();
7927 if (AllAddOne || AllSubOne) {
7979 AddToWorklist(Shift.
getNode());
8012 SetCCWidth != 1 && SetCCWidth < WideWidth &&
8022 EVT WideSetCCVT = getSetCCResultType(WideVT);
8023 SDValue WideSetCC = DAG.
getSetCC(DL, WideSetCCVT, WideLHS, WideRHS, CC);
8024 return DAG.
getSelect(DL, N1.getValueType(), WideSetCC, N1, N2);
8029 if (SimplifySelectOps(N, N1, N2))
8049 if (
SDValue V = foldVSelectOfConstants(N))
8069 CC,
SDLoc(N),
false)) {
8070 AddToWorklist(SCC.getNode());
8072 if (
ConstantSDNode *SCCC = dyn_cast<ConstantSDNode>(SCC.getNode())) {
8073 if (!SCCC->isNullValue())
8077 }
else if (SCC->isUndef()) {
8084 SCC.getOperand(0), SCC.getOperand(1), N2, N3,
8090 if (SimplifySelectOps(N, N2, N3))
8094 return SimplifySelectCC(
SDLoc(N), N0, N1, N2, N3, CC);
8104 SDValue Combined = SimplifySetCC(
8106 cast<CondCodeSDNode>(N->
getOperand(2))->
get(),
SDLoc(N), !PreferSetCC);
8114 SDValue NewSetCC = rebuildSetCC(Combined);
8155 &&
"Expected EXTEND dag node in input!");
8160 if (isa<ConstantSDNode>(N0))
8183 for (
unsigned i = 0; i != NumElts; ++i) {
8193 APInt C = cast<ConstantSDNode>(
Op)->getAPIntValue().zextOrTrunc(EVTBits);
8211 bool HasCopyToRegUses =
false;
8219 if (UI.getUse().getResNo() != N0.
getResNo())
8228 for (
unsigned i = 0; i != 2; ++i) {
8232 if (!isa<ConstantSDNode>(UseOp))
8246 HasCopyToRegUses =
true;
8249 if (HasCopyToRegUses) {
8250 bool BothLiveOut =
false;
8262 return ExtendNodes.
size();
8272 for (
SDNode *SetCC : SetCCs) {
8275 for (
unsigned j = 0; j != 2; ++j) {
8277 if (SOp == OrigLoad)
8296 "Unexpected node type (not an extend)!");
8333 EVT SplitSrcVT = SrcVT;
8334 EVT SplitDstVT = DstVT;
8345 const unsigned NumSplits =
8352 for (
unsigned Idx = 0; Idx < NumSplits; Idx++) {
8353 const unsigned Offset = Idx * Stride;
8365 Chains.
push_back(SplitLoad.getValue(1));
8372 AddToWorklist(NewChain.
getNode());
8374 CombineTo(N, NewValue);
8381 CombineTo(N0.
getNode(), Trunc, NewChain);
8387 SDValue DAGCombiner::CombineZExtLogicopShiftLoad(
SDNode *N) {
8439 Mask = Mask.
zext(VT.getSizeInBits());
8446 if (
SDValue(Load, 0).hasOneUse()) {
8451 CombineTo(Load, Trunc, ExtLoad.
getValue(1));
8460 SDValue DAGCombiner::matchVSelectOpSizesWithSetCC(
SDNode *Cast) {
8461 unsigned CastOpcode = Cast->
getOpcode();
8465 "Unexpected opcode for vector select narrowing/widening");
8495 CastA = DAG.
getNode(CastOpcode, DL, VT, A);
8496 CastB = DAG.
getNode(CastOpcode, DL, VT, B);
8505 bool LegalOperations,
SDNode *N,
8523 Combiner.CombineTo(N, ExtLoad);
8538 ((LegalOperations || VT.
isVector() ||
8543 bool DoXform =
true;
8556 Combiner.ExtendSetCCUses(SetCCs, N0, ExtLoad, ExtOpc);
8559 Combiner.CombineTo(N, ExtLoad);
8560 if (NoReplaceTrunc) {
8565 Combiner.CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
8571 bool LegalOperations) {
8596 return DAG.
getNode(ShiftOpcode, DL, VT, NotX, ShiftAmount);
8619 if (NarrowLoad.getNode() != N0.
getNode()) {
8620 CombineTo(N0.
getNode(), NarrowLoad);
8635 if (OpBits == DestBits) {
8638 if (NumSignBits > DestBits-MidBits)
8640 }
else if (OpBits < DestBits) {
8643 if (NumSignBits > OpBits-MidBits)
8648 if (NumSignBits > OpBits-MidBits)
8655 if (OpBits < DestBits)
8657 else if (OpBits > DestBits)
8672 if (
SDValue ExtLoad = CombineExtLoad(N))
8677 DAG, *
this, TLI, VT, LegalOperations, N, N0,
ISD::SEXTLOAD))
8704 bool NoReplaceTruncAnd = !N0.
hasOneUse();
8708 if (NoReplaceTruncAnd) {
8711 CombineTo(N0.
getNode(), TruncAnd);
8713 if (NoReplaceTrunc) {
8718 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
8736 if (VT.
isVector() && !LegalOperations &&
8742 EVT SVT = getSetCCResultType(N00VT);
8752 return DAG.
getSetCC(DL, VT, N00, N01, CC);
8758 if (SVT == MatchingVecType) {
8777 SDValue ExtTrueVal = (SetCCWidth == 1)
8782 SimplifySelectCC(DL, N00, N01, ExtTrueVal, Zero, CC,
true))
8786 EVT SetCCVT = getSetCCResultType(N00VT);
8794 return DAG.
getSelect(DL, VT, SetCC, ExtTrueVal, Zero);
8804 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
8840 return (Known.
Zero | 1).isAllOnesValue();
8862 APInt TruncatedBits =
8879 if (NarrowLoad.getNode() != N0.
getNode()) {
8880 CombineTo(N0.
getNode(), NarrowLoad);
8941 if (
SDValue ExtLoad = CombineExtLoad(N))
8957 bool DoXform =
true;
8961 auto *AndC = cast<ConstantSDNode>(N0.
getOperand(1));
8964 if (isAndLoadExtLoad(AndC, LN00, LoadResultTy, ExtVT))
8982 bool NoReplaceTruncAnd = !N0.
hasOneUse();
8986 if (NoReplaceTruncAnd) {
8989 CombineTo(N0.
getNode(), TruncAnd);
8991 if (NoReplaceTrunc) {
8996 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
9005 if (
SDValue ZExtLoad = CombineZExtLogicopShiftLoad(N))
9010 DAG, *
this, TLI, VT, LegalOperations, N, N0,
ISD::ZEXTLOAD))
9018 if (!LegalOperations && VT.
isVector() &&
9051 if (
SDValue SCC = SimplifySelectCC(
9054 cast<CondCodeSDNode>(N0.
getOperand(2))->
get(),
true))
9064 unsigned ShAmtVal = cast<ConstantSDNode>(ShAmt)->getZExtValue();
9071 if (ShAmtVal > KnownZeroBits)
9086 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
9112 if (NarrowLoad.getNode() != N0.
getNode()) {
9113 CombineTo(N0.
getNode(), NarrowLoad);
9148 bool DoXform =
true;
9162 CombineTo(N, ExtLoad);
9163 if (NoReplaceTrunc) {
9168 CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
9182 if (!LegalOperations || TLI.
isLoadExtLegal(ExtType, VT, MemVT)) {
9186 CombineTo(N, ExtLoad);
9198 if (VT.
isVector() && !LegalOperations) {
9211 cast<CondCodeSDNode>(N0.
getOperand(2))->
get());
9220 cast<CondCodeSDNode>(N0.
getOperand(2))->
get());
9226 if (
SDValue SCC = SimplifySelectCC(
9229 cast<CondCodeSDNode>(N0.
getOperand(2))->
get(),
true))
9240 EVT AssertVT = cast<VTSDNode>(N1)->getVT();
9244 AssertVT == cast<VTSDNode>(N0.
getOperand(1))->getVT())
9255 EVT BigA_AssertVT = cast<VTSDNode>(BigA.
getOperand(1))->getVT();
9257 "Asserting zero/sign-extended bits to a type larger than the " 9258 "truncated destination does not provide information");
9261 EVT MinAssertVT = AssertVT.
bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
9275 EVT BigA_AssertVT = cast<VTSDNode>(BigA.
getOperand(1))->getVT();
9277 "Asserting zero/sign-extended bits to a type larger than the " 9278 "truncated destination does not provide information");
9280 if (AssertVT.bitsLT(BigA_AssertVT)) {
9310 bool HasShiftedOffset =
false;
9315 ExtVT = cast<VTSDNode>(N->
getOperand(1))->getVT();
9328 uint64_t ShiftAmt = N01->getZExtValue();
9329 uint64_t MemoryWidth = LN0->getMemoryVT().getSizeInBits();
9330 if (LN0->getExtensionType() !=
ISD::SEXTLOAD && MemoryWidth > ShiftAmt)
9342 unsigned ActiveBits = 0;
9349 HasShiftedOffset =
true;
9359 if (
auto *ConstShift = dyn_cast<ConstantSDNode>(SRL.
getOperand(1))) {
9360 ShAmt = ConstShift->getZExtValue();
9363 if ((ShAmt & (EVTBits-1)) == 0) {
9371 if (!isa<LoadSDNode>(N0))
return SDValue();
9373 auto *LN0 = cast<LoadSDNode>(N0);
9384 if (ShAmt >= LN0->getMemoryVT().getSizeInBits())
9392 const APInt &ShiftMask =
9393 cast<ConstantSDNode>(Mask->
getOperand(1))->getAPIntValue();
9394 if (ShiftMask.
isMask()) {
9408 unsigned ShLeftAmt = 0;
9412 ShLeftAmt = N01->getZExtValue();
9418 if (!isa<LoadSDNode>(N0))
9422 if (!isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
9425 auto AdjustBigEndianShift = [&](
unsigned ShAmt) {
9428 return LVTStoreBits - EVTStoreBits - ShAmt;
9434 ShAmt = AdjustBigEndianShift(ShAmt);
9437 uint64_t PtrOff = ShAmt / 8;
9447 AddToWorklist(NewPtr.
getNode());
9461 WorklistRemover DeadNodes(*
this);
9466 if (ShLeftAmt != 0) {
9482 if (HasShiftedOffset) {
9486 ShAmt = AdjustBigEndianShift(ShAmt);
9505 EVT EVT = cast<VTSDNode>(N1)->getVT();
9533 if ((N00Bits <= EVTBits ||
9544 if (!LegalOperations ||
9565 if (SimplifyDemandedBits(
SDValue(N, 0)))
9570 if (
SDValue NarrowLoad = ReduceLoadWidth(N))
9578 if (ShAmt->getZExtValue()+EVTBits <= VTBits) {
9582 if (VTBits-(ShAmt->getZExtValue()+EVTBits) < InSignBits)
9594 EVT == cast<LoadSDNode>(N0)->getMemoryVT() &&
9595 ((!LegalOperations && !cast<LoadSDNode>(N0)->
isVolatile() &&
9603 CombineTo(N, ExtLoad);
9604 CombineTo(N0.
getNode(), ExtLoad, ExtLoad.getValue(1));
9605 AddToWorklist(ExtLoad.getNode());
9611 EVT == cast<LoadSDNode>(N0)->getMemoryVT() &&
9612 ((!LegalOperations && !cast<LoadSDNode>(N0)->
isVolatile()) ||
9619 CombineTo(N, ExtLoad);
9620 CombineTo(N0.
getNode(), ExtLoad, ExtLoad.getValue(1));
9635 SDValue DAGCombiner::visitSIGN_EXTEND_VECTOR_INREG(
SDNode *N) {
9645 if (SimplifyDemandedVectorElts(
SDValue(N, 0)))
9651 SDValue DAGCombiner::visitZERO_EXTEND_VECTOR_INREG(
SDNode *N) {
9661 if (SimplifyDemandedVectorElts(
SDValue(N, 0)))
9729 if (isa<ConstantSDNode>(EltNo) && isTypeLegal(NVT)) {
9730 int Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
9732 int Index = isLE ? (Elt*SizeRatio) : (Elt*SizeRatio + (SizeRatio-1));
9787 if (BuildVectEltTy == TruncVecEltTy) {
9791 unsigned TruncEltOffset = BuildVecNumElts / TruncVecNumElts;
9793 assert((BuildVecNumElts % TruncVecNumElts) == 0 &&
9794 "Invalid number of elements");
9797 for (
unsigned i = 0, e = BuildVecNumElts; i != e; i += TruncEltOffset)
9819 if (
SDValue Reduced = ReduceLoadWidth(N))
9844 unsigned NumDefs = 0;
9865 assert(V.
getNode() &&
"The single defined operand is empty!");
9867 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
9874 Opnds.push_back(NV);
9888 (!LegalOperations ||
9901 SimplifyDemandedBits(
SDValue(N, 0)))
9933 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
9947 if (!LegalOperations && N0.
hasOneUse() &&
9987 LD1->getAddressSpace() != LD2->getAddressSpace())
9989 EVT LD1VT = LD1->getValueType(0);
9993 unsigned Align = LD1->getAlignment();
9997 if (NewAlign <= Align &&
9999 return DAG.
getLoad(VT,
SDLoc(N), LD1->getChain(), LD1->getBasePtr(),
10000 LD1->getPointerInfo(),
Align);
10056 NumFPLogicOpsConv++;
10081 return ConstantFoldBITCASTofBUILD_VECTOR(N0.
getNode(),
10085 if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
10089 if (!LegalOperations ||
10115 ((!LegalOperations && !cast<LoadSDNode>(N0)->
isVolatile()) ||
10154 AddToWorklist(NewConv.
getNode());
10164 AddToWorklist(FlipBit.
getNode());
10171 AddToWorklist(Hi.getNode());
10173 AddToWorklist(FlipBit.getNode());
10177 AddToWorklist(FlipBits.getNode());
10205 if (isTypeLegal(IntXVT)) {
10211 if (OrigXWidth < VTWidth) {
10214 }
else if (OrigXWidth > VTWidth) {
10224 AddToWorklist(X.getNode());
10230 AddToWorklist(Cst.getNode());
10232 AddToWorklist(X.getNode());
10234 AddToWorklist(XorResult.getNode());
10238 SDLoc(XorResult)));
10239 AddToWorklist(XorResult64.getNode());
10243 AddToWorklist(FlipBit.getNode());
10246 AddToWorklist(FlipBits.getNode());
10252 AddToWorklist(X.getNode());
10257 AddToWorklist(Cst.getNode());
10265 if (
SDValue CombineLD = CombineConsecutiveLoads(N0.
getNode(), VT))
10280 auto PeekThroughBitcast = [&](
SDValue Op) {
10302 for (
int i = 0; i != MaskScale; ++i)
10303 NewMask.
push_back(M < 0 ? -1 : M * MaskScale + i);
10321 return CombineConsecutiveLoads(N, VT);
10327 ConstantFoldBITCASTofBUILD_VECTOR(
SDNode *BV,
EVT DstEltVT) {
10331 if (SrcEltVT == DstEltVT)
return SDValue(BV, 0);
10338 if (SrcBitSize == DstBitSize) {
10360 BV = ConstantFoldBITCASTofBUILD_VECTOR(BV, IntVT).getNode();
10368 SDNode *Tmp = ConstantFoldBITCASTofBUILD_VECTOR(BV, TmpVT).getNode();
10371 return ConstantFoldBITCASTofBUILD_VECTOR(Tmp, DstEltVT);
10379 if (SrcBitSize < DstBitSize) {
10380 unsigned NumInputsPerOutput = DstBitSize/SrcBitSize;
10384 i += NumInputsPerOutput) {
10387 bool EltIsUndef =
true;
10388 for (
unsigned j = 0; j != NumInputsPerOutput; ++j) {
10390 NewBits <<= SrcBitSize;
10393 EltIsUndef =
false;
10395 NewBits |= cast<ConstantSDNode>(
Op)->getAPIntValue().
10396 zextOrTrunc(SrcBitSize).
zext(DstBitSize);
10411 unsigned NumOutputsPerInput = SrcBitSize/DstBitSize;
10422 APInt OpVal = cast<ConstantSDNode>(
Op)->
10425 for (
unsigned j = 0; j != NumOutputsPerInput; ++j) {
10427 Ops.push_back(DAG.
getConstant(ThisVal, DL, DstEltVT));
10433 std::reverse(Ops.end()-NumOutputsPerInput, Ops.end());
10462 if (!HasFMAD && !HasFMA)
10468 CanFuse || HasFMAD);
10483 auto isContractableFMUL = [AllowFusionGlobally](
SDValue N) {
10490 if (Aggressive && isContractableFMUL(N0) && isContractableFMUL(N1)) {
10496 if (isContractableFMUL(N0) && (Aggressive || N0->
hasOneUse())) {
10497 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10503 if (isContractableFMUL(N1) && (Aggressive || N1->
hasOneUse())) {
10504 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10513 if (isContractableFMUL(N00) &&
10515 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10527 if (isContractableFMUL(N10) &&
10529 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10541 N0.
getOpcode() == PreferredFusedOpcode &&
10544 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10546 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10549 N1, Flags), Flags);
10554 N1->
getOpcode() == PreferredFusedOpcode &&
10557 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10559 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10562 N0, Flags), Flags);
10568 auto FoldFAddFMAFPExtFMul = [&] (
10571 return DAG.
getNode(PreferredFusedOpcode, SL, VT, X, Y,
10572 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10577 if (N0.
getOpcode() == PreferredFusedOpcode) {
10581 if (isContractableFMUL(N020) &&
10595 auto FoldFAddFPExtFMAFMul = [&] (
10598 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10601 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10608 if (N00.
getOpcode() == PreferredFusedOpcode) {
10610 if (isContractableFMUL(N002) &&
10621 if (N1.
getOpcode() == PreferredFusedOpcode) {
10625 if (isContractableFMUL(N120) &&
10641 if (N10.
getOpcode() == PreferredFusedOpcode) {
10643 if (isContractableFMUL(N102) &&
10673 if (!HasFMAD && !HasFMA)
10679 CanFuse || HasFMAD);
10695 auto isContractableFMUL = [AllowFusionGlobally](
SDValue N) {
10702 if (isContractableFMUL(N0) && (Aggressive || N0->
hasOneUse())) {
10703 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10710 if (isContractableFMUL(N1) && (Aggressive || N1->
hasOneUse())) {
10711 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10722 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10733 if (isContractableFMUL(N00) &&
10735 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10749 if (isContractableFMUL(N10) &&
10751 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10771 if (isContractableFMUL(N000) &&
10774 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10794 if (isContractableFMUL(N000) &&
10797 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10811 if (CanFuse && N0.
getOpcode() == PreferredFusedOpcode &&
10814 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10816 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10820 N1), Flags), Flags);
10825 if (CanFuse && N1.
getOpcode() == PreferredFusedOpcode &&
10829 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10833 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10835 N21, N0, Flags), Flags);
10841 if (N0.
getOpcode() == PreferredFusedOpcode) {
10845 if (isContractableFMUL(N020) &&
10847 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10849 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10855 N1), Flags), Flags);
10868 if (N00.
getOpcode() == PreferredFusedOpcode) {
10870 if (isContractableFMUL(N002) &&
10872 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10877 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10883 N1), Flags), Flags);
10890 if (N1.
getOpcode() == PreferredFusedOpcode &&
10893 if (isContractableFMUL(N120) &&
10897 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10900 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10906 N0, Flags), Flags);
10922 if (isContractableFMUL(N102) &&
10926 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
10931 DAG.
getNode(PreferredFusedOpcode, SL, VT,
10937 N0, Flags), Flags);
10948 SDValue DAGCombiner::visitFMULForFMADistributiveCombine(
SDNode *N) {
10961 if (!Options.NoInfsFPMath)
10972 bool HasFMAD = Options.UnsafeFPMath &&
10976 if (!HasFMAD && !HasFMA)
10988 if (
C->isExactlyValue(+1.0))
10991 if (
C->isExactlyValue(-1.0))
11011 if (C0->isExactlyValue(+1.0))
11012 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
11015 if (C0->isExactlyValue(-1.0))
11016 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
11021 if (C1->isExactlyValue(+1.0))
11024 if (C1->isExactlyValue(-1.0))
11052 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
11056 if (N0CFP && N1CFP)
11060 if (N0CFP && !N1CFP)
11065 if (N1C && N1C->
isZero())
11069 if (
SDValue NewSel = foldBinOpIntoSelect(N))
11084 auto isFMulNegTwo = [](
SDValue FMul) {
11085 if (!FMul.hasOneUse() || FMul.getOpcode() !=
ISD::FMUL)
11088 return C &&
C->isExactlyValue(-2.0);
11092 if (isFMulNegTwo(N0)) {
11098 if (isFMulNegTwo(N1)) {
11141 if (CFP01 && !CFP00 && N0.
getOperand(0) == N1) {
11162 if (CFP11 && !CFP10 && N1.
getOperand(0) == N0) {
11210 if (
SDValue Fused = visitFADDForFMACombine(N)) {
11211 AddToWorklist(Fused.getNode());
11229 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
11233 if (N0CFP && N1CFP)
11236 if (
SDValue NewSel = foldBinOpIntoSelect(N))
11240 if (N1CFP && N1CFP->
isZero()) {
11254 if (N0CFP && N0CFP->
isZero()) {
11281 if (
SDValue Fused = visitFSUBForFMACombine(N)) {
11282 AddToWorklist(Fused.getNode());
11302 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
11307 if (N0CFP && N1CFP)
11319 if (
SDValue NewSel = foldBinOpIntoSelect(N))
11325 if (N1CFP && N1CFP->
isZero())
11368 if (LHSNeg == 2 || RHSNeg == 2)
11389 if (TrueOpnd && FalseOpnd &&
11391 isa<ConstantFPSDNode>(Cond.
getOperand(1)) &&
11392 cast<ConstantFPSDNode>(Cond.
getOperand(1))->isExactlyValue(0.0)) {
11410 if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
11414 if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
11423 if (
SDValue Fused = visitFMULForFMADistributiveCombine(N)) {
11424 AddToWorklist(Fused.getNode());
11446 if (isa<ConstantFPSDNode>(N0) &&
11447 isa<ConstantFPSDNode>(N1) &&
11448 isa<ConstantFPSDNode>(N2)) {
11452 if (UnsafeFPMath) {
11453 if (N0CFP && N0CFP->
isZero())
11455 if (N1CFP && N1CFP->isZero())
11461 if (N1CFP && N1CFP->isExactlyValue(1.0))
11469 if (UnsafeFPMath) {
11494 if (N1CFP->isExactlyValue(1.0))
11498 if (N1CFP->isExactlyValue(-1.0) &&
11501 AddToWorklist(RHSNeg.
getNode());
11515 if (UnsafeFPMath) {
11517 if (N1CFP && N0 == N2) {
11543 SDValue DAGCombiner::combineRepeatedFPDivisors(
SDNode *N) {
11559 if (!MinUses || N1->
use_size() < MinUses)
11565 for (
auto *U : N1->
uses()) {
11566 if (U->getOpcode() ==
ISD::FDIV && U->getOperand(1) == N1) {
11569 if (UnsafeMath || U->getFlags().hasAllowReciprocal())
11576 if (Users.
size() < MinUses)
11585 for (
auto *U : Users) {
11587 if (Dividend != FPOne) {
11589 Reciprocal, Flags);
11590 CombineTo(U, NewNode);
11591 }
else if (U != Reciprocal.
getNode()) {
11594 CombineTo(U, Reciprocal);
11612 if (
SDValue FoldedVOp = SimplifyVBinOp(N))
11616 if (N0CFP && N1CFP)
11619 if (
SDValue NewSel = foldBinOpIntoSelect(N))
11626 const APFloat &N1APF = N1CFP->getValueAPF();
11632 (!LegalOperations ||
11653 AddToWorklist(RV.getNode());
11661 AddToWorklist(RV.getNode());
11681 AddToWorklist(RV.getNode());
11688 if (
SDValue RV = BuildReciprocalEstimate(N1, Flags)) {
11689 AddToWorklist(RV.getNode());
11699 if (LHSNeg == 2 || RHSNeg == 2)
11707 if (
SDValue CombineRepeatedDivisors = combineRepeatedFPDivisors(N))
11708 return CombineRepeatedDivisors;
11721 if (N0CFP && N1CFP)
11724 if (
SDValue NewSel = foldBinOpIntoSelect(N))
11741 return buildSqrtEstimate(N0, Flags);
11756 return (N1VT == N1Op0VT || N1Op0VT !=
MVT::f128);
11768 if (N0CFP && N1CFP)
11772 const APFloat &V = N1C->getValueAPF();
11917 (!LegalOperations ||
11935 (!LegalOperations ||
11949 (!LegalOperations ||
11974 (!LegalOperations ||
11991 (!LegalOperations ||
12032 unsigned ActualSize = std::min(InputSize, OutputSize);
12117 AddToWorklist(Tmp.
getNode());
12122 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
12135 if (N0CFP && isTypeLegal(EVT)) {
12182 CombineTo(N, ExtLoad);
12191 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
12277 AddToWorklist(Int.
getNode());
12310 if (N0CFP && N1CFP) {
12375 AddToWorklist(Int.
getNode());
12405 if (
SDValue NewN1 = rebuildSetCC(N1))
12445 const APInt &AndConst = cast<ConstantSDNode>(AndOp1)->getAPIntValue();
12448 cast<ConstantSDNode>(Op1)->getAPIntValue() == AndConst.
logBase2()) {
12489 bool Equal =
false;
12498 SetCCVT = getSetCCResultType(SetCCVT);
12521 SDValue Simp = SimplifySetCC(getSetCCResultType(CondLHS.getValueType()),
12522 CondLHS, CondRHS, CC->
get(),
SDLoc(N),
12545 if (
LD->isIndexed() ||
LD->getBasePtr().getNode() !=
N)
12547 VT =
LD->getMemoryVT();
12548 AS =
LD->getAddressSpace();
12550 if (
ST->isIndexed() ||
ST->getBasePtr().getNode() !=
N)
12552 VT =
ST->getMemoryVT();
12553 AS =
ST->getAddressSpace();
12586 bool DAGCombiner::CombineToPreIndexedLoadStore(
SDNode *N) {
12594 if (
LD->isIndexed())
12596 VT =
LD->getMemoryVT();
12600 Ptr =
LD->getBasePtr();
12602 if (
ST->isIndexed())
12604 VT =
ST->getMemoryVT();
12608 Ptr =
ST->getBasePtr();
12630 bool Swapped =
false;
12631 if (isa<ConstantSDNode>(BasePtr)) {
12650 if (isa<FrameIndexSDNode>(BasePtr) || isa<RegisterSDNode>(BasePtr))
12655 SDValue Val = cast<StoreSDNode>(
N)->getValue();
12669 if (isa<ConstantSDNode>(Offset))
12689 if (!isa<ConstantSDNode>(Op1)) {
12707 bool RealUse =
false;
12727 BasePtr, Offset, AM);
12730 BasePtr, Offset, AM);
12735 WorklistRemover DeadNodes(*
this);
12744 deleteAndRecombine(N);
12750 for (
unsigned i = 0, e = OtherUses.
size(); i != e; ++i) {
12751 unsigned OffsetIdx = 1;
12752 if (OtherUses[i]->getOperand(OffsetIdx).getNode() == BasePtr.
getNode())
12754 assert(OtherUses[i]->getOperand(!OffsetIdx).getNode() ==
12755 BasePtr.
getNode() &&
"Expected BasePtr operand");
12769 cast<ConstantSDNode>(OtherUses[i]->getOperand(OffsetIdx));
12770 int X0, X1, Y0, Y1;
12771 const APInt &Offset0 = CN->getAPIntValue();
12772 APInt Offset1 = cast<ConstantSDNode>(
Offset)->getAPIntValue();
12774 X0 = (OtherUses[i]->getOpcode() ==
ISD::SUB && OffsetIdx == 1) ? -1 : 1;
12775 Y0 = (OtherUses[i]->getOpcode() ==
ISD::SUB && OffsetIdx == 0) ? -1 : 1;
12781 APInt CNV = Offset0;
12782 if (X0 < 0) CNV = -CNV;
12783 if (X1 * Y0 * Y1 < 0) CNV = CNV + Offset1;
12784 else CNV = CNV - Offset1;
12786 SDLoc DL(OtherUses[i]);
12794 OtherUses[i]->getValueType(0), NewOp1, NewOp2);
12796 deleteAndRecombine(OtherUses[i]);
12801 deleteAndRecombine(Ptr.
getNode());
12802 AddToWorklist(Result.
getNode());
12811 bool DAGCombiner::CombineToPostIndexedLoadStore(
SDNode *N) {
12819 if (
LD->isIndexed())
12821 VT =
LD->getMemoryVT();
12825 Ptr =
LD->getBasePtr();
12827 if (
ST->isIndexed())
12829 VT =
ST->getMemoryVT();
12833 Ptr =
ST->getBasePtr();
12862 if (isa<FrameIndexSDNode>(BasePtr) || isa<RegisterSDNode>(BasePtr))
12866 bool TryNext =
false;
12874 bool RealUse =
false;
12901 BasePtr, Offset, AM)
12903 BasePtr, Offset, AM);
12904 ++PostIndexedNodes;
12909 WorklistRemover DeadNodes(*
this);
12918 deleteAndRecombine(N);
12923 deleteAndRecombine(Op);
12943 !cast<ConstantSDNode>(Inc)->isOpaque()) &&
12944 "Cannot split out indexing using opaque target constants");
12964 if (STType == STMemType)
12966 if (isTypeLegal(STMemType))
12989 "Attempting to extend value of non-matching type");
12990 if (LDType == LDMemType)
13050 SDValue Ops[] = {Val, Idx, Chain};
13051 return CombineTo(LD, Ops, 3);
13053 return CombineTo(LD, Val, Chain);
13060 if (Offset == 0 && LDType == STType && STMemType == LDMemType) {
13063 return ReplaceLd(LD, ST->
getValue(), Chain);
13071 SDLoc(ST), STType);
13073 return ReplaceLd(LD, Val, Chain);
13084 if (!getTruncatedStoreValue(ST, Val))
13086 if (!isTypeLegal(LDMemType))
13088 if (STMemType != LDMemType) {
13096 if (!extendLoadedValueToExtension(LD, Val))
13098 return ReplaceLd(LD, Val, Chain);
13103 deleteAndRecombine(Val.
getNode());
13126 dbgs() <<
"\nWith chain: "; Chain.getNode()->dump(&DAG);
13128 WorklistRemover DeadNodes(*
this);
13130 AddUsersToWorklist(Chain.getNode());
13132 deleteAndRecombine(N);
13145 cast<ConstantSDNode>(LD->
getOperand(2))->isOpaque();
13152 Index = SplitIndexingFromLoad(LD);
13155 AddUsersToWorklist(N);
13160 dbgs() <<
" and 2 other values\n");
13161 WorklistRemover DeadNodes(*
this);
13165 deleteAndRecombine(N);
13173 if (
auto V = ForwardStoreValueToDirectLoad(LD))
13193 SDValue BetterChain = FindBetterChain(N, Chain);
13196 if (Chain != BetterChain) {
13215 return CombineTo(N, ReplLoad.
getValue(0), Token);
13220 if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
13225 if (SliceUpLoad(N))
13245 struct LoadedSlice {
13252 unsigned Loads = 0;
13253 unsigned Truncates = 0;
13254 unsigned CrossRegisterBanksCopies = 0;
13255 unsigned ZExts = 0;
13256 unsigned Shift = 0;
13258 Cost(
bool ForCodeSize =
false) : ForCodeSize(ForCodeSize) {}
13261 Cost(
const LoadedSlice &
LS,
bool ForCodeSize =
false)
13262 : ForCodeSize(ForCodeSize), Loads(1) {
13263 EVT TruncType = LS.Inst->getValueType(0);
13264 EVT LoadedType = LS.getLoadedType();
13265 if (TruncType != LoadedType &&
13266 !LS.DAG->getTargetLoweringInfo().isZExtFree(LoadedType, TruncType))
13274 void addSliceGain(
const LoadedSlice &LS) {
13278 LS.Inst->getValueType(0)))
13284 if (LS.canMergeExpensiveCrossRegisterBankCopy())
13285 ++CrossRegisterBanksCopies;
13289 Loads += RHS.Loads;
13290 Truncates += RHS.Truncates;
13291 CrossRegisterBanksCopies += RHS.CrossRegisterBanksCopies;
13292 ZExts += RHS.ZExts;
13293 Shift += RHS.Shift;
13298 return Loads == RHS.Loads && Truncates == RHS.Truncates &&
13299 CrossRegisterBanksCopies == RHS.CrossRegisterBanksCopies &&
13300 ZExts == RHS.ZExts && Shift == RHS.Shift;
13303 bool operator!=(
const Cost &RHS)
const {
return !(*
this == RHS); }
13305 bool operator<(
const Cost &RHS)
const {
13308 unsigned ExpensiveOpsLHS = Loads + CrossRegisterBanksCopies;
13309 unsigned ExpensiveOpsRHS = RHS.Loads + RHS.CrossRegisterBanksCopies;
13312 if (!ForCodeSize && ExpensiveOpsLHS != ExpensiveOpsRHS)
13313 return ExpensiveOpsLHS < ExpensiveOpsRHS;
13314 return (Truncates + ZExts + Shift + ExpensiveOpsLHS) <
13315 (RHS.Truncates + RHS.ZExts + RHS.Shift + ExpensiveOpsRHS);
13318 bool operator>(
const Cost &RHS)
const {
return RHS < *
this; }
13320 bool operator<=(
const Cost &RHS)
const {
return !(RHS < *
this); }
13322 bool operator>=(
const Cost &RHS)
const {
return !(*
this < RHS); }
13341 : Inst(Inst), Origin(Origin), Shift(Shift), DAG(DAG) {}
13346 APInt getUsedBits()
const {
13351 assert(Origin &&
"No original load to compare against.");
13353 assert(Inst &&
"This slice is not bound to an instruction");
13355 "Extracted slice is bigger than the whole type!");
13358 UsedBits = UsedBits.zext(BitWidth);
13359 UsedBits <<= Shift;
13364 unsigned getLoadedSize()
const {
13365 unsigned SliceSize = getUsedBits().countPopulation();
13366 assert(!(SliceSize & 0x7) &&
"Size is not a multiple of a byte.");
13367 return SliceSize / 8;
13372 EVT getLoadedType()
const {
13373 assert(DAG &&
"Missing context");
13381 unsigned Offset = getOffsetFromBase();
13383 Alignment =
MinAlign(Alignment, Alignment + Offset);
13388 bool isLegal()
const {
13390 if (!Origin || !Inst || !DAG)
13400 EVT SliceType = getLoadedType();
13424 if (TruncateType != SliceType &&
13434 uint64_t getOffsetFromBase()
const {
13435 assert(DAG &&
"Missing context.");
13437 assert(!(Shift & 0x7) &&
"Shifts not aligned on Bytes are not supported.");
13438 uint64_t
Offset = Shift / 8;
13441 "The size of the original loaded type is not a multiple of a" 13445 assert(TySizeInBytes > Offset &&
13446 "Invalid shift amount for given loaded size");
13448 Offset = TySizeInBytes - Offset - getLoadedSize();
13459 assert(Inst && Origin &&
"Unable to replace a non-existing slice.");
13461 SDValue BaseAddr = OldBaseAddr;
13463 int64_t
Offset =
static_cast<int64_t
>(getOffsetFromBase());
13464 assert(Offset >= 0 &&
"Offset too big to fit in int64_t!");
13474 EVT SliceType = getLoadedType();
13484 if (SliceType != FinalType)
13494 bool canMergeExpensiveCrossRegisterBankCopy()
const {
13500 assert(DAG &&
"Missing context");
13559 const LoadedSlice &Second) {
13560 assert(First.Origin == Second.Origin && First.Origin &&
13561 "Unable to match different memory origins.");
13562 APInt UsedBits = First.getUsedBits();
13563 assert((UsedBits & Second.getUsedBits()) == 0 &&
13564 "Slices are not supposed to overlap.");
13565 UsedBits |= Second.getUsedBits();
13574 LoadedSlice::Cost &GlobalLSCost) {
13575 unsigned NumberOfSlices = LoadedSlices.
size();
13577 if (NumberOfSlices < 2)
13582 llvm::sort(LoadedSlices, [](
const LoadedSlice &LHS,
const LoadedSlice &RHS) {
13583 assert(LHS.Origin == RHS.Origin &&
"Different bases not implemented.");
13584 return LHS.getOffsetFromBase() < RHS.getOffsetFromBase();
13586 const TargetLowering &TLI = LoadedSlices[0].DAG->getTargetLoweringInfo();
13589 const LoadedSlice *First =
nullptr;
13590 const LoadedSlice *Second =
nullptr;
13591 for (
unsigned CurrSlice = 0; CurrSlice < NumberOfSlices; ++CurrSlice,
13594 Second = &LoadedSlices[CurrSlice];
13601 EVT LoadedType = First->getLoadedType();
13604 if (LoadedType != Second->getLoadedType())
13608 unsigned RequiredAlignment = 0;
13609 if (!TLI.hasPairedLoad(LoadedType, RequiredAlignment)) {
13615 if (RequiredAlignment > First->getAlignment())
13622 assert(GlobalLSCost.Loads > 0 &&
"We save more loads than we created!");
13623 --GlobalLSCost.Loads;
13640 const APInt &UsedBits,
bool ForCodeSize) {
13641 unsigned NumberOfSlices = LoadedSlices.
size();
13643 return NumberOfSlices > 1;
13646 if (NumberOfSlices != 2)
13654 LoadedSlice::Cost OrigCost(ForCodeSize), GlobalSlicingCost(ForCodeSize);
13656 OrigCost.Loads = 1;
13657 for (
unsigned CurrSlice = 0; CurrSlice < NumberOfSlices; ++CurrSlice) {
13658 const LoadedSlice &
LS = LoadedSlices[CurrSlice];
13660 LoadedSlice::Cost SliceCost(LS, ForCodeSize);
13661 GlobalSlicingCost += SliceCost;
13665 OrigCost.addSliceGain(LS);
13670 return OrigCost > GlobalSlicingCost;
13679 bool DAGCombiner::SliceUpLoad(
SDNode *N) {
13698 UI != UIEnd; ++UI) {
13700 if (UI.getUse().getResNo() != 0)
13704 unsigned Shift = 0;
13727 LoadedSlice
LS(User, LD, Shift, &DAG);
13728 APInt CurrentUsedBits = LS.getUsedBits();
13731 if ((CurrentUsedBits & UsedBits) != 0)
13734 UsedBits |= CurrentUsedBits;
13741 LoadedSlices.push_back(LS);
13756 LSIt = LoadedSlices.begin(),
13757 LSItEnd = LoadedSlices.end();
13758 LSIt != LSItEnd; ++LSIt) {
13759 SDValue SliceInst = LSIt->loadSlice();
13760 CombineTo(LSIt->Inst, SliceInst,
true);
13764 "It takes more than a zext to get to the loaded slice!!");
13771 AddToWorklist(Chain.
getNode());
13778 static std::pair<unsigned, unsigned>
13780 std::pair<unsigned, unsigned> Result(0, 0);
13801 uint64_t NotMask = ~cast<ConstantSDNode>(V->
getOperand(1))->getSExtValue();
13803 if (NotMaskLZ & 7)
return Result;
13805 if (NotMaskTZ & 7)
return Result;
13806 if (NotMaskLZ == 64)
return Result;
13817 switch (MaskedBytes) {
13821 default:
return Result;
13826 if (NotMaskTZ && NotMaskTZ/8 % MaskedBytes)
return Result;
13837 if (ChainOp.getNode() ==
LD) {
13846 Result.first = MaskedBytes;
13847 Result.second = NotMaskTZ/8;
13858 unsigned NumBytes = MaskInfo.first;
13859 unsigned ByteShift = MaskInfo.second;
13865 ByteShift*8, (ByteShift+NumBytes)*8);
13872 if (!DC->isTypeLegal(VT))
13889 StOffset = ByteShift;
13898 NewAlign =
MinAlign(NewAlign, StOffset);
13936 std::pair<unsigned, unsigned> MaskedLoad;
13938 if (MaskedLoad.first)
13945 if (MaskedLoad.first)
13967 APInt Imm = cast<ConstantSDNode>(N1)->getAPIntValue();
13978 while (NewBW < BitWidth &&
13985 if (NewBW >= BitWidth)
13991 ShAmt = (((ShAmt + NewBW - 1) / NewBW) * NewBW) - NewBW;
13993 std::min(BitWidth, ShAmt + NewBW));
13994 if ((Imm & Mask) == Imm) {
13998 uint64_t PtrOff = ShAmt / 8;
14002 PtrOff = (BitWidth + 7 - NewBW) / 8 - PtrOff;
14024 AddToWorklist(NewPtr.
getNode());
14025 AddToWorklist(NewLD.
getNode());
14026 AddToWorklist(NewVal.
getNode());
14027 WorklistRemover DeadNodes(*
this);
14049 if (!VT.isFloatingPoint() ||
14068 if (LDAlign < ABIAlign || STAlign < ABIAlign)
14079 AddToWorklist(NewLD.
getNode());
14080 AddToWorklist(NewST.
getNode());
14081 WorklistRemover DeadNodes(*
this);
14103 bool DAGCombiner::isMulAddWithConstProfitable(
SDNode *MulNode,
14114 if (
Use == MulNode)
14122 if (
Use->getOperand(0) == ConstNode)
14123 OtherOp =
Use->getOperand(1).getNode();
14125 OtherOp =
Use->getOperand(0).getNode();
14137 if (OtherOp == MulVar)
14165 unsigned NumStores) {
14168 SDLoc StoreDL(StoreNodes[0].MemNode);
14170 for (
unsigned i = 0; i < NumStores; ++i) {
14171 Visited.
insert(StoreNodes[i].MemNode);
14175 for (
unsigned i = 0; i < NumStores; ++i) {
14176 if (Visited.
count(StoreNodes[i].MemNode->getChain().getNode()) == 0)
14177 Chains.
push_back(StoreNodes[i].MemNode->getChain());
14180 assert(Chains.
size() > 0 &&
"Chain should have generated a chain");
14184 bool DAGCombiner::MergeStoresOfConstantsOrVecElts(
14186 bool IsConstantSrc,
bool UseVector,
bool UseTrunc) {
14192 SDLoc DL(StoreNodes[0].MemNode);
14195 unsigned SizeInBits = NumStores * ElementSizeBits;
14200 unsigned Elts = NumStores * NumMemElts;
14208 if (IsConstantSrc) {
14210 for (
unsigned I = 0;
I != NumStores; ++
I) {
14211 StoreSDNode *St = cast<StoreSDNode>(StoreNodes[
I].MemNode);
14214 if (MemVT != Val.getValueType()) {
14217 if (ElementSizeBits != Val.getValueSizeInBits()) {
14220 if (isa<ConstantFPSDNode>(Val)) {
14223 }
else if (
auto *
C = dyn_cast<ConstantSDNode>(Val))
14225 .zextOrTrunc(Val.getValueSizeInBits())
14226 .zextOrTrunc(ElementSizeBits),
14236 DL, StoreTy, BuildVector);
14239 for (
unsigned i = 0; i < NumStores; ++i) {
14240 StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
14248 if ((MemVT != Val.getValueType()) &&
14274 assert(IsConstantSrc &&
"Merged vector elements should use vector store");
14276 APInt StoreInt(SizeInBits, 0);
14281 for (
unsigned i = 0; i < NumStores; ++i) {
14282 unsigned Idx = IsLE ? (NumStores - 1 - i) : i;
14283 StoreSDNode *St = cast<StoreSDNode>(StoreNodes[Idx].MemNode);
14285 SDValue Val = St->getValue();
14287 StoreInt <<= ElementSizeBits;
14289 StoreInt |=
C->getAPIntValue()
14290 .zextOrTrunc(ElementSizeBits)
14291 .zextOrTrunc(SizeInBits);
14293 StoreInt |=
C->getValueAPF()
14295 .zextOrTrunc(ElementSizeBits)
14296 .zextOrTrunc(SizeInBits);
14306 StoredVal = DAG.
getConstant(StoreInt, DL, StoreTy);
14310 SDValue NewChain = getMergeStoreChains(StoreNodes, NumStores);
14319 EVT LegalizedStoredValTy =
14321 unsigned LegalizedStoreSize = LegalizedStoredValTy.
getSizeInBits();
14325 LegalizedStoredValTy);
14327 NewChain, DL, ExtendedStoreVal, FirstInChain->
getBasePtr(),
14334 for (
unsigned i = 0; i < NumStores; ++i)
14335 CombineTo(StoreNodes[i].MemNode, NewStore);
14337 AddToWorklist(NewChain.
getNode());
14341 void DAGCombiner::getStoreMergeCandidates(
14358 bool IsConstantSrc = isa<ConstantSDNode>(Val) || isa<ConstantFPSDNode>(Val);
14361 bool IsLoadSrc = isa<LoadSDNode>(Val);
14366 auto *Ld = cast<LoadSDNode>(Val);
14368 LoadVT = Ld->getMemoryVT();
14370 if (MemVT != LoadVT)
14373 if (!Ld->hasNUsesOfValue(1, 0))
14376 if (Ld->isVolatile() || Ld->isIndexed())
14380 int64_t &
Offset) ->
bool {
14391 if (
LoadSDNode *OtherLd = dyn_cast<LoadSDNode>(Val)) {
14393 if (LoadVT != OtherLd->getMemoryVT())
14396 if (!OtherLd->hasNUsesOfValue(1, 0))
14399 if (OtherLd->isVolatile() || OtherLd->isIndexed())
14401 if (!(LBasePtr.equalBaseIndex(LPtr, DAG)))
14406 if (IsConstantSrc) {
14409 if (!(isa<ConstantSDNode>(Val) || isa<ConstantFPSDNode>(Val)))
14412 if (IsExtractVecSrc) {
14444 if (
LoadSDNode *Ldn = dyn_cast<LoadSDNode>(RootNode)) {
14445 RootNode = Ldn->getChain().getNode();
14447 if (
I.getOperandNo() == 0 && isa<LoadSDNode>(*I))
14448 for (
auto I2 = (*I)->use_begin(), E2 = (*I)->use_end(); I2 != E2; ++I2)
14449 if (I2.getOperandNo() == 0)
14450 if (
StoreSDNode *OtherST = dyn_cast<StoreSDNode>(*I2)) {
14453 if (CandidateMatch(OtherST, Ptr, PtrDiff))
14454 StoreNodes.
push_back(MemOpLink(OtherST, PtrDiff));
14458 if (
I.getOperandNo() == 0)
14459 if (
StoreSDNode *OtherST = dyn_cast<StoreSDNode>(*
I)) {
14462 if (CandidateMatch(OtherST, Ptr, PtrDiff))
14463 StoreNodes.
push_back(MemOpLink(OtherST, PtrDiff));
14472 bool DAGCombiner::checkMergeStoreCandidatesForDependencies(
14488 while (!Worklist.
empty()) {
14490 if (!Visited.
insert(N).second)
14499 unsigned int Max = 1024 + Visited.
size();
14501 for (
unsigned i = 0; i < NumStores; ++i) {
14502 SDNode *N = StoreNodes[i].MemNode;
14518 for (
unsigned i = 0; i < NumStores; ++i)
14525 bool DAGCombiner::MergeConsecutiveStores(
StoreSDNode *St) {
14549 bool IsLoadSrc = isa<LoadSDNode>(StoredVal);
14550 bool IsConstantSrc = isa<ConstantSDNode>(StoredVal) ||
14551 isa<ConstantFPSDNode>(StoredVal);
14555 if (!IsConstantSrc && !IsLoadSrc && !IsExtractVecSrc)
14561 getStoreMergeCandidates(St, StoreNodes, RootNode);
14564 if (StoreNodes.
size() < 2)
14569 llvm::sort(StoreNodes, [](MemOpLink LHS, MemOpLink RHS) {
14570 return LHS.OffsetFromBase < RHS.OffsetFromBase;
14582 while (StoreNodes.
size() > 1) {
14583 unsigned StartIdx = 0;
14584 while ((StartIdx + 1 < StoreNodes.
size()) &&
14585 StoreNodes[StartIdx].OffsetFromBase + ElementSizeBytes !=
14586 StoreNodes[StartIdx + 1].OffsetFromBase)
14590 if (StartIdx + 1 >= StoreNodes.
size())
14598 unsigned NumConsecutiveStores = 1;
14599 int64_t StartAddress = StoreNodes[0].OffsetFromBase;
14602 for (
unsigned i = 1, e = StoreNodes.
size(); i < e; ++i) {
14603 int64_t CurrAddress = StoreNodes[i].OffsetFromBase;
14604 if (CurrAddress - StartAddress != (ElementSizeBytes * i))
14606 NumConsecutiveStores = i + 1;
14609 if (NumConsecutiveStores < 2) {
14611 StoreNodes.
begin() + NumConsecutiveStores);
14620 if (IsConstantSrc) {
14621 while (NumConsecutiveStores >= 2) {
14624 unsigned FirstStoreAlign = FirstInChain->
getAlignment();
14625 unsigned LastLegalType = 1;
14626 unsigned LastLegalVectorType = 1;
14627 bool LastIntegerTrunc =
false;
14628 bool NonZero =
false;
14629 unsigned FirstZeroAfterNonZero = NumConsecutiveStores;
14630 for (
unsigned i = 0; i < NumConsecutiveStores; ++i) {
14631 StoreSDNode *ST = cast<StoreSDNode>(StoreNodes[i].MemNode);
14633 bool IsElementZero =
false;
14635 IsElementZero =
C->isNullValue();
14637 IsElementZero =
C->getConstantFPValue()->isNullValue();
14638 if (IsElementZero) {
14639 if (NonZero && FirstZeroAfterNonZero == NumConsecutiveStores)
14640 FirstZeroAfterNonZero = i;
14642 NonZero |= !IsElementZero;
14645 unsigned SizeInBits = (i + 1) * ElementSizeBytes * 8;
14647 bool IsFast =
false;
14656 FirstStoreAlign, &IsFast) &&
14658 LastIntegerTrunc =
false;
14659 LastLegalType = i + 1;
14663 EVT LegalizedStoredValTy =
14668 FirstStoreAlign, &IsFast) &&
14670 LastIntegerTrunc =
true;
14671 LastLegalType = i + 1;
14682 unsigned Elts = (i + 1) * NumMemElts;
14687 FirstStoreAlign, &IsFast) &&
14689 LastLegalVectorType = i + 1;
14693 bool UseVector = (LastLegalVectorType > LastLegalType) && !NoVectors;
14694 unsigned NumElem = (UseVector) ? LastLegalVectorType : LastLegalType;
14706 unsigned NumSkip = 1;
14708 (NumSkip < NumConsecutiveStores) &&
14709 (NumSkip < FirstZeroAfterNonZero) &&
14710 (StoreNodes[NumSkip].MemNode->getAlignment() <= FirstStoreAlign))
14714 NumConsecutiveStores -= NumSkip;
14719 if (!checkMergeStoreCandidatesForDependencies(StoreNodes, NumElem,
14722 NumConsecutiveStores -= NumElem;
14726 RV |= MergeStoresOfConstantsOrVecElts(StoreNodes, MemVT, NumElem,
true,
14727 UseVector, LastIntegerTrunc);
14731 NumConsecutiveStores -= NumElem;
14738 if (IsExtractVecSrc) {
14740 while (NumConsecutiveStores >= 2) {
14743 unsigned FirstStoreAlign = FirstInChain->
getAlignment();
14744 unsigned NumStoresToMerge = 1;
14745 for (
unsigned i = 0; i < NumConsecutiveStores; ++i) {
14747 unsigned Elts = (i + 1) * NumMemElts;
14759 FirstStoreAlign, &IsFast) &&
14761 NumStoresToMerge = i + 1;
14766 if (NumStoresToMerge < 2) {
14773 unsigned NumSkip = 1;
14775 (NumSkip < NumConsecutiveStores) &&
14776 (StoreNodes[NumSkip].MemNode->getAlignment() <= FirstStoreAlign))
14780 NumConsecutiveStores -= NumSkip;
14785 if (!checkMergeStoreCandidatesForDependencies(
14786 StoreNodes, NumStoresToMerge, RootNode)) {
14788 StoreNodes.
begin() + NumStoresToMerge);
14789 NumConsecutiveStores -= NumStoresToMerge;
14793 RV |= MergeStoresOfConstantsOrVecElts(
14794 StoreNodes, MemVT, NumStoresToMerge,
false,
true,
false);
14797 StoreNodes.
begin() + NumStoresToMerge);
14798 NumConsecutiveStores -= NumStoresToMerge;
14814 for (
unsigned i = 0; i < NumConsecutiveStores; ++i) {
14815 StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
14821 int64_t LdOffset = 0;
14832 LoadNodes.
push_back(MemOpLink(Ld, LdOffset));
14835 while (NumConsecutiveStores >= 2 && LoadNodes.
size() >= 2) {
14838 unsigned RequiredAlignment;
14839 if (LoadNodes.
size() == 2 &&
14841 StoreNodes[0].MemNode->getAlignment() >= RequiredAlignment) {
14848 unsigned FirstStoreAlign = FirstInChain->
getAlignment();
14849 LoadSDNode *FirstLoad = cast<LoadSDNode>(LoadNodes[0].MemNode);
14857 unsigned LastConsecutiveLoad = 1;
14860 unsigned LastLegalVectorType = 1;
14861 unsigned LastLegalIntegerType = 1;
14862 bool isDereferenceable =
true;
14863 bool DoIntegerTruncate =
false;
14864 StartAddress = LoadNodes[0].OffsetFromBase;
14866 for (
unsigned i = 1; i < LoadNodes.
size(); ++i) {
14868 if (LoadNodes[i].MemNode->getChain() != FirstChain)
14871 int64_t CurrAddress = LoadNodes[i].OffsetFromBase;
14872 if (CurrAddress - StartAddress != (ElementSizeBytes * i))
14874 LastConsecutiveLoad = i;
14876 if (isDereferenceable && !LoadNodes[i].MemNode->isDereferenceable())
14877 isDereferenceable =
false;
14880 unsigned Elts = (i + 1) * NumMemElts;
14887 bool IsFastSt, IsFastLd;
14891 FirstStoreAlign, &IsFastSt) &&
14894 FirstLoadAlign, &IsFastLd) &&
14896 LastLegalVectorType = i + 1;
14900 unsigned SizeInBits = (i + 1) * ElementSizeBytes * 8;
14905 FirstStoreAlign, &IsFastSt) &&
14908 FirstLoadAlign, &IsFastLd) &&
14910 LastLegalIntegerType = i + 1;
14911 DoIntegerTruncate =
false;
14924 FirstStoreAlign, &IsFastSt) &&
14927 FirstLoadAlign, &IsFastLd) &&
14929 LastLegalIntegerType = i + 1;
14930 DoIntegerTruncate =
true;
14938 LastLegalVectorType > LastLegalIntegerType && !NoVectors;
14939 unsigned LastLegalType =
14940 std::max(LastLegalVectorType, LastLegalIntegerType);
14945 std::min(NumConsecutiveStores, LastConsecutiveLoad + 1);
14946 NumElem = std::min(LastLegalType, NumElem);
14956 unsigned NumSkip = 1;
14957 while ((NumSkip < LoadNodes.
size()) &&
14958 (LoadNodes[NumSkip].MemNode->getAlignment() <= FirstLoadAlign) &&
14959 (StoreNodes[NumSkip].MemNode->getAlignment() <= FirstStoreAlign))
14963 NumConsecutiveStores -= NumSkip;
14968 if (!checkMergeStoreCandidatesForDependencies(StoreNodes, NumElem,
14972 NumConsecutiveStores -= NumElem;
14981 unsigned Elts = NumElem * NumMemElts;
14984 unsigned SizeInBits = NumElem * ElementSizeBytes * 8;
14988 SDLoc LoadDL(LoadNodes[0].MemNode);
14989 SDLoc StoreDL(StoreNodes[0].MemNode);
14994 SDValue NewStoreChain = getMergeStoreChains(StoreNodes, NumElem);
14995 AddToWorklist(NewStoreChain.
getNode());
15002 if (UseVectorTy || !DoIntegerTruncate) {
15006 FirstLoadAlign, MMOFlags);
15008 NewStoreChain, StoreDL, NewLoad, FirstInChain->
getBasePtr(),
15016 FirstLoadAlign, MMOFlags);
15017 NewStore = DAG.
getTruncStore(NewStoreChain, StoreDL, NewLoad,
15025 for (
unsigned i = 0; i < NumElem; ++i) {
15026 LoadSDNode *Ld = cast<LoadSDNode>(LoadNodes[i].MemNode);
15033 for (
unsigned i = 0; i < NumElem; ++i) {
15034 SDValue Val = StoreNodes[i].MemNode->getOperand(1);
15035 CombineTo(StoreNodes[i].MemNode, NewStore);
15037 recursivelyDeleteUnusedNodes(Val.
getNode());
15043 NumConsecutiveStores -= NumElem;
15068 AddToWorklist(Token.
getNode());
15071 return CombineTo(ST, Token,
false);
15105 bitcastToAPInt().getZExtValue(),
SDLoc(CFP),
15118 return DAG.
getStore(Chain, DL, Tmp,
15141 Alignment =
MinAlign(Alignment, 4U);
15144 Alignment, MMOFlags, AAInfo);
15169 if (((!LegalOperations && !ST->
isVolatile()) ||
15205 if (
SDValue NewST = TransformFPLoadStorePair(N))
15211 if (findBetterNeighborChains(ST)) {
15222 (!isa<ConstantSDNode>(Value) ||
15223 !cast<ConstantSDNode>(Value)->isOpaque())) {
15230 AddToWorklist(Value.
getNode());
15237 if (SimplifyDemandedBits(
15253 if (
LoadSDNode *Ld = dyn_cast<LoadSDNode>(Value)) {
15254 if (Ld->getBasePtr() == Ptr && ST->
getMemoryVT() == Ld->getMemoryVT() &&
15258 Chain.reachesChainWithoutSideEffects(
SDValue(Ld, 1))) {
15264 if (
StoreSDNode *ST1 = dyn_cast<StoreSDNode>(Chain)) {
15266 !ST1->isVolatile() && ST1->getBasePtr() == Ptr &&
15270 if (ST1->getValue() == Value) {
15280 !ST1->getBasePtr().isUndef()) {
15283 CombineTo(ST1, ST1->getChain());
15307 bool Changed = MergeConsecutiveStores(ST);
15308 if (!Changed)
break;
15317 if (CombineToPreIndexedLoadStore(N) || CombineToPostIndexedLoadStore(N))
15325 if (isa<ConstantFPSDNode>(ST->
getValue())) {
15326 if (
SDValue NewSt = replaceStoreOfFPConstant(ST))
15333 return ReduceLoadOpStoreWidth(N);
15438 Alignment / 2, MMOFlags, AAInfo);
15447 SDValue DAGCombiner::combineInsertEltToShuffle(
SDNode *N,
unsigned InsIndex) {
15459 unsigned NumMaskVals = ExtendRatio * NumSrcElts;
15467 for (
unsigned i = 0; i != NumMaskVals; ++i) {
15468 if (i / NumSrcElts == InsIndex)
15469 Mask[i] = (i % NumSrcElts) + NumMaskVals;
15484 ConcatOps[0] = SubVec;
15490 AddToWorklist(PaddedSubV.
getNode());
15491 AddToWorklist(DestVecBC.
getNode());
15492 AddToWorklist(Shuf.
getNode());
15527 unsigned Elt = IndexC->getZExtValue();
15528 if (
SDValue Shuf = combineInsertEltToShuffle(N, Elt))
15539 && isa<ConstantSDNode>(InVec.getOperand(2))) {
15540 unsigned OtherElt = InVec.getConstantOperandVal(2);
15541 if (Elt < OtherElt) {
15544 InVec.getOperand(0), InVal, EltNo);
15545 AddToWorklist(NewOp.
getNode());
15562 Ops.
append(InVec.getNode()->op_begin(),
15563 InVec.getNode()->op_end());
15564 }
else if (InVec.isUndef()) {
15569 assert(Ops.
size() == NumElts &&
"Unexpected vector size");
15572 if (Elt < Ops.
size()) {
15575 EVT OpVT = Ops[0].getValueType();
15583 SDValue DAGCombiner::scalarizeExtractedVectorLoad(
SDNode *EVE,
EVT InVecVT,
15609 if (
auto *ConstEltNo = dyn_cast<ConstantSDNode>(EltNo)) {
15610 int Elt = ConstEltNo->getZExtValue();
15631 if (ResultVT.bitsGT(VecEltVT)) {
15639 OriginalLoad->
getChain(), NewPtr, MPI, VecEltVT,
15648 if (ResultVT.bitsLT(VecEltVT))
15653 WorklistRemover DeadNodes(*
this);
15659 AddToWorklist(Load.
getNode());
15660 AddUsersToWorklist(Load.
getNode());
15662 AddToWorklist(EVE);
15670 bool LegalOperations) {
15736 if (IndexC && IndexC->getAPIntValue().uge(NumElts))
15747 if (ScalarVT == InEltVT)
15761 unsigned ExtractIndex = IndexC->getZExtValue();
15763 unsigned BCTruncElt = IsLE ? 0 : NumElts - 1;
15774 "Extract element and scalar to vector can't change element type " 15775 "from FP to integer.");
15778 BCTruncElt = IsLE ? 0 : XBitWidth / VecEltBitWidth - 1;
15783 if (ExtractIndex == BCTruncElt && XBitWidth > VecEltBitWidth) {
15784 assert(XBitWidth % VecEltBitWidth == 0 &&
15785 "Scalar bitwidth must be a multiple of vector element bitwidth");
15801 auto *Shuf = cast<ShuffleVectorSDNode>(VecOp);
15803 int OrigElt = Shuf->getMaskElt(IndexC->getZExtValue());
15811 if (OrigElt < (
int)NumElts) {
15815 OrigElt -= NumElts;
15831 if (!LegalOperations ||
15845 Use->getOperand(0) == VecOp &&
15846 isa<ConstantSDNode>(
Use->getOperand(1));
15850 auto *CstElt = cast<ConstantSDNode>(
Use->getOperand(1));
15851 if (CstElt->getAPIntValue().ult(NumElts))
15852 DemandedElts.
setBit(CstElt->getZExtValue());
15854 if (SimplifyDemandedVectorElts(VecOp, DemandedElts,
true)) {
15866 bool BCNumEltsChanged =
false;
15881 BCNumEltsChanged =
true;
15887 if (!LegalOperations && !IndexC && VecOp.
hasOneUse() &&
15889 !Index->hasPredecessor(VecOp.
getNode())) {
15892 return scalarizeExtractedVectorLoad(N, VecVT, Index,
VecLoad);
15897 if (!LegalOperations || !IndexC)
15903 int Elt = IndexC->getZExtValue();
15906 LN0 = cast<LoadSDNode>(VecOp);
15914 LN0 = cast<LoadSDNode>(VecOp.
getOperand(0));
15916 if (
auto *Shuf = dyn_cast<ShuffleVectorSDNode>(VecOp)) {
15927 if (BCNumEltsChanged)
15931 int Idx = (Elt > (int)NumElts) ? -1 : Shuf->getMaskElt(Elt);
15942 LN0 = cast<LoadSDNode>(VecOp);
15943 Elt = (Idx < (int)NumElts) ? Idx : Idx - (int)NumElts;
15944 Index = DAG.
getConstant(Elt, DL, Index.getValueType());
15957 return scalarizeExtractedVectorLoad(N, VecVT, Index, LN0);
15961 SDValue DAGCombiner::reduceBuildVecExtToExtBuildVec(
SDNode *N) {
15981 bool AllAnyExt =
true;
15983 for (
unsigned i = 0; i != NumInScalars; ++i) {
15992 if (!ZeroExt && !AnyExt) {
16004 else if (InTy != SourceType) {
16011 AllAnyExt &= AnyExt;
16018 bool ValidTypes = SourceType !=
MVT::Other &&
16029 assert(ElemRatio > 1 &&
"Invalid element size ratio");
16041 Cast.
isUndef()) &&
"Invalid cast opcode");
16047 unsigned Index = isLE ? (i * ElemRatio) :
16048 (i * ElemRatio + (ElemRatio - 1));
16050 assert(Index < Ops.
size() &&
"Invalid index");
16057 "Invalid vector size");
16059 if (!isTypeLegal(VecVT) ||
16076 unsigned LeftIdx) {
16084 unsigned Vec2Offset = 0;
16086 unsigned ShuffleNumElems = NumElems;
16098 if (InVT1 != VT || InVT2 != VT) {
16103 assert(NumConcats >= 2 &&
"Concat needs at least two inputs!");
16105 ConcatOps[0] = VecIn1;
16106 ConcatOps[1] = VecIn2 ? VecIn2 : DAG.
getUNDEF(InVT1);
16121 Vec2Offset = NumElems;
16127 if (LegalOperations &&
16134 if (InVT1 != InVT2) {
16138 DAG.
getUNDEF(InVT1), VecIn2, ZeroIdx);
16140 ShuffleNumElems = NumElems * 2;
16150 ConcatOps[0] = VecIn2;
16167 for (
unsigned i = 0; i != NumElems; ++i) {
16168 if (VectorMask[i] <= 0)
16172 if (VectorMask[i] == (
int)LeftIdx) {
16173 Mask[i] = ExtIndex;
16174 }
else if (VectorMask[i] == (
int)LeftIdx + 1) {
16175 Mask[i] = Vec2Offset + ExtIndex;
16188 if (ShuffleNumElems > NumElems)
16201 for (
int i = 0; i != NumBVOps; ++i) {
16233 if (DestSize % SrcSize != 0 ||
16239 int ZextRatio = DestSize / SrcSize;
16240 int NumMaskElts = NumBVOps * ZextRatio;
16242 for (
int i = 0; i != NumMaskElts; ++i) {
16243 if (i / ZextRatio == ZextElt) {
16248 if (i % ZextRatio == 0)
16251 ShufMask[i] = NumMaskElts;
16280 if (!isTypeLegal(VT))
16290 bool UsesZeroVector =
false;
16303 for (
unsigned i = 0; i != NumElems; ++i) {
16313 UsesZeroVector =
true;
16325 APInt ExtractIdx = cast<ConstantSDNode>(Op.
getOperand(1))->getAPIntValue();
16337 unsigned Idx = std::distance(
16339 if (Idx == VecIn.
size())
16342 VectorMask[i] = Idx;
16346 if (VecIn.
size() < 2)
16353 if (VecIn.
size() == 2) {
16354 unsigned MaxIndex = 0;
16355 unsigned NearestPow2 = 0;
16361 for (
unsigned i = 0; i < NumElems; i++) {
16362 if (VectorMask[i] <= 0)
16365 IndexVec[i] =
Index;
16366 MaxIndex =
std::max(MaxIndex, Index);
16370 if (InVT.
isSimple() && NearestPow2 > 2 && MaxIndex < NearestPow2 &&
16371 NumElems * 2 < NearestPow2) {
16372 unsigned SplitSize = NearestPow2 / 2;
16384 for (
unsigned i = 0; i < NumElems; i++) {
16385 if (VectorMask[i] <= 0)
16387 VectorMask[i] = (IndexVec[i] < SplitSize) ? 1 : 2;
16413 for (
unsigned In = 0, Len = (VecIn.
size() / 2);
In < Len; ++
In) {
16414 unsigned LeftIdx = 2 *
In + 1;
16415 SDValue VecLeft = VecIn[LeftIdx];
16417 (LeftIdx + 1) < VecIn.
size() ? VecIn[LeftIdx + 1] :
SDValue();
16419 if (
SDValue Shuffle = createBuildVecShuffle(DL, N, VectorMask, VecLeft,
16420 VecRight, LeftIdx))
16428 if (UsesZeroVector)
16433 if (Shuffles.
size() == 1)
16434 return Shuffles[0];
16437 for (
int &Vec : VectorMask)
16439 Vec = Shuffles.
size() - 1;
16441 Vec = (Vec - 1) / 2;
16455 if (Shuffles.
size() % 2)
16458 for (
unsigned CurSize = Shuffles.
size(); CurSize > 1; CurSize /= 2) {
16460 Shuffles[CurSize] = DAG.
getUNDEF(VT);
16463 for (
unsigned In = 0, Len = CurSize / 2;
In < Len; ++
In) {
16467 for (
unsigned i = 0; i != NumElems; ++i) {
16468 if (VectorMask[i] == Left) {
16470 VectorMask[i] =
In;
16471 }
else if (VectorMask[i] == Right) {
16472 Mask[i] = i + NumElems;
16473 VectorMask[i] =
In;
16481 return Shuffles[0];
16489 SDValue DAGCombiner::convertBuildVecZextToZext(
SDNode *N) {
16490 if (LegalOperations)
16496 auto checkElem = [&](
SDValue Op) -> int64_t {
16501 return C->getZExtValue();
16507 int64_t
Offset = checkElem(Op0);
16521 for (
unsigned i = 1; i != NumElems; ++i) {
16522 if ((Offset + i) != checkElem(N->
getOperand(i)))
16547 if (!LegalOperations) {
16550 EVT SrcVT = Splat.getValueType();
16568 auto checkElem = [&](
SDValue Op) -> uint64_t {
16571 if (
auto CNode = dyn_cast<ConstantSDNode>(Op.
getOperand(1)))
16572 return CNode->getZExtValue();
16576 int Offset = checkElem(Op0);
16578 if (Offset + i != checkElem(N->
getOperand(i))) {
16584 if ((Offset == 0) &&
16587 if ((Offset != -1) &&
16594 if (
SDValue V = convertBuildVecZextToZext(N))
16597 if (
SDValue V = reduceBuildVecExtToExtBuildVec(N))
16600 if (
SDValue V = reduceBuildVecToShuffle(N))
16622 bool AnyInteger =
false;
16623 bool AnyFP =
false;
16685 Mask.
append((
unsigned)NumOpElts, -1);
16702 Mask.
append((
unsigned)NumOpElts, -1);
16717 if (0 == (NumExtElts % NumElts))
16718 ExtIdx /= (NumExtElts / NumElts);
16719 else if (0 == (NumElts % NumExtElts))
16720 ExtIdx *= (NumElts / NumExtElts);
16725 if (SV0.
isUndef() || SV0 == ExtVec) {
16727 for (
int i = 0; i != NumOpElts; ++i)
16729 }
else if (SV1.isUndef() || SV1 == ExtVec) {
16731 for (
int i = 0; i != NumOpElts; ++i)
16767 Scalar.hasOneUse()) {
16769 if (SVT == Scalar.getOperand(0).getValueType())
16770 Scalar = Scalar.getOperand(0);
16774 if (!Scalar.getValueType().isVector()) {
16780 TLI.
isTypeLegal(Scalar->getOperand(0).getValueType()))
16781 Scalar = Scalar->getOperand(0);
16783 EVT SclTy = Scalar.getValueType();
16793 if (VNTNumElms < 2)
16809 auto IsBuildVectorOrUndef = [](
const SDValue &
Op) {
16820 bool FoundMinVT =
false;
16824 MinVT = (!FoundMinVT || OpSVT.
bitsLE(MinVT)) ? OpSVT : MinVT;
16827 assert(FoundMinVT &&
"Concat vector type mismatch");
16842 for (
unsigned i = 0; i != NumElts; ++i)
16850 "Concat vector type mismatch");
16881 if (SingleSource.
getNode()) {
16894 unsigned IdentityIndex = i * PartNumElem;
16906 return SingleSource;
16919 if (!ExtractIndexC)
16934 unsigned ExtractIndex = ExtractIndexC->getZExtValue();
16936 "Extract index is not a multiple of the vector length.");
16941 if (WideWidth % NarrowWidth != 0)
16946 unsigned NarrowingRatio = WideWidth / NarrowWidth;
16948 if (WideNumElts % NarrowingRatio != 0)
16953 WideNumElts / NarrowingRatio);
16982 if (NarrowingRatio != 2)
17002 if (!ConcatL && !ConcatR)
17022 SDValue NarrowBinOp = DAG.
getNode(BOpcode, DL, NarrowBVT, X, Y);
17036 if (!Ld || Ld->getExtensionType() || Ld->isVolatile() || !ExtIdx)
17056 SDValue NewLd = DAG.
getLoad(VT, DL, Ld->getChain(), NewAddr, MMO);
17084 assert((Idx % NumElems) == 0 &&
17085 "IDX in concat is not a multiple of the result vector length.");
17093 if (
auto *Idx = dyn_cast<ConstantSDNode>(N->
getOperand(1))) {
17098 if (ExtractSize % EltSize == 0) {
17099 unsigned NumElems = ExtractSize / EltSize;
17101 EVT ExtractVT = NumElems == 1 ? EltVT :
17109 if (NumElems == 1) {
17131 if (!NVT.
bitsEq(SmallVT))
17138 if (InsIdx && ExtIdx) {
17157 if (SimplifyDemandedVectorElts(
SDValue(N, 0)))
17176 unsigned NumConcats = NumElts / NumElemsPerConcat;
17181 if (NumElemsPerConcat * 2 == NumElts && N1.
isUndef() &&
17183 SVN->
getMask().end(), [](
int i) {
return i == -1; })) {
17192 for (
unsigned I = 0;
I != NumConcats; ++
I) {
17194 unsigned Begin =
I * NumElemsPerConcat;
17195 bool AllUndef =
true, NoUndef =
true;
17196 for (
unsigned J = Begin; J != Begin + NumElemsPerConcat; ++J) {
17204 if (SVN->
getMaskElt(Begin) % NumElemsPerConcat != 0)
17207 for (
unsigned J = 1; J != NumElemsPerConcat; ++J)
17211 unsigned FirstElt = SVN->
getMaskElt(Begin) / NumElemsPerConcat;
17217 }
else if (AllUndef) {
17270 bool IsSplat =
false;
17274 if (
SDValue Splat0 = BV0->getSplatValue())
17275 IsSplat = (Splat0 == BV1->getSplatValue());
17279 for (
int M : SVN->
getMask()) {
17282 int Idx = M < (int)NumElts ? M : M - NumElts;
17283 SDValue &S = (M < (int)NumElts ? N0 : N1);
17287 assert(Idx == 0 &&
"Unexpected SCALAR_TO_VECTOR operand index.");
17299 if (!Op.
isUndef() && !isa<ConstantSDNode>(
Op) && !isa<ConstantFPSDNode>(Op))
17300 if (!IsSplat && !DuplicateOps.
insert(Op).second)
17327 bool LegalOperations) {
17341 auto isAnyExtend = [&
Mask, &NumElts](
unsigned Scale) {
17342 for (
unsigned i = 0; i != NumElts; ++i) {
17345 if ((i % Scale) == 0 && Mask[i] == (int)(i / Scale))
17354 for (
unsigned Scale = 2; Scale < NumElts; Scale *= 2) {
17356 if (NumElts % Scale != 0)
17358 if (!isAnyExtend(Scale))
17366 if (!LegalOperations ||
17370 SDLoc(SVN), OutVT, N0));
17405 if (ExtDstSizeInBits % ExtSrcSizeInBits != 0)
17407 unsigned ExtScale = ExtDstSizeInBits / ExtSrcSizeInBits;
17412 auto isTruncate = [&
Mask, &NumElts](
unsigned Scale) {
17413 for (
unsigned i = 0; i != NumElts; ++i) {
17416 if ((i * Scale) < NumElts && Mask[i] == (int)(i * Scale))
17426 if (EltSizeInBits != ExtSrcSizeInBits)
17431 if (isTruncate(ExtScale))
17446 assert(UserMask.
size() == SplatMask.
size() &&
"Mask length mismatch");
17464 auto CanSimplifyToExistingSplat = [](
ArrayRef<int> UserMask,
17466 for (
unsigned i = 0, e = UserMask.
size(); i != e; ++i)
17467 if (UserMask[i] != -1 && SplatMask[i] == -1 &&
17468 SplatMask[UserMask[i]] != -1)
17472 if (CanSimplifyToExistingSplat(UserMask, SplatMask))
17478 for (
int Idx : UserMask)
17479 NewMask.
push_back(Idx == -1 ? -1 : SplatMask[Idx]);
17491 int MaskSize = Mask.
size();
17492 int EltFromOp0 = -1;
17497 for (
int i = 0; i != MaskSize; ++i) {
17498 if (Mask[i] >= 0 && Mask[i] < MaskSize) {
17500 if (EltFromOp0 != -1)
17503 }
else if (Mask[i] != i + MaskSize) {
17523 if (ShufOp0Index == -1) {
17527 if (ShufOp0Index == -1)
17531 Mask = CommutedMask;
17539 assert(Mask[ShufOp0Index] >= 0 && Mask[ShufOp0Index] < (
int)Mask.
size() &&
17540 "Shuffle mask value must be from operand 0");
17545 if (!InsIndexC || InsIndexC->getSExtValue() != Mask[ShufOp0Index])
17559 Op0.getOperand(2).getValueType());
17561 Op1, Op0.getOperand(1), NewInsIndex);
17582 for (
unsigned i = 0; i != NumElts; ++i) {
17584 if (Idx >= (
int)NumElts) Idx -= NumElts;
17596 bool Changed =
false;
17598 for (
unsigned i = 0; i != NumElts; ++i) {
17600 if (Idx >= (
int)NumElts) {
17614 if (
auto *N0Shuf = dyn_cast<ShuffleVectorSDNode>(N0))
17615 if (N1->
isUndef() && N0Shuf->isSplat())
17635 "BUILD_VECTOR has wrong number of operands");
17637 bool AllSame =
true;
17638 for (
unsigned i = 0; i != NumElts; ++i) {
17645 if (!Base.getNode())
17647 for (
unsigned i = 0; i != NumElts; ++i) {
17671 if (SimplifyDemandedVectorElts(
SDValue(N, 0)))
17709 for (
int s = 0; s != Scale; ++s)
17710 NewMask.
push_back(M < 0 ? -1 : Scale * M + s);
17721 EVT ScaleVT = SVT.
bitsLT(InnerSVT) ? VT : InnerVT;
17733 ScaleShuffleMask(InnerSVN->
getMask(), InnerScale);
17735 ScaleShuffleMask(SVN->
getMask(), OuterScale);
17739 for (
int M : OuterMask)
17740 NewMask.
push_back(M < 0 ? -1 : InnerMask[M]);
17772 "Shuffle types don't match");
17776 bool HasSameOp0 = N0 == SV0;
17777 bool IsSV1Undef = SV1.
isUndef();
17778 if (HasSameOp0 || IsSV1Undef || N0 == SV1)
17802 "Shuffle types don't match");
17808 for (
unsigned i = 0; i != NumElts; ++i) {
17817 if (Idx < (
int)NumElts) {
17827 CurrentVec = (Idx < (int) NumElts) ? OtherSV->
getOperand(0)
17842 Idx = Idx % NumElts;
17843 if (!SV0.getNode() || SV0 == CurrentVec) {
17852 if (SV1.getNode() && SV1 != CurrentVec)
17862 bool isUndefMask =
true;
17863 for (
unsigned i = 0; i != NumElts && isUndefMask; ++i)
17864 isUndefMask &= Mask[i] < 0;
17869 if (!SV0.getNode())
17871 if (!SV1.getNode())
17908 int Elt = C0->getZExtValue();
18012 if (!isa<ConstantSDNode>(N2))
18015 unsigned InsIdx = cast<ConstantSDNode>(N2)->getZExtValue();
18025 if (InsIdx < OtherIdx) {
18029 AddToWorklist(NewOp.
getNode());
18042 Ops[cast<ConstantSDNode>(N2)->getZExtValue() / Factor] = N1;
18048 if (SimplifyDemandedVectorElts(
SDValue(N, 0)))
18093 if (LegalOperations)
18105 auto BuildClearMask = [&](
int Split) {
18106 int NumSubElts = NumElts *
Split;
18110 for (
int i = 0; i != NumSubElts; ++i) {
18111 int EltIdx = i /
Split;
18112 int SubIdx = i %
Split;
18120 if (isa<ConstantSDNode>(Elt))
18121 Bits = cast<ConstantSDNode>(Elt)->getAPIntValue();
18122 else if (isa<ConstantFPSDNode>(Elt))
18123 Bits = cast<ConstantFPSDNode>(Elt)->getValueAPF().bitcastToAPInt();
18129 Bits.
lshrInPlace((Split - SubIdx - 1) * NumSubBits);
18135 Bits = Bits.
trunc(NumSubBits);
18139 else if (Bits == 0)
18173 "SimplifyVBinOp only works on vectors!");
18187 if (LegalTypes && isa<ShuffleVectorSDNode>(LHS) &&
18188 isa<ShuffleVectorSDNode>(RHS) && LHS.hasOneUse() && RHS.hasOneUse() &&
18189 LHS.getOperand(1).isUndef() &&
18190 RHS.getOperand(1).isUndef()) {
18194 if (SVN0->
getMask().equals(SVN1->getMask())) {
18198 LHS.getOperand(0), RHS.getOperand(0),
18200 AddUsersToWorklist(N);
18214 cast<CondCodeSDNode>(N0.
getOperand(2))->
get());
18219 if (SCC.getNode()) {
18225 SCC.getOperand(0), SCC.getOperand(1),
18226 SCC.getOperand(4));
18227 AddToWorklist(SETCC.
getNode());
18229 SCC.getOperand(2), SCC.getOperand(3));
18242 bool DAGCombiner::SimplifySelectOps(
SDNode *TheSelect,
SDValue LHS,
18255 CC = cast<CondCodeSDNode>(TheSelect->
getOperand(4))->
get();
18262 CC = cast<CondCodeSDNode>(Cmp.
getOperand(2))->
get();
18267 if (Zero && Zero->
isZero() &&
18271 CombineTo(TheSelect, Sqrt);
18299 LLD->
isIndexed() || RLD->isIndexed() ||
18313 RLD->getPointerInfo().getAddrSpace() != 0 ||
18332 Visited.
insert(TheSelect);
18352 (RLD->hasAnyUseOfValue(1) &&
18359 RLD->getBasePtr());
18374 (RLD->hasAnyUseOfValue(1) &&
18390 unsigned Alignment = std::min(LLD->
getAlignment(), RLD->getAlignment());
18392 if (!RLD->isInvariant())
18394 if (!RLD->isDereferenceable())
18411 CombineTo(TheSelect, Load);
18458 if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue() - 1)) == 0)) {
18459 unsigned ShCt = XType.
getSizeInBits() - N2C->getAPIntValue().logBase2() - 1;
18462 AddToWorklist(Shift.
getNode());
18464 if (XType.
bitsGT(AType)) {
18466 AddToWorklist(Shift.
getNode());
18470 Shift = DAG.
getNOT(DL, Shift, AType);
18477 AddToWorklist(Shift.
getNode());
18479 if (XType.
bitsGT(AType)) {
18481 AddToWorklist(Shift.
getNode());
18485 Shift = DAG.
getNOT(DL, Shift, AType);
18494 SDValue DAGCombiner::convertSelectOfFPConstantsToLoadOffset(
18510 TLI.
isFPImmLegal(TV->getValueAPF(), TV->getValueType(0)) ||
18511 TLI.
isFPImmLegal(FV->getValueAPF(), FV->getValueType(0)))
18516 if (!TV->hasOneUse() && !FV->hasOneUse())
18520 const_cast<ConstantFP*>(TV->getConstantFPValue()) };
18528 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
18537 AddToWorklist(Cond.
getNode());
18539 AddToWorklist(CstOffset.getNode());
18540 CPIdx = DAG.
getNode(
ISD::ADD, DL, CPIdx.getValueType(), CPIdx, CstOffset);
18541 AddToWorklist(CPIdx.getNode());
18551 bool NotExtCompare) {
18553 if (N2 == N3)
return N2;
18562 SDValue SCC = SimplifySetCC(getSetCCResultType(CmpOpVT), N0, N1, CC, DL,
18564 if (SCC.getNode()) AddToWorklist(SCC.getNode());
18566 if (
auto *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.getNode())) {
18569 return !SCCC->isNullValue() ? N2 : N3;
18573 convertSelectOfFPConstantsToLoadOffset(DL, N0, N1, N2, N3, CC))
18576 if (
SDValue V = foldSelectCCToShiftAnd(DL, N0, N1, N2, N3, CC))
18589 if (ConstAndRHS && ConstAndRHS->getAPIntValue().countPopulation() == 1) {
18591 const APInt &AndMask = ConstAndRHS->getAPIntValue();
18609 bool Fold = N2C &&
isNullConstant(N3) && N2C->getAPIntValue().isPowerOf2();
18610 bool Swap = N3C &&
isNullConstant(N2) && N3C->getAPIntValue().isPowerOf2();
18612 if ((Fold || Swap) &&
18624 if (NotExtCompare && N2C->isOne())
18630 SCC = DAG.
getSetCC(DL, getSetCCResultType(CmpOpVT), N0, N1, CC);
18640 AddToWorklist(SCC.
getNode());
18641 AddToWorklist(Temp.
getNode());
18662 (N1C->isAllOnesValue() && CC ==
ISD::SETGT)) &&
18664 SubC = dyn_cast<ConstantSDNode>(N3.
getOperand(0));
18668 SubC = dyn_cast<ConstantSDNode>(N2.
getOperand(0));
18675 getShiftAmountTy(CmpOpVT)));
18677 AddToWorklist(Shift.
getNode());
18678 AddToWorklist(Add.
getNode());
18698 if (
auto *ValueOnZeroC = dyn_cast<ConstantSDNode>(ValueOnZero)) {
18724 bool foldBooleans) {
18726 DagCombineInfo(DAG, Level,
false,
this);
18727 return TLI.
SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo, DL);
18820 if (Enabled == TLI.ReciprocalEstimate::Disabled)
18827 AddToWorklist(Est.getNode());
18835 for (
int i = 0; i < Iterations; ++i) {
18837 AddToWorklist(NewEst.
getNode());
18840 AddToWorklist(NewEst.getNode());
18843 AddToWorklist(NewEst.getNode());
18846 AddToWorklist(Est.getNode());
18862 unsigned Iterations,
18871 AddToWorklist(HalfArg.
getNode());
18874 AddToWorklist(HalfArg.getNode());
18877 for (
unsigned i = 0; i < Iterations; ++i) {
18879 AddToWorklist(NewEst.
getNode());
18882 AddToWorklist(NewEst.getNode());
18885 AddToWorklist(NewEst.getNode());
18888 AddToWorklist(Est.getNode());
18894 AddToWorklist(Est.
getNode());
18906 unsigned Iterations,
18919 for (
unsigned i = 0; i < Iterations; ++i) {
18924 AddToWorklist(AEE.getNode());
18927 AddToWorklist(RHS.getNode());
18933 if (Reciprocal || (i + 1) < Iterations) {
18940 AddToWorklist(LHS.getNode());
18943 AddToWorklist(Est.getNode());
18965 if (Enabled == TLI.ReciprocalEstimate::Disabled)
18972 bool UseOneConstNR =
false;
18976 AddToWorklist(Est.
getNode());
18979 Est = UseOneConstNR
18980 ? buildSqrtNROneConst(Op, Est, Iterations, Flags, Reciprocal)
18981 : buildSqrtNRTwoConst(Op, Est, Iterations, Flags, Reciprocal);
18988 EVT CCVT = getSetCCResultType(VT);
19000 Est = DAG.
getNode(SelOpcode, DL, VT, IsDenorm, FPZero, Est);
19001 AddToWorklist(Fabs.
getNode());
19002 AddToWorklist(IsDenorm.
getNode());
19003 AddToWorklist(Est.
getNode());
19008 Est = DAG.
getNode(SelOpcode, DL, VT, IsZero, FPZero, Est);
19009 AddToWorklist(IsZero.
getNode());
19010 AddToWorklist(Est.
getNode());
19021 return buildSqrtEstimateImpl(Op, Flags,
true);
19025 return buildSqrtEstimateImpl(Op, Flags,
false);
19054 return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0));
19060 if (
auto *A = dyn_cast<FrameIndexSDNode>(BasePtr0.
getBase()))
19061 if (
auto *
B = dyn_cast<FrameIndexSDNode>(BasePtr1.
getBase())) {
19070 bool IsFI0 = isa<FrameIndexSDNode>(BasePtr0.
getBase());
19071 bool IsFI1 = isa<FrameIndexSDNode>(BasePtr1.
getBase());
19072 bool IsGV0 = isa<GlobalAddressSDNode>(BasePtr0.
getBase());
19073 bool IsGV1 = isa<GlobalAddressSDNode>(BasePtr1.
getBase());
19074 bool IsCV0 = isa<ConstantPoolSDNode>(BasePtr0.
getBase());
19075 bool IsCV1 = isa<ConstantPoolSDNode>(BasePtr1.
getBase());
19080 (IsGV0 != IsGV1) || (IsCV0 != IsCV1)) &&
19081 (IsFI0 || IsGV0 || IsCV0) && (IsFI1 || IsGV1 || IsCV1))
19093 if (OrigAlignment0 == OrigAlignment1 && SrcValOffset0 != SrcValOffset1 &&
19094 NumBytes0 == NumBytes1 && OrigAlignment0 > NumBytes0) {
19095 int64_t OffAlign0 = SrcValOffset0 % OrigAlignment0;
19096 int64_t OffAlign1 = SrcValOffset1 % OrigAlignment1;
19100 if ((OffAlign0 + NumBytes0) <= OffAlign1 ||
19101 (OffAlign1 + NumBytes1) <= OffAlign0)
19117 int64_t MinOffset = std::min(SrcValOffset0, SrcValOffset1);
19118 int64_t Overlap0 = NumBytes0 + SrcValOffset0 - MinOffset;
19119 int64_t Overlap1 = NumBytes1 + SrcValOffset1 - MinOffset;
19135 void DAGCombiner::GatherAllAliases(
SDNode *N,
SDValue OriginalChain,
19141 bool IsLoad = isa<LoadSDNode>(
N) && !cast<LSBaseSDNode>(N)->isVolatile();
19145 unsigned Depth = 0;
19150 while (!Chains.
empty()) {
19177 bool IsOpLoad = isa<LoadSDNode>(Chain.
getNode()) &&
19181 if (!(IsLoad && IsOpLoad) &&
19182 isAlias(cast<LSBaseSDNode>(N), cast<LSBaseSDNode>(Chain.
getNode()))) {
19230 GatherAllAliases(N, OldChain, Aliases);
19233 if (Aliases.
size() == 0)
19237 if (Aliases.
size() == 1)
19262 bool DAGCombiner::parallelizeChainedStores(
StoreSDNode *St) {
19293 if (Chain->isVolatile() || Chain->isIndexed())
19302 int64_t Length = (Chain->getMemoryVT().getSizeInBits() + 7) / 8;
19305 auto I = Intervals.find(Offset);
19307 if (
I != Intervals.end() &&
I.start() < (Offset + Length))
19310 if (
I != Intervals.begin() && (--
I).stop() <=
Offset)
19312 Intervals.insert(Offset, Offset + Length,
Unit);
19319 if (ChainedStores.
size() == 0)
19326 for (
unsigned I = ChainedStores.
size();
I;) {
19328 SDValue BetterChain = FindBetterChain(S, NewChain);
19332 ChainedStores[
I] = S;
19336 SDValue BetterChain = FindBetterChain(St, NewChain);
19351 auto hasImprovedChain = [&](
SDValue ST) ->
bool {
19354 bool AddNewChain =
llvm::all_of(TFOps, hasImprovedChain);
19361 AddToWorklist(STChain);
19369 bool DAGCombiner::findBetterNeighborChains(
StoreSDNode *St) {
19384 if (parallelizeChainedStores(St))
19389 if (St->
getChain() != BetterChain) {
19390 replaceStoreChain(St, BetterChain);
19400 DAGCombiner(*
this, AA, OptLevel).Run(Level);
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
bool LegalizeOp(SDNode *N, SmallSetVector< SDNode *, 16 > &UpdatedNodes)
Transforms a SelectionDAG node and any operands to it into a node that is compatible with the target ...
APInt abs() const
Get the absolute value;.
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B, const MVT::SimpleValueType SVT=MVT::SimpleValueType::Any) const
Find the largest common subclass of A and B.
static bool isBSwapHWordElement(SDValue N, MutableArrayRef< SDNode *> Parts)
Return true if the specified node is an element that makes up a 32-bit packed halfword byteswap...
SDValue getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, bool isTargetGA=false, unsigned char TargetFlags=0)
static MVT getIntegerVT(unsigned BitWidth)
std::string & operator+=(std::string &buffer, StringRef string)
BUILTIN_OP_END - This must be the last enum value in this list.
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
EVT getValueType() const
Return the ValueType of the referenced return value.
static SDValue FoldIntToFPToInt(SDNode *N, SelectionDAG &DAG)
static void commuteMask(MutableArrayRef< int > Mask)
Change values in a shuffle permute mask assuming the two vector operands have swapped position...
bool isShiftedMask() const
Return true if this APInt value contains a sequence of ones with the remainder zero.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const SDValue & getOffset() const
iterator_range< use_iterator > uses()
static SDValue tryToFoldExtendOfConstant(SDNode *N, const TargetLowering &TLI, SelectionDAG &DAG, bool LegalTypes)
Try to fold a sext/zext/aext dag node into a ConstantSDNode or a build_vector of constants.
static SDValue foldAddSubBoolOfMaskedVal(SDNode *N, SelectionDAG &DAG)
virtual bool canMergeStoresTo(unsigned AS, EVT MemVT, const SelectionDAG &DAG) const
Returns if it's reasonable to merge stores to MemVT size.
static bool isConstant(const MachineInstr &MI)
bool hasNoSignedZeros() const
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant, which is required to be operand #1) half of the integer or float value specified as operand #0.
uint64_t getZExtValue() const
Get zero extended value.
APInt sext(unsigned width) const
Sign extend to a new width.
static bool areSlicesNextToEachOther(const LoadedSlice &First, const LoadedSlice &Second)
Check whether or not First and Second are next to each other in memory.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
const TargetLibraryInfo & getLibInfo() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef...
DiagnosticInfoOptimizationBase::Argument NV
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
typename SuperClass::const_iterator const_iterator
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
SDValue getIndexedLoad(SDValue OrigLoad, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM)
DELETED_NODE - This is an illegal value that is used to catch errors.
LLVM_NODISCARD T pop_back_val()
virtual bool isFPImmLegal(const APFloat &, EVT) const
Returns true if the target can instruction select the specified FP immediate natively.
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
BR_CC - Conditional branch.
This class represents lattice values for constants.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not...
size_type size() const
Determine the number of elements in the SetVector.
SDValue simplifyShift(SDValue X, SDValue Y)
Try to simplify a shift into 1 of its operands or a constant.
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0...
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
static SDValue foldAddSubOfSignBit(SDNode *N, SelectionDAG &DAG)
Try to fold a 'not' shifted sign-bit with add/sub with constant operand into a shift and add with a d...
virtual bool reduceSelectOfFPConstantLoads(bool IsFPSetCC) const
Return true if it is profitable to convert a select of FP constants into a constant pool load whose a...
int getSplatIndex() const
static SDValue simplifyDivRem(SDNode *N, SelectionDAG &DAG)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
const Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
bool isNullOrNullSplat(SDValue V)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
static uint64_t * getMemory(unsigned numWords)
A utility function for allocating memory and checking for allocation failure.
const SDValue & getBasePtr() const
bool isNegative() const
Return true if the value is negative.
Carry-setting nodes for multiple precision addition and subtraction.
static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op, KnownBits &Known)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void push_back(const T &Elt)
static SDValue combineShuffleOfScalars(ShuffleVectorSDNode *SVN, SelectionDAG &DAG, const TargetLowering &TLI)
Clients of various APIs that cause global effects on the DAG can optionally implement this interface...
SDValue makeEquivalentMemoryOrdering(LoadSDNode *Old, SDValue New)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
APInt zext(unsigned width) const
Zero extend to a new width.
bool operator>(int64_t V1, const APSInt &V2)
virtual bool enableAggressiveFMAFusion(EVT VT) const
Return true if target always beneficiates from combining into FMA for a given value type...
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
const SDValue & getValue() const
virtual bool getPreIndexedAddressParts(SDNode *, SDValue &, SDValue &, ISD::MemIndexedMode &, SelectionDAG &) const
Returns true by value, base pointer and offset pointer and addressing mode by reference if the node's...
virtual SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps, bool &UseOneConstNR, bool Reciprocal) const
Hooks for building estimates in place of slower divisions and square roots.
SDVTList getVTList() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
virtual bool isFNegFree(EVT VT) const
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger)
Return the result of a logical AND between different comparisons of identical values: ((X op1 Y) & (X...
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
This method will be invoked for all target nodes and for any target-independent nodes that the target...
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
The two locations do not alias at all.
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
detail::ValueMatchesPoly< M > HasValue(M Matcher)
const SDValue & getChain() const
unsigned getResNo() const
Convenience function for get().getResNo().
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
virtual bool isCommutativeBinOp(unsigned Opcode) const
Returns true if the opcode is a commutative binary operation.
static const fltSemantics & EVTToAPFloatSemantics(EVT VT)
Returns an APFloat semantics tag appropriate for the given type.
unsigned getAlignment() const
unsigned getValueSizeInBits(unsigned ResNo) const
Returns MVT::getSizeInBits(getValueType(ResNo)).
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isBitwiseNot(SDValue V)
Returns true if V is a bitwise not operation.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
bool isAllOnesOrAllOnesSplat(SDValue V)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM)
APInt trunc(unsigned width) const
Truncate to new width.
void setAllBits()
Set every bit to 1.
bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const
Return true if the specified store with truncation is legal on this target.
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const fltSemantics & getSemantics() const
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
virtual bool isTypeDesirableForOp(unsigned, EVT VT) const
Return true if the target has native support for the specified value type and it is 'desirable' to us...
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
const SDNodeFlags getFlags() const
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...
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
iv Induction Variable Users
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2018 maximum semantics.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
virtual bool storeOfVectorConstantIsCheap(EVT MemVT, unsigned NumElem, unsigned AddrSpace) const
Return true if it is expected to be cheaper to do a store of a non-zero vector constant with the give...
bool isOperationLegalOrCustom(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
void DeleteNode(SDNode *N)
Remove the specified node from the system.
static SDValue combineTruncationShuffle(ShuffleVectorSDNode *SVN, SelectionDAG &DAG)
bool isConstTrueVal(const SDNode *N) const
Return if the N is a constant or constant vector equal to the true value from getBooleanContents().
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
SDValue getConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offs=0, bool isT=false, unsigned char TargetFlags=0)
unsigned getBitWidth() const
Get the bit width of this value.
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
static SDNode * ShrinkLoadReplaceStoreWithStore(const std::pair< unsigned, unsigned > &MaskInfo, SDValue IVal, StoreSDNode *St, DAGCombiner *DC)
Check to see if IVal is something that provides a value as specified by MaskInfo. ...
virtual SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode *> &Created) const
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators...
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
EntryToken - This is the marker used to indicate the start of a region.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To, unsigned Num)
Like ReplaceAllUsesOfValueWith, but for multiple values at once.
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
const ConstantFP * getConstantFPValue() const
unsigned getBitWidth() const
Return the number of bits in the APInt.
SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, SmallVectorImpl< SDNode *> &Created) const
Given an ISD::UDIV node expressing a divide by constant, return a DAG expression to select that will ...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
bool isAllOnesValue() const
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal on this target.
void transferDbgValues(SDValue From, SDValue To, unsigned OffsetInBits=0, unsigned SizeInBits=0, bool InvalidateDbg=true)
Transfer debug values from one node to another, while optionally generating fragment expressions for ...
virtual bool isFPExtFree(EVT DestVT, EVT SrcVT) const
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
bool hasApproximateFuncs() const
virtual bool isStoreBitCastBeneficial(EVT StoreVT, EVT BitcastVT) const
Return true if the following transform is beneficial: (store (y (conv x)), y*)) -> (store x...
bool isTruncatingStore() const
Return true if the op does a truncation before store.
int getRecipEstimateSqrtEnabled(EVT VT, MachineFunction &MF) const
Return a ReciprocalEstimate enum value for a square root of the given type based on the function's at...
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode *> &Visited, SmallVectorImpl< const SDNode *> &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, const SDLoc &DL)
Returns sum of the base pointer and offset.
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
bool operator<=(int64_t V1, const APSInt &V2)
static bool CanCombineFCOPYSIGN_EXTEND_ROUND(SDNode *N)
copysign(x, fp_extend(y)) -> copysign(x, y) copysign(x, fp_round(y)) -> copysign(x, y)
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
static cl::opt< bool > UseTBAA("combiner-use-tbaa", cl::Hidden, cl::init(true), cl::desc("Enable DAG combiner's use of TBAA"))
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
static uint32_t getAlignment(const MCSectionCOFF &Sec)
bool hasOneUse() const
Return true if there is exactly one use of this node.
static bool isContractable(SDNode *N)
A description of a memory reference used in the backend.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
OverflowKind computeOverflowKind(SDValue N0, SDValue N1) const
Determine if the result of the addition of 2 node can overflow.
virtual bool decomposeMulByConstant(EVT VT, SDValue C) const
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
bool SimplifyDemandedVectorElts(SDValue Op, const APInt &DemandedEltMask, APInt &KnownUndef, APInt &KnownZero, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Vector Op.
static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG)
void setBit(unsigned BitPosition)
Set a given bit to 1.
static ManagedStatic< DebugCounter > DC
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans, DAGCombinerInfo &DCI, const SDLoc &dl) const
Try to simplify a setcc built with the specified operands and cc.
bool operator>=(int64_t V1, const APSInt &V2)
bool isUndef(unsigned Opcode, ArrayRef< SDValue > Ops)
Return true if the result of this operation is always undefined.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static cl::opt< std::string > CombinerAAOnlyFunc("combiner-aa-only-func", cl::Hidden, cl::desc("Only use DAG-combiner alias analysis in this" " function"))
APInt shl(unsigned shiftAmt) const
Left-shift function.
Shift and rotation operations.
bool matchUnaryPredicate(SDValue Op, std::function< bool(ConstantSDNode *)> Match, bool AllowUndefs=false)
Attempt to match a unary predicate against a scalar/splat constant or every element of a constant BUI...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
static unsigned getPPCf128HiElementSelector(const SelectionDAG &DAG)
APInt zextOrSelf(unsigned width) const
Zero extend or truncate to width.
Base class for LoadSDNode and StoreSDNode.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef...
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth...
A Use represents the edge between a Value definition and its users.
SDValue getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO)
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static bool isLoad(int Opcode)
const SDValue & getPassThru() const
CopyToReg - This node has three operands: a chain, a register number to set to this value...
op_iterator op_end() const
unsigned getScalarValueSizeInBits() const
uint64_t getConstantOperandVal(unsigned i) const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
This file contains the simple types necessary to represent the attributes associated with functions a...
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2018 minimum semantics.
virtual bool generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel) const
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal or custom on this target.
The memory access is dereferenceable (i.e., doesn't trap).
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first...
const SDValue & getValue() const
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
virtual bool convertSetCCLogicToBitwiseLogic(EVT VT) const
Use bitwise logic to make pairs of compares more efficient.
virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const
Return true if it is cheaper to split the store of a merged int val from a pair of smaller values int...
const DataLayout & getDataLayout() const
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
This class is used to represent EVT's, which are used to parameterize some operations.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual bool aggressivelyPreferBuildVectorSources(EVT VecVT) const
zlib-gnu style compression
This file implements a class to represent arbitrary precision integral constant values and operations...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
iterator_range< allnodes_iterator > allnodes()
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
This class is used to represent an MSTORE node.
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
unsigned getSizeInBits() const
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
unsigned getActiveBits() const
Compute the number of active bits in the value.
int64_t getSExtValue() const
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
static SDValue combineMinNumMaxNum(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode CC, const TargetLowering &TLI, SelectionDAG &DAG)
Generate Min/Max node.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
unsigned getScalarSizeInBits() const
virtual bool isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT) const
Return true if the following transform is beneficial: fold (conv (load x)) -> (load (conv*)x) On arch...
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
int64_t getSExtValue() const
Get sign extended value.
Type * getType() const
All values are typed, get the type of this value.
bool getBoolValue() const
Convert APInt to a boolean value.
MachineFunction & getMachineFunction() const
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
bool insert(const value_type &X)
Insert a new element into the SetVector.
SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO)
bool isOneOrOneSplat(SDValue V)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
bool isKnownNeverZero(SDValue Op) const
Test whether the given SDValue is known to contain non-zero value(s).
const SDValue & getScale() const
const TargetMachine & getTarget() const
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
static bool isBooleanFlip(SDValue V, EVT VT, const TargetLowering &TLI)
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
Simple integer binary arithmetic operators.
static cl::opt< bool > StressLoadSlicing("combiner-stress-load-slicing", cl::Hidden, cl::desc("Bypass the profitability model of load slicing"), cl::init(false))
Hidden option to stress test load slicing, i.e., when this option is enabled, load slicing bypasses m...
bool has(LibFunc F) const
Tests whether a library function is available.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool isLittleEndian() const
Layout endianness...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isKnownNeverNaN(SDValue Op, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue is known to never be NaN.
SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Mask, EVT MemVT, MachineMemOperand *MMO, bool IsTruncating=false, bool IsCompressing=false)
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
op_iterator op_begin() const
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AddrSpace, Instruction *I=nullptr) const
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification, or lowering of the constant.
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
ArrayRef< SDUse > ops() const
const SDValue & getMask() const
int64_t getSrcValueOffset() const
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
SDValue GetDemandedBits(SDValue V, const APInt &Mask)
See if the specified operand can be simplified with the knowledge that only the bits specified by Mas...
static bool isLegalToCombineMinNumMaxNum(SelectionDAG &DAG, SDValue LHS, SDValue RHS)
std::pair< EVT, EVT > GetSplitDestVTs(const EVT &VT) const
Compute the VTs needed for the low/hi parts of a type which is split (or expanded) into two not neces...
int getRecipEstimateDivEnabled(EVT VT, MachineFunction &MF) const
Return a ReciprocalEstimate enum value for a division of the given type based on the function's attri...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
UNDEF - An undefined node.
This class is used to represent ISD::STORE nodes.
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
bool hasAllowReciprocal() const
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
AliasResult
The possible results of an alias query.
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
const Value * getValue() const
Return the base address of the memory access.
iterator find(const_arg_type_t< KeyT > Val)
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits...
bool isZero() const
Return true if the value is positive or negative zero.
bool hasAllowContract() const
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
bool isNegative() const
Determine sign of this APInt.
const SDValue & getBasePtr() const
initializer< Ty > init(const Ty &Val)
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
bool erase(const KeyT &Val)
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
static SDValue foldBitcastedFPLogic(SDNode *N, SelectionDAG &DAG, const TargetLowering &TLI)
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
bool isAllOnesValue() const
Determine if all bits are set.
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool isExpandingLoad() const
static SDValue combineConcatVectorOfExtracts(SDNode *N, SelectionDAG &DAG)
static SDValue ConvertSelectToConcatVector(SDNode *N, SelectionDAG &DAG)
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
Simple binary floating point operators.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
size_t size() const
size - Get the array size.
static int getShuffleMaskIndexOfOneElementFromOp0IntoOp1(ArrayRef< int > Mask)
If the shuffle mask is taking exactly one element from the first vector operand and passing through a...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
iterator_range< value_op_iterator > op_values() const
LLVM_NODISCARD bool empty() const
bool isRound() const
Return true if the size is a power-of-two number of bytes.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const SDValue & getOperand(unsigned Num) const
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Carry-using nodes for multiple precision addition and subtraction.
bool matchBinaryPredicate(SDValue LHS, SDValue RHS, std::function< bool(ConstantSDNode *, ConstantSDNode *)> Match, bool AllowUndefs=false)
Attempt to match a binary predicate against a pair of scalar/splat constants or every element of a pa...
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool isMask(unsigned numBits) const
bool isOneValue() const
Determine if this is a value of 1.
std::pair< SDValue, SDValue > SplitVectorOperand(const SDNode *N, unsigned OpNo)
Split the node's operand with EXTRACT_SUBVECTOR and return the low/high part.
virtual bool isFPExtFoldable(unsigned Opcode, EVT DestVT, EVT SrcVT) const
Return true if an fpext operation input to an Opcode operation is free (for instance, because half-precision floating-point numbers are implicitly extended to float-precision) for an FMA instruction.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
void AddToWorklist(SDNode *N)
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
void Combine(CombineLevel Level, AliasAnalysis *AA, CodeGenOpt::Level OptLevel)
This iterates over the nodes in the SelectionDAG, folding certain types of nodes together, or eliminating superfluous nodes.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This class provides iterator support for SDUse operands that use a specific SDNode.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
const APInt & getAPIntValue() const
bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
static bool matchRotateHalf(SelectionDAG &DAG, SDValue Op, SDValue &Shift, SDValue &Mask)
Match "(X shl/srl V1) & V2" where V2 may not be present.
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
virtual bool hasPairedLoad(EVT, unsigned &) const
Return true if the target supplies and combines to a paired load two loaded values of type LoadedType...
static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG)
If we are extracting a subvector produced by a wide binary operator try to use a narrow binary operat...
static SDValue visitFMinMax(SelectionDAG &DAG, SDNode *N, APFloat(*Op)(const APFloat &, const APFloat &))
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
unsigned getOriginalAlignment() const
Returns alignment and volatility of the memory access.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
const SDValue & getValue() const
CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y)...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const
Return true if the specified indexed load is legal on this target.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
static cl::opt< bool > CombinerGlobalAA("combiner-global-alias-analysis", cl::Hidden, cl::desc("Enable DAG combiner's use of IR alias analysis"))
virtual bool isDesirableToTransformToIntegerOp(unsigned, EVT) const
Return true if it is profitable for dag combiner to transform a floating point op of specified opcode...
SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::LoadExtType, bool IsExpanding=false)
Bit counting operators with an undefined result for zero inputs.
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
static const Optional< ByteProvider > calculateByteProvider(SDValue Op, unsigned Index, unsigned Depth, bool Root=false)
Recursively traverses the expression calculating the origin of the requested byte of the given value...
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
const SDValue & getIndex() const
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static SDValue tryToFoldExtOfExtload(SelectionDAG &DAG, DAGCombiner &Combiner, const TargetLowering &TLI, EVT VT, bool LegalOperations, SDNode *N, SDValue N0, ISD::LoadExtType ExtLoadType)
iterator erase(const_iterator CI)
const SDValue & getBasePtr() const
bool haveNoCommonBitsSet(SDValue A, SDValue B) const
Return true if A and B have no common bits set.
static bool areUsedBitsDense(const APInt &UsedBits)
Check that all bits set in UsedBits form a dense region, i.e., UsedBits looks like 0...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static void adjustCostForPairing(SmallVectorImpl< LoadedSlice > &LoadedSlices, LoadedSlice::Cost &GlobalLSCost)
Adjust the GlobalLSCost according to the target paring capabilities and the layout of the slices...
SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
int getDivRefinementSteps(EVT VT, MachineFunction &MF) const
Return the refinement step count for a division of the given type based on the function's attributes...
This class contains a discriminated union of information about pointers in memory operands...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
HANDLENODE node - Used as a handle for various purposes.
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE maxNum semantics.
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value...
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT...
static char isNegatibleForFree(SDValue Op, bool LegalOperations, const TargetLowering &TLI, const TargetOptions *Options, unsigned Depth=0)
Return 1 if we can compute the negated form of the specified expression for the same cost as the expr...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
static SDValue getAsCarry(const TargetLowering &TLI, SDValue V)
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
void sort(IteratorTy Start, IteratorTy End)
virtual bool shouldScalarizeBinop(SDValue VecOp) const
Try to convert an extract element of a vector binary operation into an extract element followed by a ...
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
The memory access writes data.
static SDValue combineShuffleOfSplat(ArrayRef< int > UserMask, ShuffleVectorSDNode *Splat, SelectionDAG &DAG)
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type...
bool use_empty() const
Return true if there are no uses of this node.
Representation for a specific memory location.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
virtual bool IsDesirableToPromoteOp(SDValue, EVT &) const
This method query the target whether it is beneficial for dag combiner to promote the specified node...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef...
void dump() const
Dump this node, for debugging.
static bool canFoldInAddressingMode(SDNode *N, SDNode *Use, SelectionDAG &DAG, const TargetLowering &TLI)
Return true if 'Use' is a load or a store that uses N as its base pointer and that N may be folded in...
const TargetLowering & getTargetLoweringInfo() const
Helper struct to parse and store a memory address as base + index + offset.
A SetVector that performs no allocations if smaller than a certain size.
unsigned getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
void setNoUnsignedWrap(bool b)
static SDValue combineShuffleToVectorExtend(ShuffleVectorSDNode *SVN, SelectionDAG &DAG, const TargetLowering &TLI, bool LegalOperations)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static void zeroExtendToMatch(APInt &LHS, APInt &RHS, unsigned Offset=0)
virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT) const
Return true if it is profitable to reduce a load to a smaller type.
SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, SmallVectorImpl< SDNode *> &Created) const
Given an ISD::SDIV node expressing a divide by constant, return a DAG expression to select that will ...
virtual bool shouldNormalizeToSelectSequence(LLVMContext &Context, EVT VT) const
Returns true if we should normalize select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y)) if it is likely that it saves us from materializing N0 and N1 in an integer register.
virtual bool getPostIndexedAddressParts(SDNode *, SDNode *, SDValue &, SDValue &, ISD::MemIndexedMode &, SelectionDAG &) const
Returns true by value, base pointer and offset pointer and addressing mode by reference if this node ...
BlockVerifier::State From
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
static int numVectorEltsOrZero(EVT T)
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
EVT getVectorElementType() const
Given a vector type, return the type of each element.
std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provides VTs and return the low/high part...
static SDValue foldExtendedSignBitTest(SDNode *N, SelectionDAG &DAG, bool LegalOperations)
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and rounds it to a floating point val...
const SDValue & getMask() const
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
virtual bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, unsigned Index) const
Return true if EXTRACT_SUBVECTOR is cheap for extracting this result type from this source type with ...
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
static APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
bool allOperandsUndef(const SDNode *N)
Return true if the node has at least one operand and all operands of the specified node are ISD::UNDE...
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
BRCOND - Conditional branch.
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values, following the IEEE-754 2008 definition.
static SDValue scalarizeExtractedBinop(SDNode *ExtElt, SelectionDAG &DAG, bool LegalOperations)
Transform a vector binary operation into a scalar binary operation by moving the math/logic after an ...
const SDValue & getPassThru() const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Byte Swap and Counting operators.
static SDValue flipBoolean(SDValue V, const SDLoc &DL, EVT VT, SelectionDAG &DAG, const TargetLowering &TLI)
APFloat neg(APFloat X)
Returns the negated value of the argument.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
virtual bool isVectorLoadExtDesirable(SDValue ExtVal) const
Return true if folding a vector load into ExtVal (a sign, zero, or any extend node) is profitable...
LLVM_NODISCARD T pop_back_val()
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
SDValue IncrementMemoryAddress(SDValue Addr, SDValue Mask, const SDLoc &DL, EVT DataVT, SelectionDAG &DAG, bool IsCompressedMemory) const
Increments memory address Addr according to the type of the value DataVT that should be stored...
Represents one node in the SelectionDAG.
CondCode getSetCCInverse(CondCode Operation, bool isInteger)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
static BaseIndexOffset match(const LSBaseSDNode *N, const SelectionDAG &DAG)
Parses tree in Ptr for base, index, offset addresses.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
static SDValue tryToFoldExtOfLoad(SelectionDAG &DAG, DAGCombiner &Combiner, const TargetLowering &TLI, EVT VT, bool LegalOperations, SDNode *N, SDValue N0, ISD::LoadExtType ExtLoadType, ISD::NodeType ExtOpc)
static unsigned int semanticsPrecision(const fltSemantics &)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static std::pair< SDValue, SDValue > SplitVSETCC(const SDNode *N, SelectionDAG &DAG)
bool isConstFalseVal(const SDNode *N) const
Return if the N is a constant or constant vector equal to the false value from getBooleanContents().
unsigned logBase2() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachinePointerInfo getWithOffset(int64_t O) const
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned countTrailingOnes() const
Count the number of trailing one bits.
size_t use_size() const
Return the number of uses of this node.
SDNode * isConstantIntBuildVectorOrConstantInt(SDValue N)
Test whether the given value is a constant int or similar node.
static SDValue foldFPToIntToFP(SDNode *N, SelectionDAG &DAG, const TargetLowering &TLI)
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT...
EVT getMemoryVT() const
Return the type of the in-memory value.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
Class for arbitrary precision integers.
static bool matchRotateSub(SDValue Pos, SDValue Neg, unsigned EltSize, SelectionDAG &DAG)
bool isBuildVectorOfConstantFPSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantFPSDNode or undef...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
static SDValue replaceShuffleOfInsert(ShuffleVectorSDNode *Shuf, SelectionDAG &DAG)
If a shuffle inserts exactly one element from a source vector operand into another vector operand and...
virtual bool preferShiftsToClearExtremeBits(SDValue X) const
There are two ways to clear extreme bits (either low or high): Mask: x & (-1 << y) (the instcombine c...
virtual bool hasAndNot(SDValue X) const
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
iterator_range< use_iterator > uses()
static cl::opt< bool > MaySplitLoadIndex("combiner-split-load-index", cl::Hidden, cl::init(true), cl::desc("DAG combiner may split indexing from loads"))
static SDNode * getBuildPairElt(SDNode *N, unsigned i)
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, SDNode *Cst1, SDNode *Cst2)
A "pseudo-class" with methods for operating on BUILD_VECTORs.
Select(COND, TRUEVAL, FALSEVAL).
SDValue peekThroughOneUseBitcasts(SDValue V)
Return the non-bitcasted and one-use source operand of V if it exists.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, unsigned Depth=0)
If isNegatibleForFree returns true, return the newly negated expression.
static use_iterator use_end()
bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
ZERO_EXTEND - Used for integer types, zeroing the new bits.
const SDValue & getBasePtr() const
ANY_EXTEND - Used for integer types. The high bits are undefined.
static std::pair< unsigned, unsigned > CheckForMaskedLoad(SDValue V, SDValue Ptr, SDValue Chain)
Check to see if V is (and load (ptr), imm), where the load is having specific bytes cleared out...
virtual bool isFMAFasterThanFMulAndFAdd(EVT) const
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
iterator insert(iterator I, T &&Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
static bool isAnyConstantBuildVector(SDValue V, bool NoOpaques=false)
CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger)
Return the result of a logical OR between different comparisons of identical values: ((X op1 Y) | (X ...
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
int getMaskElt(unsigned Idx) const
static SDValue partitionShuffleOfConcats(SDNode *N, SelectionDAG &DAG)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, const SDNodeFlags Flags=SDNodeFlags())
bool hasVectorReduction() const
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Flags
Flags values. These may be or'd together.
int getSqrtRefinementSteps(EVT VT, MachineFunction &MF) const
Return the refinement step count for a square root of the given type based on the function's attribut...
amdgpu Simplify well known AMD library false Value Value * Arg
The memory access reads data.
bool hasNoSignedWrap() const
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool operator!=(uint64_t V1, const APInt &V2)
static mvt_range all_valuetypes()
SimpleValueType Iteration.
bool ugt(const APInt &RHS) const
Unsigned greather than comparison.
opStatus
IEEE-754R 7: Default exception handling.
These are IR-level optimization flags that may be propagated to SDNodes.
Represents a use of a SDNode.
virtual bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const
Return true if it is profitable to move this shift by a constant amount though its operand...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isVector() const
Return true if this is a vector value type.
static SDValue extractShiftForRotate(SelectionDAG &DAG, SDValue OppShift, SDValue ExtractFrom, SDValue &Mask, const SDLoc &DL)
Helper function for visitOR to extract the needed side of a rotate idiom from a shl/srl/mul/udiv.
const SDValue & getValue() const
virtual bool convertSelectOfConstantsToMath(EVT VT) const
Return true if a select of constants (select Cond, C1, C2) should be transformed into simple math ops...
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
Bitwise operators - logical and, logical or, logical xor.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
pointer data()
Return a pointer to the vector's buffer, even if empty().
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
LLVM_NODISCARD bool empty() const
StringRef getValueAsString() const
Return the attribute's value as a string.
bool isKnownToBeAPowerOfTwo(SDValue Val) const
Test if the given value is known to have exactly one bit set.
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
This file provides utility analysis objects describing memory locations.
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps) const
Return a reciprocal estimate value for the input operand.
ISD::CondCode get() const
const ConstantInt * getConstantIntValue() const
const TargetSubtargetInfo & getSubtarget() const
bool empty() const
Determine if the SetVector is empty or not.
Flags getFlags() const
Return the raw flags of the source value,.
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
The memory access always returns the same value (or traps).
unsigned InferPtrAlignment(SDValue Ptr) const
Infer alignment of a load / store address.
static SDValue tryFoldToZero(const SDLoc &DL, const TargetLowering &TLI, EVT VT, SelectionDAG &DAG, bool LegalOperations)
virtual bool shouldFoldShiftPairToMask(const SDNode *N, CombineLevel Level) const
Return true if it is profitable to fold a pair of shifts into a mask.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static SDValue combineConcatVectorOfScalars(SDNode *N, SelectionDAG &DAG)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isBinaryOp(const SDNode *N)
Return true if the node is a math/logic binary operator.
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, const TargetLowering &TLI)
For the instruction sequence of store below, F and I values are bundled together as an i64 value befo...
const SDValue & getBasePtr() const
static SDValue getInputChainForNode(SDNode *N)
Given a node, return its input chain if it has one, otherwise return a null sd operand.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
unsigned getOpcode() const
SDValue getValue(unsigned R) const
virtual bool isIntDivCheap(EVT VT, AttributeList Attr) const
Return true if integer divide is usually cheaper than a sequence of several shifts, adds, and multiplies for this target.
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
This class is used to represent an MSCATTER node.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
LLVM_NODISCARD bool empty() const
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
static SDValue stripConstantMask(SelectionDAG &DAG, SDValue Op, SDValue &Mask)
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
const MachinePointerInfo & getPointerInfo() const
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, unsigned Alignment=1, bool *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
This class is used to form a handle around another node that is persistent and is updated across invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
unsigned getMinSignedBits() const
Get the minimum bit size for this signed APInt.
SDValue simplifySelect(SDValue Cond, SDValue TVal, SDValue FVal)
Try to simplify a select/vselect into 1 of its operands or a constant.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
This class is used to represent an MLOAD node.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
bool operator<(int64_t V1, const APSInt &V2)
static ConstantSDNode * getAsNonOpaqueConstant(SDValue N)
If N is a ConstantSDNode with isOpaque() == false return it casted to a ConstantSDNode pointer else n...
static bool ExtendUsesToFormExtLoad(EVT VT, SDNode *N, SDValue N0, unsigned ExtOpc, SmallVectorImpl< SDNode *> &ExtendNodes, const TargetLowering &TLI)
ArrayRef< int > getMask() const
LLVM Value Representation.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
FMA - Perform a * b + c with no intermediate rounding step.
static bool isSlicingProfitable(SmallVectorImpl< LoadedSlice > &LoadedSlices, const APInt &UsedBits, bool ForCodeSize)
Check the profitability of all involved LoadedSlice.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
A vector that has set insertion semantics.
bool isTruncatingStore() const
Return true if the op does a truncation before store.
static bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned, const TargetLowering &TLI)
Return true if divmod libcall is available.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
This class is used to represent an MGATHER node.
bool hasNoUnsignedWrap() const
SDValue getValueType(EVT)
virtual bool isVectorClearMaskLegal(ArrayRef< int >, EVT) const
Similar to isShuffleMaskLegal.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
virtual bool isFsqrtCheap(SDValue X, SelectionDAG &DAG) const
Return true if SQRT(X) shouldn't be replaced with X*RSQRT(X).
bool isNonTemporal() const
bool isUndef() const
Return true if the type of the node type undefined.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone...
bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal on this target.
virtual bool mergeStoresAfterLegalization() const
Allow store merging after legalization in addition to before legalization.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
bool hasAllowReassociation() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX)
virtual bool useAA() const
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine, etc.).
const APFloat & getValueAPF() const
unsigned NoSignedZerosFPMath
NoSignedZerosFPMath - This flag is enabled when the -enable-no-signed-zeros-fp-math is specified on t...
virtual const SelectionDAGTargetInfo * getSelectionDAGInfo() const
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations...
SetCC operator - This evaluates to a true value iff the condition is true.
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const
Return true if folding a constant offset with the given GlobalAddress is legal.
APInt bitcastToAPInt() const
static SDNode * isConstantFPBuildVectorOrConstantFP(SDValue N)
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG)
If we are extracting a subvector from a wide vector load, convert to a narrow load to eliminate the e...
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
bool operator==(uint64_t V1, const APInt &V2)
unsigned getNumOperands() const
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations, those with specific masks.
static bool isVolatile(Instruction *Inst)
static APInt getNullValue(unsigned numBits)
Get the '0' value.
const SDValue & getOperand(unsigned i) const
bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG) const
SDNode * getUser()
This returns the SDNode that contains this Use.
unsigned getGatherAllAliasesMaxDepth() const
uint64_t getZExtValue() const
SDNode * getNodeIfExists(unsigned Opcode, SDVTList VTList, ArrayRef< SDValue > Ops, const SDNodeFlags Flags=SDNodeFlags())
Get the specified node if it's already available, or else return NULL.
TRUNCATE - Completely drop the high bits.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static void Split(std::vector< std::string > &V, StringRef S)
Splits a string of comma separated items in to a vector of strings.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
bool hasTargetDAGCombine(ISD::NodeType NT) const
If true, the target has custom DAG combine transformations that it can perform for the specified node...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
virtual bool hasBitPreservingFPLogic(EVT VT) const
Return true if it is safe to transform an integer-domain bitwise operation into the equivalent floati...
Perform various unary floating-point operations inspired by libm.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
virtual bool isLegalAddImmediate(int64_t) const
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
const SDValue & getBasePtr() const
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVMContext * getContext() const
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE minNum semantics.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const
Return true if the specified indexed load is legal on this target.
Carry-using nodes for multiple precision addition and subtraction.
const SDValue & getMask() const
bool isNullValue() const
Determine if all bits are clear.
CARRY_FALSE - This node is used when folding other nodes, like ADDC/SUBC, which indicate the carry re...
virtual bool isNarrowingProfitable(EVT, EVT) const
Return true if it's profitable to narrow operations of type VT1 to VT2.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
This file describes how to lower LLVM code to machine code.
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO)
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
virtual bool shouldSplatInsEltVarIndex(EVT) const
Return true if inserting a scalar into a variable element of an undef vector is more efficiently hand...
static bool isConstantOrConstantVector(SDValue N, bool NoOpaques=false)
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
This class is used to represent ISD::LOAD nodes.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.