85#define DEBUG_TYPE "dagcombine"
87STATISTIC(NodesCombined ,
"Number of dag nodes combined");
88STATISTIC(PreIndexedNodes ,
"Number of pre-indexed nodes created");
89STATISTIC(PostIndexedNodes,
"Number of post-indexed nodes created");
90STATISTIC(OpsNarrowed ,
"Number of load/op/store narrowed");
91STATISTIC(LdStFP2Int ,
"Number of fp load/store pairs transformed to int");
93STATISTIC(NumFPLogicOpsConv,
"Number of logic ops converted to fp ops");
96 "Controls whether a DAG combine is performed for a node");
100 cl::desc(
"Enable DAG combiner's use of IR alias analysis"));
104 cl::desc(
"Enable DAG combiner's use of TBAA"));
109 cl::desc(
"Only use DAG-combiner alias analysis in this"
117 cl::desc(
"Bypass the profitability model of load slicing"),
122 cl::desc(
"DAG combiner may split indexing from loads"));
126 cl::desc(
"DAG combiner enable merging multiple stores "
127 "into a wider store"));
131 cl::desc(
"Limit the number of operands to inline for Token Factors"));
135 cl::desc(
"Limit the number of times for the same StoreNode and RootNode "
136 "to bail out in store merging dependence check"));
140 cl::desc(
"DAG combiner enable reducing the width of load/op/store "
143 "combiner-reduce-load-op-store-width-force-narrowing-profitable",
145 cl::desc(
"DAG combiner force override the narrowing profitable check when "
146 "reducing the width of load/op/store sequences"));
150 cl::desc(
"DAG combiner enable load/<replace bytes>/store with "
151 "a narrower store"));
155 cl::desc(
"Disable the DAG combiner"));
165 bool LegalDAG =
false;
166 bool LegalOperations =
false;
167 bool LegalTypes =
false;
169 bool DisableGenericCombines;
205 void AddUsersToWorklist(
SDNode *
N) {
211 void AddToWorklistWithUsers(SDNode *
N) {
212 AddUsersToWorklist(
N);
219 void clearAddedDanglingWorklistEntries() {
221 while (!PruningList.empty()) {
222 auto *
N = PruningList.pop_back_val();
224 recursivelyDeleteUnusedNodes(
N);
228 SDNode *getNextWorklistEntry() {
230 clearAddedDanglingWorklistEntries();
234 while (!
N && !Worklist.empty()) {
235 N = Worklist.pop_back_val();
239 assert(
N->getCombinerWorklistIndex() >= 0 &&
240 "Found a worklist entry without a corresponding map entry!");
242 N->setCombinerWorklistIndex(-2);
252 : DAG(
D), TLI(
D.getTargetLoweringInfo()),
253 STI(
D.getSubtarget().getSelectionDAGInfo()), OptLevel(OL),
255 ForCodeSize = DAG.shouldOptForSize();
256 DisableGenericCombines =
259 MaximumLegalStoreInBits = 0;
263 if (EVT(VT).
isSimple() && VT != MVT::Other &&
264 TLI.isTypeLegal(EVT(VT)) &&
265 VT.getSizeInBits().getKnownMinValue() >= MaximumLegalStoreInBits)
266 MaximumLegalStoreInBits = VT.getSizeInBits().getKnownMinValue();
269 void ConsiderForPruning(SDNode *
N) {
271 PruningList.insert(
N);
276 void AddToWorklist(SDNode *
N,
bool IsCandidateForPruning =
true,
277 bool SkipIfCombinedBefore =
false) {
279 "Deleted Node added to Worklist");
286 if (SkipIfCombinedBefore &&
N->getCombinerWorklistIndex() == -2)
289 if (IsCandidateForPruning)
290 ConsiderForPruning(
N);
292 if (
N->getCombinerWorklistIndex() < 0) {
293 N->setCombinerWorklistIndex(Worklist.size());
294 Worklist.push_back(
N);
299 void removeFromWorklist(SDNode *
N) {
300 PruningList.remove(
N);
301 StoreRootCountMap.erase(
N);
303 int WorklistIndex =
N->getCombinerWorklistIndex();
307 if (WorklistIndex < 0)
311 Worklist[WorklistIndex] =
nullptr;
312 N->setCombinerWorklistIndex(-1);
315 void deleteAndRecombine(SDNode *
N);
316 bool recursivelyDeleteUnusedNodes(SDNode *
N);
324 return CombineTo(
N, &Res, 1, AddTo);
331 return CombineTo(
N, To, 2, AddTo);
334 SDValue CombineTo(SDNode *
N, SmallVectorImpl<SDValue> *To,
336 return CombineTo(
N, To->
data(), To->
size(), AddTo);
339 void CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO);
342 unsigned MaximumLegalStoreInBits;
348 unsigned BitWidth =
Op.getScalarValueSizeInBits();
350 return SimplifyDemandedBits(
Op, DemandedBits);
353 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits) {
354 EVT VT =
Op.getValueType();
358 return SimplifyDemandedBits(
Op, DemandedBits, DemandedElts,
false);
364 bool SimplifyDemandedVectorElts(
SDValue Op) {
366 if (
Op.getValueType().isScalableVector())
369 unsigned NumElts =
Op.getValueType().getVectorNumElements();
371 return SimplifyDemandedVectorElts(
Op, DemandedElts);
374 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
375 const APInt &DemandedElts,
376 bool AssumeSingleUse =
false);
377 bool SimplifyDemandedVectorElts(
SDValue Op,
const APInt &DemandedElts,
378 bool AssumeSingleUse =
false);
380 bool CombineToPreIndexedLoadStore(SDNode *
N);
381 bool CombineToPostIndexedLoadStore(SDNode *
N);
382 SDValue SplitIndexingFromLoad(LoadSDNode *LD);
383 bool SliceUpLoad(SDNode *
N);
389 StoreSDNode *getUniqueStoreFeeding(LoadSDNode *LD, int64_t &
Offset);
391 SDValue ForwardStoreValueToDirectLoad(LoadSDNode *LD);
392 bool getTruncatedStoreValue(StoreSDNode *ST,
SDValue &Val);
393 bool extendLoadedValueToExtension(LoadSDNode *LD,
SDValue &Val);
395 void ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad);
404 SDValue foldShiftToAvg(SDNode *
N,
const SDLoc &
DL);
406 SDValue foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT);
424 SDValue visitTokenFactor(SDNode *
N);
425 SDValue visitMERGE_VALUES(SDNode *
N);
429 SDNode *LocReference);
440 SDValue visitUADDO_CARRY(SDNode *
N);
441 SDValue visitSADDO_CARRY(SDNode *
N);
447 SDValue visitUSUBO_CARRY(SDNode *
N);
448 SDValue visitSSUBO_CARRY(SDNode *
N);
449 template <
class MatchContextClass>
SDValue visitMUL(SDNode *
N);
470 SDValue SimplifyVCastOp(SDNode *
N,
const SDLoc &
DL);
471 SDValue SimplifyVBinOp(SDNode *
N,
const SDLoc &
DL);
475 SDValue visitFunnelShift(SDNode *
N);
482 SDValue visitCTLZ_ZERO_UNDEF(SDNode *
N);
484 SDValue visitCTTZ_ZERO_UNDEF(SDNode *
N);
492 SDValue visitSIGN_EXTEND(SDNode *
N);
493 SDValue visitZERO_EXTEND(SDNode *
N);
496 SDValue visitAssertAlign(SDNode *
N);
497 SDValue visitSIGN_EXTEND_INREG(SDNode *
N);
498 SDValue visitEXTEND_VECTOR_INREG(SDNode *
N);
500 SDValue visitTRUNCATE_USAT_U(SDNode *
N);
507 SDValue visitSTRICT_FADD(SDNode *
N);
510 template <
class MatchContextClass>
SDValue visitFMA(SDNode *
N);
518 SDValue visitFCANONICALIZE(SDNode *
N);
538 SDValue replaceStoreOfFPConstant(StoreSDNode *ST);
539 SDValue replaceStoreOfInsertLoad(StoreSDNode *ST);
541 bool refineExtractVectorEltIntoMultipleNarrowExtractVectorElts(SDNode *
N);
544 SDValue visitATOMIC_STORE(SDNode *
N);
545 SDValue visitLIFETIME_END(SDNode *
N);
546 SDValue visitINSERT_VECTOR_ELT(SDNode *
N);
547 SDValue visitEXTRACT_VECTOR_ELT(SDNode *
N);
548 SDValue visitBUILD_VECTOR(SDNode *
N);
549 SDValue visitCONCAT_VECTORS(SDNode *
N);
550 SDValue visitVECTOR_INTERLEAVE(SDNode *
N);
551 SDValue visitEXTRACT_SUBVECTOR(SDNode *
N);
552 SDValue visitVECTOR_SHUFFLE(SDNode *
N);
553 SDValue visitSCALAR_TO_VECTOR(SDNode *
N);
554 SDValue visitINSERT_SUBVECTOR(SDNode *
N);
555 SDValue visitVECTOR_COMPRESS(SDNode *
N);
561 SDValue visitPARTIAL_REDUCE_MLA(SDNode *
N);
564 SDValue visitVP_STRIDED_LOAD(SDNode *
N);
565 SDValue visitVP_STRIDED_STORE(SDNode *
N);
572 SDValue visitGET_FPENV_MEM(SDNode *
N);
573 SDValue visitSET_FPENV_MEM(SDNode *
N);
575 template <
class MatchContextClass>
576 SDValue visitFADDForFMACombine(SDNode *
N);
577 template <
class MatchContextClass>
578 SDValue visitFSUBForFMACombine(SDNode *
N);
579 SDValue visitFMULForFMADistributiveCombine(SDNode *
N);
581 SDValue XformToShuffleWithZero(SDNode *
N);
582 bool reassociationCanBreakAddressingModePattern(
unsigned Opc,
588 SDValue N1, SDNodeFlags Flags);
590 SDValue N1, SDNodeFlags Flags);
591 SDValue reassociateReduction(
unsigned RedOpc,
unsigned Opc,
const SDLoc &
DL,
593 SDNodeFlags Flags = SDNodeFlags());
595 SDValue visitShiftByConstant(SDNode *
N);
597 SDValue foldSelectOfConstants(SDNode *
N);
598 SDValue foldVSelectOfConstants(SDNode *
N);
599 SDValue foldBinOpIntoSelect(SDNode *BO);
601 SDValue hoistLogicOpWithSameOpcodeHands(SDNode *
N);
605 bool NotExtCompare =
false);
606 SDValue convertSelectOfFPConstantsToLoadOffset(
609 SDValue foldSignChangeInBitcast(SDNode *
N);
612 SDValue foldSelectOfBinops(SDNode *
N);
616 SDValue foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL);
617 SDValue foldABSToABD(SDNode *
N,
const SDLoc &
DL);
622 SDValue unfoldMaskedMerge(SDNode *
N);
623 SDValue unfoldExtremeBitClearingToShifts(SDNode *
N);
625 const SDLoc &
DL,
bool foldBooleans);
629 SDValue &CC,
bool MatchStrict =
false)
const;
630 bool isOneUseSetCC(
SDValue N)
const;
632 SDValue foldAddToAvg(SDNode *
N,
const SDLoc &
DL);
633 SDValue foldSubToAvg(SDNode *
N,
const SDLoc &
DL);
635 SDValue SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
637 SDValue CombineConsecutiveLoads(SDNode *
N, EVT VT);
638 SDValue foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
639 const TargetLowering &TLI);
640 SDValue foldPartialReduceMLAMulOp(SDNode *
N);
641 SDValue foldPartialReduceAdd(SDNode *
N);
644 SDValue CombineZExtLogicopShiftLoad(SDNode *
N);
645 SDValue combineRepeatedFPDivisors(SDNode *
N);
646 SDValue combineFMulOrFDivWithIntPow2(SDNode *
N);
647 SDValue replaceShuffleOfInsert(ShuffleVectorSDNode *Shuf);
648 SDValue mergeInsertEltWithShuffle(SDNode *
N,
unsigned InsIndex);
649 SDValue combineInsertEltToShuffle(SDNode *
N,
unsigned InsIndex);
650 SDValue combineInsertEltToLoad(SDNode *
N,
unsigned InsIndex);
657 bool KnownNeverZero =
false,
658 bool InexpensiveOnly =
false,
659 std::optional<EVT> OutVT = std::nullopt);
669 bool DemandHighBits =
true);
673 bool HasPos,
unsigned PosOpcode,
674 unsigned NegOpcode,
const SDLoc &
DL);
677 bool HasPos,
unsigned PosOpcode,
678 unsigned NegOpcode,
const SDLoc &
DL);
681 SDValue MatchLoadCombine(SDNode *
N);
682 SDValue mergeTruncStores(StoreSDNode *
N);
684 SDValue ReduceLoadOpStoreWidth(SDNode *
N);
686 SDValue TransformFPLoadStorePair(SDNode *
N);
687 SDValue convertBuildVecZextToZext(SDNode *
N);
688 SDValue convertBuildVecZextToBuildVecWithZeros(SDNode *
N);
689 SDValue reduceBuildVecExtToExtBuildVec(SDNode *
N);
690 SDValue reduceBuildVecTruncToBitCast(SDNode *
N);
691 SDValue reduceBuildVecToShuffle(SDNode *
N);
692 SDValue createBuildVecShuffle(
const SDLoc &
DL, SDNode *
N,
693 ArrayRef<int> VectorMask,
SDValue VecIn1,
694 SDValue VecIn2,
unsigned LeftIdx,
696 SDValue matchVSelectOpSizesWithSetCC(SDNode *Cast);
700 void GatherAllAliases(SDNode *
N,
SDValue OriginalChain,
701 SmallVectorImpl<SDValue> &Aliases);
704 bool mayAlias(SDNode *Op0, SDNode *Op1)
const;
716 bool findBetterNeighborChains(StoreSDNode *St);
720 bool parallelizeChainedStores(StoreSDNode *St);
726 LSBaseSDNode *MemNode;
729 int64_t OffsetFromBase;
731 MemOpLink(LSBaseSDNode *
N, int64_t
Offset)
732 : MemNode(
N), OffsetFromBase(
Offset) {}
737 StoreSource getStoreSource(
SDValue StoreVal) {
741 return StoreSource::Constant;
745 return StoreSource::Constant;
746 return StoreSource::Unknown;
749 return StoreSource::Extract;
751 return StoreSource::Load;
753 return StoreSource::Unknown;
761 bool isMulAddWithConstProfitable(SDNode *MulNode,
SDValue AddNode,
767 bool isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
768 EVT LoadResultTy, EVT &ExtVT);
773 EVT &MemVT,
unsigned ShAmt = 0);
776 bool SearchForAndLoads(SDNode *
N, SmallVectorImpl<LoadSDNode*> &Loads,
777 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
778 ConstantSDNode *Mask, SDNode *&NodeToMask);
781 bool BackwardsPropagateMask(SDNode *
N);
785 SDValue getMergeStoreChains(SmallVectorImpl<MemOpLink> &StoreNodes,
797 bool mergeStoresOfConstantsOrVecElts(SmallVectorImpl<MemOpLink> &StoreNodes,
798 EVT MemVT,
unsigned NumStores,
799 bool IsConstantSrc,
bool UseVector,
805 SDNode *getStoreMergeCandidates(StoreSDNode *St,
806 SmallVectorImpl<MemOpLink> &StoreNodes);
812 bool checkMergeStoreCandidatesForDependencies(
813 SmallVectorImpl<MemOpLink> &StoreNodes,
unsigned NumStores,
818 bool hasCallInLdStChain(StoreSDNode *St, LoadSDNode *Ld);
823 unsigned getConsecutiveStores(SmallVectorImpl<MemOpLink> &StoreNodes,
824 int64_t ElementSizeBytes)
const;
828 bool tryStoreMergeOfConstants(SmallVectorImpl<MemOpLink> &StoreNodes,
829 unsigned NumConsecutiveStores,
830 EVT MemVT, SDNode *Root,
bool AllowVectors);
836 bool tryStoreMergeOfExtracts(SmallVectorImpl<MemOpLink> &StoreNodes,
837 unsigned NumConsecutiveStores, EVT MemVT,
842 bool tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
843 unsigned NumConsecutiveStores, EVT MemVT,
844 SDNode *Root,
bool AllowVectors,
845 bool IsNonTemporalStore,
bool IsNonTemporalLoad);
850 bool mergeConsecutiveStores(StoreSDNode *St);
858 SDValue distributeTruncateThroughAnd(SDNode *
N);
864 bool hasOperation(
unsigned Opcode, EVT VT) {
865 return TLI.isOperationLegalOrCustom(Opcode, VT, LegalOperations);
868 bool hasUMin(EVT VT)
const {
869 auto LK = TLI.getTypeConversion(*DAG.getContext(), VT);
872 TLI.isOperationLegalOrCustom(
ISD::UMIN, LK.second);
879 SelectionDAG &getDAG()
const {
return DAG; }
882 EVT getShiftAmountTy(EVT LHSTy) {
883 return TLI.getShiftAmountTy(LHSTy, DAG.getDataLayout());
888 bool isTypeLegal(
const EVT &VT) {
889 if (!LegalTypes)
return true;
890 return TLI.isTypeLegal(VT);
894 EVT getSetCCResultType(EVT VT)
const {
895 return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
898 void ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
909 explicit WorklistRemover(DAGCombiner &dc)
910 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
912 void NodeDeleted(SDNode *
N, SDNode *
E)
override {
913 DC.removeFromWorklist(
N);
921 explicit WorklistInserter(DAGCombiner &dc)
922 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
926 void NodeInserted(SDNode *
N)
override { DC.ConsiderForPruning(
N); }
936 ((DAGCombiner*)
DC)->AddToWorklist(
N);
941 return ((DAGCombiner*)
DC)->CombineTo(
N, &To[0], To.
size(), AddTo);
946 return ((DAGCombiner*)
DC)->CombineTo(
N, Res, AddTo);
951 return ((DAGCombiner*)
DC)->CombineTo(
N, Res0, Res1, AddTo);
956 return ((DAGCombiner*)
DC)->recursivelyDeleteUnusedNodes(
N);
961 return ((DAGCombiner*)
DC)->CommitTargetLoweringOpt(TLO);
968void DAGCombiner::deleteAndRecombine(
SDNode *
N) {
969 removeFromWorklist(
N);
977 if (
Op->hasOneUse() ||
Op->getNumValues() > 1)
978 AddToWorklist(
Op.getNode());
987 unsigned Bits =
Offset + std::max(
LHS.getBitWidth(),
RHS.getBitWidth());
998 SDValue &CC,
bool MatchStrict)
const {
1000 LHS =
N.getOperand(0);
1001 RHS =
N.getOperand(1);
1009 LHS =
N.getOperand(1);
1010 RHS =
N.getOperand(2);
1023 LHS =
N.getOperand(0);
1024 RHS =
N.getOperand(1);
1032bool DAGCombiner::isOneUseSetCC(
SDValue N)
const {
1034 if (isSetCCEquivalent(
N, N0, N1, N2) &&
N->hasOneUse())
1046 MaskForTy = 0xFFULL;
1049 MaskForTy = 0xFFFFULL;
1052 MaskForTy = 0xFFFFFFFFULL;
1070 bool AllowTruncation =
false) {
1072 return !(Const->isOpaque() && NoOpaques);
1075 unsigned BitWidth =
N.getScalarValueSizeInBits();
1080 if (!Const || (Const->isOpaque() && NoOpaques))
1084 if ((AllowTruncation &&
1085 Const->getAPIntValue().getActiveBits() >
BitWidth) ||
1086 (!AllowTruncation && Const->getAPIntValue().getBitWidth() !=
BitWidth))
1108bool DAGCombiner::reassociationCanBreakAddressingModePattern(
unsigned Opc,
1136 : (N1.
getOperand(0).getConstantOperandVal(0) *
1141 ScalableOffset = -ScalableOffset;
1142 if (
all_of(
N->users(), [&](SDNode *Node) {
1143 if (auto *LoadStore = dyn_cast<MemSDNode>(Node);
1144 LoadStore && LoadStore->getBasePtr().getNode() == N) {
1145 TargetLoweringBase::AddrMode AM;
1146 AM.HasBaseReg = true;
1147 AM.ScalableOffset = ScalableOffset;
1148 EVT VT = LoadStore->getMemoryVT();
1149 unsigned AS = LoadStore->getAddressSpace();
1150 Type *AccessTy = VT.getTypeForEVT(*DAG.getContext());
1151 return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM, AccessTy,
1166 const APInt &C2APIntVal = C2->getAPIntValue();
1174 const APInt &C1APIntVal = C1->getAPIntValue();
1175 const APInt CombinedValueIntVal = C1APIntVal + C2APIntVal;
1178 const int64_t CombinedValue = CombinedValueIntVal.
getSExtValue();
1180 for (SDNode *Node :
N->users()) {
1185 TargetLoweringBase::AddrMode AM;
1187 AM.
BaseOffs = C2APIntVal.getSExtValue();
1189 unsigned AS =
LoadStore->getAddressSpace();
1205 for (SDNode *Node :
N->users()) {
1212 TargetLoweringBase::AddrMode AM;
1214 AM.
BaseOffs = C2APIntVal.getSExtValue();
1216 unsigned AS =
LoadStore->getAddressSpace();
1229SDValue DAGCombiner::reassociateOpsCommutative(
unsigned Opc,
const SDLoc &
DL,
1231 SDNodeFlags Flags) {
1241 SDNodeFlags NewFlags;
1243 Flags.hasNoUnsignedWrap())
1251 return DAG.
getNode(
Opc,
DL, VT, N00, OpNode, NewFlags);
1259 return DAG.
getNode(
Opc,
DL, VT, OpNode, N01, NewFlags);
1269 if (N1 == N00 || N1 == N01)
1315 if (CC1 == CC00 && CC1 != CC01) {
1319 if (CC1 == CC01 && CC1 != CC00) {
1333 SDValue N1, SDNodeFlags Flags) {
1339 if (!
Flags.hasAllowReassociation() || !
Flags.hasNoSignedZeros())
1342 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N0, N1, Flags))
1344 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N1, N0, Flags))
1352SDValue DAGCombiner::reassociateReduction(
unsigned RedOpc,
unsigned Opc,
1354 SDValue N1, SDNodeFlags Flags) {
1360 SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
1382 A.getValueType() ==
C.getValueType() &&
1383 hasOperation(
Opc,
A.getValueType()) &&
1391 SelectionDAG::FlagInserter FlagsInserter(
1402SDValue DAGCombiner::CombineTo(SDNode *
N,
const SDValue *To,
unsigned NumTo,
1404 assert(
N->getNumValues() == NumTo &&
"Broken CombineTo call!");
1408 dbgs() <<
" and " << NumTo - 1 <<
" other values\n");
1409 for (
unsigned i = 0, e = NumTo; i !=
e; ++i)
1411 N->getValueType(i) == To[i].getValueType()) &&
1412 "Cannot combine value to value of different type!");
1414 WorklistRemover DeadNodes(*
this);
1418 for (
unsigned i = 0, e = NumTo; i !=
e; ++i) {
1420 AddToWorklistWithUsers(To[i].
getNode());
1428 deleteAndRecombine(
N);
1433CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO) {
1446 recursivelyDeleteUnusedNodes(TLO.
Old.
getNode());
1451bool DAGCombiner::SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
1452 const APInt &DemandedElts,
1453 bool AssumeSingleUse) {
1454 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1461 AddToWorklist(
Op.getNode());
1463 CommitTargetLoweringOpt(TLO);
1470bool DAGCombiner::SimplifyDemandedVectorElts(
SDValue Op,
1471 const APInt &DemandedElts,
1472 bool AssumeSingleUse) {
1473 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1474 APInt KnownUndef, KnownZero;
1476 TLO, 0, AssumeSingleUse))
1480 AddToWorklist(
Op.getNode());
1482 CommitTargetLoweringOpt(TLO);
1486void DAGCombiner::ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad) {
1488 EVT VT =
Load->getValueType(0);
1497 AddToWorklist(Trunc.
getNode());
1498 recursivelyDeleteUnusedNodes(Load);
1506 EVT MemVT =
LD->getMemoryVT();
1508 :
LD->getExtensionType();
1511 LD->getChain(),
LD->getBasePtr(),
1512 MemVT,
LD->getMemOperand());
1515 unsigned Opc =
Op.getOpcode();
1519 if (
SDValue Op0 = SExtPromoteOperand(
Op.getOperand(0), PVT))
1523 if (
SDValue Op0 = ZExtPromoteOperand(
Op.getOperand(0), PVT))
1541 EVT OldVT =
Op.getValueType();
1543 bool Replace =
false;
1544 SDValue NewOp = PromoteOperand(
Op, PVT, Replace);
1547 AddToWorklist(NewOp.
getNode());
1550 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1556 EVT OldVT =
Op.getValueType();
1558 bool Replace =
false;
1559 SDValue NewOp = PromoteOperand(
Op, PVT, Replace);
1562 AddToWorklist(NewOp.
getNode());
1565 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1573 if (!LegalOperations)
1576 EVT VT =
Op.getValueType();
1582 unsigned Opc =
Op.getOpcode();
1590 assert(PVT != VT &&
"Don't know what type to promote to!");
1594 bool Replace0 =
false;
1596 SDValue NN0 = PromoteOperand(N0, PVT, Replace0);
1598 bool Replace1 =
false;
1600 SDValue NN1 = PromoteOperand(N1, PVT, Replace1);
1612 Replace1 &= (N0 != N1) && !N1->
hasOneUse();
1615 CombineTo(
Op.getNode(), RV);
1641 if (!LegalOperations)
1644 EVT VT =
Op.getValueType();
1650 unsigned Opc =
Op.getOpcode();
1658 assert(PVT != VT &&
"Don't know what type to promote to!");
1662 bool Replace =
false;
1665 N0 = SExtPromoteOperand(N0, PVT);
1667 N0 = ZExtPromoteOperand(N0, PVT);
1669 N0 = PromoteOperand(N0, PVT, Replace);
1680 ReplaceLoadWithPromotedLoad(
Op.getOperand(0).getNode(), N0.
getNode());
1690 if (!LegalOperations)
1693 EVT VT =
Op.getValueType();
1699 unsigned Opc =
Op.getOpcode();
1707 assert(PVT != VT &&
"Don't know what type to promote to!");
1712 return DAG.
getNode(
Op.getOpcode(), SDLoc(
Op), VT,
Op.getOperand(0));
1717bool DAGCombiner::PromoteLoad(
SDValue Op) {
1718 if (!LegalOperations)
1724 EVT VT =
Op.getValueType();
1730 unsigned Opc =
Op.getOpcode();
1738 assert(PVT != VT &&
"Don't know what type to promote to!");
1741 SDNode *
N =
Op.getNode();
1743 EVT MemVT =
LD->getMemoryVT();
1745 :
LD->getExtensionType();
1747 LD->getChain(),
LD->getBasePtr(),
1748 MemVT,
LD->getMemOperand());
1757 AddToWorklist(
Result.getNode());
1758 recursivelyDeleteUnusedNodes(
N);
1771bool DAGCombiner::recursivelyDeleteUnusedNodes(SDNode *
N) {
1772 if (!
N->use_empty())
1775 SmallSetVector<SDNode *, 16> Nodes;
1782 if (
N->use_empty()) {
1783 for (
const SDValue &ChildN :
N->op_values())
1784 Nodes.
insert(ChildN.getNode());
1786 removeFromWorklist(
N);
1791 }
while (!Nodes.
empty());
1806 WorklistInserter AddNodes(*
this);
1814 for (SDNode &Node : DAG.
allnodes())
1815 AddToWorklist(&Node,
Node.use_empty());
1820 HandleSDNode Dummy(DAG.
getRoot());
1823 while (SDNode *
N = getNextWorklistEntry()) {
1827 if (recursivelyDeleteUnusedNodes(
N))
1830 WorklistRemover DeadNodes(*
this);
1835 SmallSetVector<SDNode *, 16> UpdatedNodes;
1838 for (SDNode *LN : UpdatedNodes)
1839 AddToWorklistWithUsers(LN);
1851 for (
const SDValue &ChildN :
N->op_values())
1852 AddToWorklist(ChildN.getNode(),
true,
1863 ChainsWithoutMergeableStores.
clear();
1874 "Node was deleted but visit returned new node!");
1882 N->getNumValues() == 1 &&
"Type mismatch");
1892 AddToWorklistWithUsers(RV.
getNode());
1898 recursivelyDeleteUnusedNodes(
N);
1902 DAG.
setRoot(Dummy.getValue());
1906SDValue DAGCombiner::visit(SDNode *
N) {
1908 switch (
N->getOpcode()) {
1935 case ISD::MUL:
return visitMUL<EmptyMatchContext>(
N);
1999 case ISD::FMA:
return visitFMA<EmptyMatchContext>(
N);
2052 return visitPARTIAL_REDUCE_MLA(
N);
2078#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) case ISD::SDOPC:
2079#include "llvm/IR/VPIntrinsics.def"
2080 return visitVPOp(
N);
2086SDValue DAGCombiner::combine(SDNode *
N) {
2091 if (!DisableGenericCombines)
2097 "Node was deleted but visit returned NULL!");
2103 TargetLowering::DAGCombinerInfo
2104 DagCombineInfo(DAG, Level,
false,
this);
2112 switch (
N->getOpcode()) {
2120 RV = PromoteIntBinOp(
SDValue(
N, 0));
2125 RV = PromoteIntShiftOp(
SDValue(
N, 0));
2161 if (
unsigned NumOps =
N->getNumOperands()) {
2162 if (
N->getOperand(0).getValueType() == MVT::Other)
2163 return N->getOperand(0);
2164 if (
N->getOperand(
NumOps-1).getValueType() == MVT::Other)
2165 return N->getOperand(
NumOps-1);
2166 for (
unsigned i = 1; i <
NumOps-1; ++i)
2167 if (
N->getOperand(i).getValueType() == MVT::Other)
2168 return N->getOperand(i);
2173SDValue DAGCombiner::visitFCANONICALIZE(SDNode *
N) {
2174 SDValue Operand =
N->getOperand(0);
2186SDValue DAGCombiner::visitTokenFactor(SDNode *
N) {
2189 if (
N->getNumOperands() == 2) {
2191 return N->getOperand(0);
2193 return N->getOperand(1);
2208 AddToWorklist(*(
N->user_begin()));
2212 SmallPtrSet<SDNode*, 16> SeenOps;
2220 for (
unsigned i = 0; i < TFs.
size(); ++i) {
2225 for (
unsigned j = i;
j < TFs.
size();
j++)
2226 Ops.emplace_back(TFs[j], 0);
2233 SDNode *TF = TFs[i];
2236 switch (
Op.getOpcode()) {
2254 if (SeenOps.
insert(
Op.getNode()).second)
2265 for (
unsigned i = 1, e = TFs.
size(); i < e; i++)
2266 AddToWorklist(TFs[i]);
2276 SmallVector<unsigned, 8> OpWorkCount;
2277 SmallPtrSet<SDNode *, 16> SeenChains;
2278 bool DidPruneOps =
false;
2280 unsigned NumLeftToConsider = 0;
2282 Worklist.
push_back(std::make_pair(
Op.getNode(), NumLeftToConsider++));
2286 auto AddToWorklist = [&](
unsigned CurIdx, SDNode *
Op,
unsigned OpNumber) {
2292 unsigned OrigOpNumber = 0;
2293 while (OrigOpNumber <
Ops.size() &&
Ops[OrigOpNumber].getNode() !=
Op)
2296 "expected to find TokenFactor Operand");
2298 for (
unsigned i = CurIdx + 1; i < Worklist.
size(); ++i) {
2299 if (Worklist[i].second == OrigOpNumber) {
2300 Worklist[i].second = OpNumber;
2303 OpWorkCount[OpNumber] += OpWorkCount[OrigOpNumber];
2304 OpWorkCount[OrigOpNumber] = 0;
2305 NumLeftToConsider--;
2308 if (SeenChains.
insert(
Op).second) {
2309 OpWorkCount[OpNumber]++;
2314 for (
unsigned i = 0; i < Worklist.
size() && i < 1024; ++i) {
2316 if (NumLeftToConsider <= 1)
2318 auto CurNode = Worklist[i].first;
2319 auto CurOpNumber = Worklist[i].second;
2320 assert((OpWorkCount[CurOpNumber] > 0) &&
2321 "Node should not appear in worklist");
2322 switch (CurNode->getOpcode()) {
2328 NumLeftToConsider++;
2331 for (
const SDValue &
Op : CurNode->op_values())
2332 AddToWorklist(i,
Op.getNode(), CurOpNumber);
2338 AddToWorklist(i, CurNode->getOperand(0).getNode(), CurOpNumber);
2342 AddToWorklist(i, MemNode->getChain().getNode(), CurOpNumber);
2345 OpWorkCount[CurOpNumber]--;
2346 if (OpWorkCount[CurOpNumber] == 0)
2347 NumLeftToConsider--;
2361 if (SeenChains.
count(
Op.getNode()) == 0)
2375SDValue DAGCombiner::visitMERGE_VALUES(SDNode *
N) {
2376 WorklistRemover DeadNodes(*
this);
2382 AddUsersToWorklist(
N);
2387 }
while (!
N->use_empty());
2388 deleteAndRecombine(
N);
2396 return Const !=
nullptr && !Const->isOpaque() ? Const :
nullptr;
2406 Op =
N->getOperand(0);
2408 if (
N->getFlags().hasNoUnsignedWrap())
2413 if (
N.getValueType().getScalarType() != MVT::i1 ||
2430 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2432 VT = LD->getMemoryVT();
2433 AS = LD->getAddressSpace();
2435 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2437 VT = ST->getMemoryVT();
2438 AS = ST->getAddressSpace();
2440 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2442 VT = LD->getMemoryVT();
2443 AS = LD->getAddressSpace();
2445 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2447 VT = ST->getMemoryVT();
2448 AS = ST->getAddressSpace();
2454 if (
N->isAnyAdd()) {
2463 }
else if (
N->getOpcode() ==
ISD::SUB) {
2485 bool ShouldCommuteOperands) {
2491 if (ShouldCommuteOperands)
2505 unsigned Opcode =
N->getOpcode();
2506 EVT VT =
N->getValueType(0);
2511 unsigned OpNo = ShouldCommuteOperands ? 0 : 1;
2531SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
2534 "Unexpected binary operator");
2546 unsigned SelOpNo = 0;
2583 bool CanFoldNonConst =
2589 if (!CanFoldNonConst &&
2598 if (CanFoldNonConst) {
2617 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CT, CBO});
2622 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CF, CBO});
2633 "Expecting add or sub");
2638 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2639 SDValue C = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2640 SDValue Z = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2646 if (Z.getOperand(0).getValueType() != MVT::i1)
2658 EVT VT =
C.getValueType();
2666SDValue DAGCombiner::foldSubToAvg(SDNode *
N,
const SDLoc &
DL) {
2671 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
2676 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
2687SDValue DAGCombiner::visitPTRADD(SDNode *
N) {
2697 "PTRADD with different operand types is not supported");
2708 !reassociationCanBreakAddressingModePattern(
ISD::PTRADD,
DL,
N, N0, N1)) {
2719 if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
2724 AddToWorklist(
Add.getNode());
2748 if (
const GlobalAddressSDNode *GA =
2763 AddToWorklist(Inner.
getNode());
2785 SDNodeFlags CommonFlags =
N->getFlags() & N1->
getFlags();
2793 if (ZIsConstant != YIsConstant) {
2797 AddToWorklist(Inner.
getNode());
2807 bool TransformCannotBreakAddrMode =
none_of(
N->users(), [&](SDNode *User) {
2808 return canFoldInAddressingMode(N, User, DAG, TLI);
2811 if (TransformCannotBreakAddrMode)
2823 "Expecting add or sub");
2827 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2828 SDValue ConstantOp = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2829 SDValue ShiftOp = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2851 {ConstantOp, DAG.getConstant(1, DL, VT)})) {
2853 Not.getOperand(0), ShAmt);
2869SDValue DAGCombiner::visitADDLike(SDNode *
N) {
2895 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
2927 if ((!LegalOperations ||
2930 X.getScalarValueSizeInBits() == 1) {
2946 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
2950 if (!reassociationCanBreakAddressingModePattern(
ISD::ADD,
DL,
N, N0, N1)) {
3037 auto MatchUSUBSAT = [](ConstantSDNode *
Max, ConstantSDNode *
Op) {
3038 return (!Max && !
Op) ||
3039 (
Max &&
Op &&
Max->getAPIntValue() == (-
Op->getAPIntValue()));
3080 !
N->getFlags().hasNoSignedWrap()))) {
3101 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3105 if (
N->getFlags().hasNoUnsignedWrap() &&
3109 if (
N->getFlags().hasNoSignedWrap() &&
3118 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3126 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3132 if (
N->getFlags().hasNoUnsignedWrap() &&
3137 if (
N->getFlags().hasNoSignedWrap() &&
3148 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3153 if (
SDValue Combined = visitADDLikeCommutative(N0, N1,
N))
3156 if (
SDValue Combined = visitADDLikeCommutative(N1, N0,
N))
3164SDValue DAGCombiner::foldAddToAvg(SDNode *
N,
const SDLoc &
DL) {
3193SDValue DAGCombiner::visitADD(SDNode *
N) {
3199 if (
SDValue Combined = visitADDLike(
N))
3208 if (
SDValue V = MatchRotate(N0, N1, SDLoc(
N),
true))
3242 APInt NewStep = C0 + C1;
3252 APInt NewStep = SV0 + SV1;
3260SDValue DAGCombiner::visitADDSAT(SDNode *
N) {
3261 unsigned Opcode =
N->getOpcode();
3279 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
3283 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
3303 bool ForceCarryReconstruction =
false) {
3308 if (ForceCarryReconstruction && V.getValueType() == MVT::i1)
3312 V = V.getOperand(0);
3317 if (ForceCarryReconstruction)
3321 V = V.getOperand(0);
3329 if (V.getResNo() != 1)
3336 EVT VT = V->getValueType(0);
3380 SDNode *LocReference) {
3382 SDLoc
DL(LocReference);
3444 if (TN->
getVT() == MVT::i1) {
3461 DAG.
getVTList(VT, Carry.getValueType()), N0,
3467SDValue DAGCombiner::visitADDC(SDNode *
N) {
3474 if (!
N->hasAnyUseOfValue(1))
3514 return V.getOperand(0);
3520SDValue DAGCombiner::visitADDO(SDNode *
N) {
3526 EVT CarryVT =
N->getValueType(1);
3530 if (!
N->hasAnyUseOfValue(1))
3537 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
3562 if (
SDValue Combined = visitUADDOLike(N0, N1,
N))
3565 if (
SDValue Combined = visitUADDOLike(N1, N0,
N))
3596SDValue DAGCombiner::visitADDE(SDNode *
N) {
3615SDValue DAGCombiner::visitUADDO_CARRY(SDNode *
N) {
3629 if (!LegalOperations ||
3639 AddToWorklist(CarryExt.
getNode());
3645 if (
SDValue Combined = visitUADDO_CARRYLike(N0, N1, CarryIn,
N))
3648 if (
SDValue Combined = visitUADDO_CARRYLike(N1, N0, CarryIn,
N))
3795 EVT CarryOutType =
N->getValueType(0);
3811 unsigned CarryInOperandNum =
3813 if (Opcode ==
ISD::USUBO && CarryInOperandNum != 1)
3904SDValue DAGCombiner::visitSADDO_CARRY(SDNode *
N) {
3918 if (!LegalOperations ||
3923 if (
SDValue Combined = visitSADDO_CARRYLike(N0, N1, CarryIn,
N))
3926 if (
SDValue Combined = visitSADDO_CARRYLike(N1, N0, CarryIn,
N))
3938 "Illegal truncation");
3962SDValue DAGCombiner::foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL) {
3964 !(!LegalOperations || hasOperation(
ISD::USUBSAT, DstVT)))
3967 EVT SubVT =
N->getValueType(0);
4035template <
class MatchContextClass>
4058 if ((
BitWidth - Src.getValueType().getScalarSizeInBits()) != BitWidthDiff)
4070 if (!(AndMask.
isMask(AndMaskWidth) && XorMask.
countr_one() >= AndMaskWidth))
4105 if (
SDValue Res = CheckAndFoldMulCase(Mul0, Mul1))
4108 if (
SDValue Res = CheckAndFoldMulCase(Mul1, Mul0))
4146SDValue DAGCombiner::visitSUB(SDNode *
N) {
4166 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4193 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4216 if (
N->getFlags().hasNoUnsignedWrap())
4222 if (
N->getFlags().hasNoSignedWrap())
4248 if (hasOperation(NewOpc, VT))
4393 if (!reassociationCanBreakAddressingModePattern(
ISD::SUB,
DL,
N, N0, N1) &&
4431 if ((!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4441 if (GA->getGlobal() == GB->getGlobal())
4442 return DAG.
getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
4449 if (TN->
getVT() == MVT::i1) {
4502 DAG.
getVTList(VT, Carry.getValueType()), NegX, Zero,
4510 if (!C0->isOpaque()) {
4511 const APInt &C0Val = C0->getAPIntValue();
4512 const APInt &MaybeOnes = ~DAG.computeKnownBits(N1).Zero;
4513 if ((C0Val - MaybeOnes) == (C0Val ^ MaybeOnes))
4519 if ((!LegalOperations || hasOperation(
ISD::ABDS, VT)) &&
4531 if ((!LegalOperations || hasOperation(
ISD::ABDU, VT)) &&
4545SDValue DAGCombiner::visitSUBSAT(SDNode *
N) {
4546 unsigned Opcode =
N->getOpcode();
4567 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4586SDValue DAGCombiner::visitSUBC(SDNode *
N) {
4593 if (!
N->hasAnyUseOfValue(1))
4614SDValue DAGCombiner::visitSUBO(SDNode *
N) {
4620 EVT CarryVT =
N->getValueType(1);
4624 if (!
N->hasAnyUseOfValue(1))
4656SDValue DAGCombiner::visitSUBE(SDNode *
N) {
4668SDValue DAGCombiner::visitUSUBO_CARRY(SDNode *
N) {
4675 if (!LegalOperations ||
4683SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *
N) {
4690 if (!LegalOperations ||
4700SDValue DAGCombiner::visitMULFIX(SDNode *
N) {
4713 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0, Scale);
4722template <
class MatchContextClass>
SDValue DAGCombiner::visitMUL(SDNode *
N) {
4728 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
4729 MatchContextClass Matcher(DAG, TLI,
N);
4744 bool N1IsConst =
false;
4745 bool N1IsOpaqueConst =
false;
4752 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4757 "Splat APInt should be element width");
4767 if (N1IsConst && ConstValue1.
isZero())
4771 if (N1IsConst && ConstValue1.
isOne())
4775 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4779 if (N1IsConst && ConstValue1.
isAllOnes())
4785 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
4789 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap());
4791 return Matcher.getNode(
ISD::SHL,
DL, VT, N0, Trunc, Flags);
4797 unsigned Log2Val = (-ConstValue1).logBase2();
4801 return Matcher.getNode(
4812 SDVTList LoHiVT = DAG.
getVTList(VT, VT);
4815 if (LoHi->hasAnyUseOfValue(1))
4818 if (LoHi->hasAnyUseOfValue(1))
4839 if (!UseVP && N1IsConst &&
4845 APInt MulC = ConstValue1.
abs();
4847 unsigned TZeros = MulC == 2 ? 0 : MulC.
countr_zero();
4849 if ((MulC - 1).isPowerOf2())
4851 else if ((MulC + 1).isPowerOf2())
4856 MathOp ==
ISD::ADD ? (MulC - 1).logBase2() : (MulC + 1).logBase2();
4859 "multiply-by-constant generated out of bounds shift");
4863 TZeros ? DAG.
getNode(MathOp,
DL, VT, Shl,
4905 return Matcher.getNode(
4923 APInt NewStep = C0 * MulVal;
4929 if (!UseVP && (!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4943 SmallBitVector ClearMask;
4945 auto IsClearMask = [&ClearMask](ConstantSDNode *
V) {
4946 if (!V ||
V->isZero()) {
4960 for (
unsigned I = 0;
I != NumElts; ++
I)
4991 EVT NodeType =
Node->getValueType(0);
4992 if (!NodeType.isSimple())
4994 switch (NodeType.getSimpleVT().SimpleTy) {
4995 default:
return false;
4996 case MVT::i8: LC=
isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
4997 case MVT::i16: LC=
isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
4998 case MVT::i32: LC=
isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
4999 case MVT::i64: LC=
isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
5000 case MVT::i128: LC=
isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
5007SDValue DAGCombiner::useDivRem(SDNode *Node) {
5008 if (
Node->use_empty())
5011 unsigned Opcode =
Node->getOpcode();
5016 EVT VT =
Node->getValueType(0);
5030 unsigned OtherOpcode = 0;
5044 for (SDNode *User : Op0->
users()) {
5051 unsigned UserOpc =
User->getOpcode();
5052 if ((UserOpc == Opcode || UserOpc == OtherOpcode || UserOpc == DivRemOpc) &&
5053 User->getOperand(0) == Op0 &&
5054 User->getOperand(1) == Op1) {
5056 if (UserOpc == OtherOpcode) {
5058 combined = DAG.
getNode(DivRemOpc, SDLoc(Node), VTs, Op0, Op1);
5059 }
else if (UserOpc == DivRemOpc) {
5062 assert(UserOpc == Opcode);
5067 CombineTo(User, combined);
5069 CombineTo(User, combined.
getValue(1));
5078 EVT VT =
N->getValueType(0);
5081 unsigned Opc =
N->getOpcode();
5100 if (N0C && N0C->
isZero())
5120SDValue DAGCombiner::visitSDIV(SDNode *
N) {
5123 EVT VT =
N->getValueType(0);
5133 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5150 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5158 if (
SDValue V = visitSDIVLike(N0, N1,
N)) {
5165 if (!
N->getFlags().hasExact()) {
5168 AddToWorklist(
Mul.getNode());
5169 AddToWorklist(
Sub.getNode());
5170 CombineTo(RemNode,
Sub);
5191 if (
C->isZero() ||
C->isOpaque())
5193 if (
C->getAPIntValue().isPowerOf2())
5195 if (
C->getAPIntValue().isNegatedPowerOf2())
5206 EVT VT =
N->getValueType(0);
5231 AddToWorklist(Sign.
getNode());
5237 AddToWorklist(
Add.getNode());
5248 Sra = DAG.
getSelect(
DL, VT, IsOneOrAllOnes, N0, Sra);
5274SDValue DAGCombiner::visitUDIV(SDNode *
N) {
5277 EVT VT =
N->getValueType(0);
5287 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5301 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5304 if (
SDValue V = visitUDIVLike(N0, N1,
N)) {
5311 if (!
N->getFlags().hasExact()) {
5314 AddToWorklist(
Mul.getNode());
5315 AddToWorklist(
Sub.getNode());
5316 CombineTo(RemNode,
Sub);
5341 EVT VT =
N->getValueType(0);
5346 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5347 AddToWorklist(LogBase2.getNode());
5351 AddToWorklist(Trunc.
getNode());
5361 if (
SDValue LogBase2 = BuildLogBase2(N10,
DL)) {
5362 AddToWorklist(LogBase2.getNode());
5366 AddToWorklist(Trunc.
getNode());
5368 AddToWorklist(
Add.getNode());
5396SDValue DAGCombiner::visitREM(SDNode *
N) {
5397 unsigned Opcode =
N->getOpcode();
5400 EVT VT =
N->getValueType(0);
5422 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5435 AddToWorklist(
Add.getNode());
5446 AddToWorklist(
Add.getNode());
5463 if (
SDValue OptimizedRem = buildOptimizedSREM(N0, N1,
N))
5464 return OptimizedRem;
5468 isSigned ? visitSDIVLike(N0, N1,
N) : visitUDIVLike(N0, N1,
N);
5471 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
5472 if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
5474 CombineTo(DivNode, OptimizedDiv);
5477 AddToWorklist(OptimizedDiv.
getNode());
5478 AddToWorklist(
Mul.getNode());
5485 return DivRem.getValue(1);
5508SDValue DAGCombiner::visitMULHS(SDNode *
N) {
5511 EVT VT =
N->getValueType(0);
5524 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5567SDValue DAGCombiner::visitMULHU(SDNode *
N) {
5570 EVT VT =
N->getValueType(0);
5583 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5608 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5623 unsigned SimpleSize =
Simple.getSizeInBits();
5644SDValue DAGCombiner::visitAVG(SDNode *
N) {
5645 unsigned Opcode =
N->getOpcode();
5648 EVT VT =
N->getValueType(0);
5659 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5662 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5688 X.getValueType() ==
Y.getValueType() &&
5689 hasOperation(Opcode,
X.getValueType())) {
5695 X.getValueType() ==
Y.getValueType() &&
5696 hasOperation(Opcode,
X.getValueType())) {
5729 if (IsSigned &&
Add->getFlags().hasNoSignedWrap())
5732 if (!IsSigned &&
Add->getFlags().hasNoUnsignedWrap())
5746SDValue DAGCombiner::visitABD(SDNode *
N) {
5747 unsigned Opcode =
N->getOpcode();
5750 EVT VT =
N->getValueType(0);
5760 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5763 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5778 (!LegalOperations || hasOperation(
ISD::ABS, VT)))
5796SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
5799 bool HiExists =
N->hasAnyUseOfValue(1);
5800 if (!HiExists && (!LegalOperations ||
5803 return CombineTo(
N, Res, Res);
5807 bool LoExists =
N->hasAnyUseOfValue(0);
5808 if (!LoExists && (!LegalOperations ||
5811 return CombineTo(
N, Res, Res);
5815 if (LoExists && HiExists)
5821 AddToWorklist(
Lo.getNode());
5824 (!LegalOperations ||
5826 return CombineTo(
N, LoOpt, LoOpt);
5831 AddToWorklist(
Hi.getNode());
5834 (!LegalOperations ||
5836 return CombineTo(
N, HiOpt, HiOpt);
5842SDValue DAGCombiner::visitSMUL_LOHI(SDNode *
N) {
5848 EVT VT =
N->getValueType(0);
5864 unsigned SimpleSize =
Simple.getSizeInBits();
5876 return CombineTo(
N,
Lo,
Hi);
5883SDValue DAGCombiner::visitUMUL_LOHI(SDNode *
N) {
5889 EVT VT =
N->getValueType(0);
5904 return CombineTo(
N, Zero, Zero);
5910 return CombineTo(
N, N0, Zero);
5917 unsigned SimpleSize =
Simple.getSizeInBits();
5929 return CombineTo(
N,
Lo,
Hi);
5936SDValue DAGCombiner::visitMULO(SDNode *
N) {
5942 EVT CarryVT =
N->getValueType(1);
5963 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
5975 N->getVTList(), N0, N0);
5982 return CombineTo(
N,
And, Cmp);
6020 unsigned Opcode0 = isSignedMinMax(N0, N1, N2, N3, CC);
6074 unsigned Opcode1 = isSignedMinMax(N00, N01, N02, N03, N0CC);
6075 if (!Opcode1 || Opcode0 == Opcode1)
6085 APInt MinCPlus1 = MinC + 1;
6086 if (-MaxC == MinCPlus1 && MinCPlus1.
isPowerOf2()) {
6092 if (MaxC == 0 && MinC != 0 && MinCPlus1.
isPowerOf2()) {
6143 unsigned BW = (C1 + 1).exactLogBase2();
6159SDValue DAGCombiner::visitIMINMAX(SDNode *
N) {
6163 unsigned Opcode =
N->getOpcode();
6179 return C0 > C1 ? N0 : N1;
6181 return C0 > C1 ? N1 : N0;
6187 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
6191 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
6195 if (
SDValue RMINMAX = reassociateOps(Opcode,
DL, N0, N1,
N->getFlags()))
6215 return DAG.
getNode(AltOpcode,
DL, VT, N0, N1);
6227 auto ReductionOpcode = [](
unsigned Opcode) {
6241 if (
SDValue SD = reassociateReduction(ReductionOpcode(Opcode), Opcode,
6242 SDLoc(
N), VT, N0, N1))
6254SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *
N) {
6257 unsigned LogicOpcode =
N->getOpcode();
6282 if (XVT !=
Y.getValueType())
6286 if ((VT.
isVector() || LegalOperations) &&
6296 SDNodeFlags LogicFlags;
6302 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6312 if (XVT !=
Y.getValueType())
6324 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6345 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6360 return DAG.
getNode(HandOpcode,
DL, VT, Logic0, Logic1, S);
6373 if (XVT.
isInteger() && XVT ==
Y.getValueType() &&
6377 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6396 assert(
X.getValueType() ==
Y.getValueType() &&
6397 "Inputs to shuffles are not the same type");
6403 if (!SVN0->hasOneUse() || !SVN1->hasOneUse() ||
6404 !SVN0->getMask().equals(SVN1->getMask()))
6440 SDValue LL, LR, RL, RR, N0CC, N1CC;
6441 if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
6442 !isSetCCEquivalent(N1, RL, RR, N1CC))
6446 "Unexpected operand types for bitwise logic op");
6449 "Unexpected operand types for setcc");
6465 if (LR == RR && CC0 == CC1 && IsInteger) {
6470 bool AndEqZero = IsAnd && CC1 ==
ISD::SETEQ && IsZero;
6472 bool AndGtNeg1 = IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6474 bool OrNeZero = !IsAnd && CC1 ==
ISD::SETNE && IsZero;
6476 bool OrLtZero = !IsAnd && CC1 ==
ISD::SETLT && IsZero;
6482 if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
6484 AddToWorklist(
Or.getNode());
6489 bool AndEqNeg1 = IsAnd && CC1 ==
ISD::SETEQ && IsNeg1;
6491 bool AndLtZero = IsAnd && CC1 ==
ISD::SETLT && IsZero;
6493 bool OrNeNeg1 = !IsAnd && CC1 ==
ISD::SETNE && IsNeg1;
6495 bool OrGtNeg1 = !IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6501 if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
6503 AddToWorklist(
And.getNode());
6517 AddToWorklist(
Add.getNode());
6538 auto MatchDiffPow2 = [&](ConstantSDNode *C0, ConstantSDNode *C1) {
6544 return !C0->
isOpaque() && !C1->isOpaque() && (CMax - CMin).isPowerOf2();
6562 if (LL == RR && LR == RL) {
6569 if (LL == RL && LR == RR) {
6573 (!LegalOperations ||
6596 bool isFMAXNUMFMINNUM_IEEE,
6597 bool isFMAXNUMFMINNUM) {
6608 isFMAXNUMFMINNUM_IEEE
6616 isFMAXNUMFMINNUM_IEEE
6634 isFMAXNUMFMINNUM_IEEE
6643 isFMAXNUMFMINNUM_IEEE
6654 (LogicOp->getOpcode() ==
ISD::AND || LogicOp->getOpcode() ==
ISD::OR) &&
6655 "Invalid Op to combine SETCC with");
6661 !
LHS->hasOneUse() || !
RHS->hasOneUse())
6666 LogicOp,
LHS.getNode(),
RHS.getNode());
6678 EVT VT = LogicOp->getValueType(0);
6701 (isFMAXNUMFMINNUM_IEEE || isFMAXNUMFMINNUM))) &&
6707 SDValue CommonValue, Operand1, Operand2;
6715 }
else if (LHS1 == RHS1) {
6728 }
else if (RHS0 == LHS1) {
6745 bool IsSigned = isSignedIntSetCC(CC);
6749 bool IsOr = (LogicOp->getOpcode() ==
ISD::OR);
6757 DAG, isFMAXNUMFMINNUM_IEEE, isFMAXNUMFMINNUM);
6761 DAG.
getNode(NewOpcode,
DL, OpVT, Operand1, Operand2);
6762 return DAG.
getSetCC(
DL, VT, MinMaxValue, CommonValue, CC);
6767 if (LHS0 == LHS1 && RHS0 == RHS1 && CCL == CCR &&
6771 return DAG.
getSetCC(
DL, VT, LHS0, RHS0, CCL);
6778 LHS0 == RHS0 && LHS1C && RHS1C && OpVT.
isInteger()) {
6779 const APInt &APLhs = LHS1C->getAPIntValue();
6780 const APInt &APRhs = RHS1C->getAPIntValue();
6784 if (APLhs == (-APRhs) &&
6795 }
else if (TargetPreference &
6816 APInt Dif = MaxC - MinC;
6850 EVT CondVT =
Cond.getValueType();
6861 EVT OpVT =
T.getValueType();
6880 if (
SDValue V = foldLogicOfSetCCs(
true, N0, N1,
DL))
6897 APInt
ADDC = ADDI->getAPIntValue();
6898 APInt SRLC = SRLI->getAPIntValue();
6910 CombineTo(N0.
getNode(), NewAdd);
6923bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
6924 EVT LoadResultTy, EVT &ExtVT) {
6933 if (ExtVT == LoadedVT &&
6934 (!LegalOperations ||
6950 if (LegalOperations &&
6960bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
6969 const unsigned ByteShAmt = ShAmt / 8;
6988 if (LdStMemVT.
bitsLT(MemVT))
7003 if (PtrType == MVT::Untyped || PtrType.
isExtended())
7010 if (!
SDValue(Load, 0).hasOneUse())
7013 if (LegalOperations &&
7022 if (
Load->getNumValues() > 2)
7041 if (LegalOperations &&
7048bool DAGCombiner::SearchForAndLoads(SDNode *
N,
7049 SmallVectorImpl<LoadSDNode*> &Loads,
7050 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
7051 ConstantSDNode *Mask,
7052 SDNode *&NodeToMask) {
7056 if (
Op.getValueType().isVector())
7062 "Expected bitwise logic operation");
7063 if (!
C->getAPIntValue().isSubsetOf(
Mask->getAPIntValue()))
7068 if (!
Op.hasOneUse())
7071 switch(
Op.getOpcode()) {
7075 if (isAndLoadExtLoad(Mask, Load,
Load->getValueType(0), ExtVT) &&
7093 unsigned ActiveBits =
Mask->getAPIntValue().countr_one();
7097 Op.getOperand(0).getValueType();
7108 if (!SearchForAndLoads(
Op.getNode(), Loads, NodesWithConsts, Mask,
7119 NodeToMask =
Op.getNode();
7122 for (
unsigned i = 0, e = NodeToMask->
getNumValues(); i < e; ++i) {
7123 MVT VT =
SDValue(NodeToMask, i).getSimpleValueType();
7124 if (VT != MVT::Glue && VT != MVT::Other) {
7126 NodeToMask =
nullptr;
7138bool DAGCombiner::BackwardsPropagateMask(SDNode *
N) {
7143 if (!
Mask->getAPIntValue().isMask())
7151 SmallPtrSet<SDNode*, 2> NodesWithConsts;
7152 SDNode *FixupNode =
nullptr;
7153 if (SearchForAndLoads(
N, Loads, NodesWithConsts, Mask, FixupNode)) {
7166 SDValue(FixupNode, 0), MaskOp);
7168 if (
And.getOpcode() == ISD ::AND)
7173 for (
auto *LogicN : NodesWithConsts) {
7179 if (LogicN->getOpcode() ==
ISD::AND &&
7198 for (
auto *Load : Loads) {
7203 if (
And.getOpcode() == ISD ::AND)
7206 SDValue NewLoad = reduceLoadWidth(
And.getNode());
7208 "Shouldn't be masking the load if it can't be narrowed");
7209 CombineTo(Load, NewLoad, NewLoad.
getValue(1));
7222SDValue DAGCombiner::unfoldExtremeBitClearingToShifts(SDNode *
N) {
7233 unsigned OuterShift;
7234 unsigned InnerShift;
7236 auto matchMask = [&OuterShift, &InnerShift, &
Y](
SDValue M) ->
bool {
7239 OuterShift =
M->getOpcode();
7248 Y =
M->getOperand(1);
7255 else if (matchMask(N0))
7261 EVT VT =
N->getValueType(0);
7278 SDValue And0 =
And->getOperand(0), And1 =
And->getOperand(1);
7288 bool FoundNot =
false;
7291 Src = Src.getOperand(0);
7297 Src = Src.getOperand(0);
7301 if (Src.getOpcode() !=
ISD::SRL || !Src.hasOneUse())
7305 EVT SrcVT = Src.getValueType();
7314 if (!ShiftAmtC || !ShiftAmtC->getAPIntValue().ult(
BitWidth))
7318 Src = Src.getOperand(0);
7325 Src = Src.getOperand(0);
7349 EVT VT =
N->getValueType(0);
7375 unsigned LogicOpcode =
N->getOpcode();
7377 "Expected bitwise logic operation");
7379 if (!LogicOp.hasOneUse() || !ShiftOp.
hasOneUse())
7383 unsigned ShiftOpcode = ShiftOp.
getOpcode();
7384 if (LogicOp.getOpcode() != LogicOpcode ||
7396 if (LogicOp.getOperand(0).getOpcode() == ShiftOpcode &&
7397 LogicOp.getOperand(0).getOperand(1) ==
Y) {
7399 Z = LogicOp.getOperand(1);
7400 }
else if (LogicOp.getOperand(1).getOpcode() == ShiftOpcode &&
7401 LogicOp.getOperand(1).getOperand(1) ==
Y) {
7403 Z = LogicOp.getOperand(0);
7408 EVT VT =
N->getValueType(0);
7412 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift, Z);
7423 unsigned LogicOpcode =
N->getOpcode();
7425 "Expected bitwise logic operation");
7426 if (LeftHand.
getOpcode() != LogicOpcode ||
7447 EVT VT =
N->getValueType(0);
7449 return DAG.
getNode(LogicOpcode,
DL, VT, CombinedShifts, W);
7461 "Must be called with ISD::OR or ISD::AND node");
7475 EVT VT = M.getValueType();
7483SDValue DAGCombiner::visitAND(SDNode *
N) {
7507 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
7524 EVT LoadVT =
MLoad->getMemoryVT();
7530 uint64_t ElementSize =
7532 if (
Splat->getAPIntValue().isMask(ElementSize)) {
7536 LoadVT,
MLoad->getMemOperand(),
MLoad->getAddressingMode(),
7538 bool LoadHasOtherUsers = !N0.
hasOneUse();
7539 CombineTo(
N, NewLoad);
7540 if (LoadHasOtherUsers)
7561 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
7574 auto MatchSubset = [](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
7575 return RHS->getAPIntValue().isSubsetOf(
LHS->getAPIntValue());
7585 APInt
Mask = ~N1C->getAPIntValue();
7610 {N0Op0.getOperand(1)})) {
7643 unsigned EltBitWidth =
Vector->getValueType(0).getScalarSizeInBits();
7644 APInt SplatValue, SplatUndef;
7645 unsigned SplatBitSize;
7652 const bool IsBigEndian =
false;
7654 Vector->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
7655 HasAnyUndefs, EltBitWidth, IsBigEndian);
7659 if (IsSplat && (SplatBitSize % EltBitWidth) == 0) {
7662 SplatValue |= SplatUndef;
7669 for (
unsigned i = 0, n = (SplatBitSize / EltBitWidth); i < n; ++i)
7670 Constant &= SplatValue.
extractBits(EltBitWidth, i * EltBitWidth);
7678 Load->getValueType(0),
7679 Load->getMemoryVT());
7687 switch (
Load->getExtensionType()) {
7688 default:
B =
false;
break;
7700 CombineTo(
N, (N0.
getNode() == Load) ? NewLoad : N0);
7704 Load->getValueType(0), SDLoc(Load),
7705 Load->getChain(),
Load->getBasePtr(),
7706 Load->getOffset(),
Load->getMemoryVT(),
7707 Load->getMemOperand());
7709 if (
Load->getNumValues() == 3) {
7711 SDValue To[] = { NewLoad.getValue(0), NewLoad.getValue(1),
7712 NewLoad.getValue(2) };
7713 CombineTo(Load, To, 3,
true);
7715 CombineTo(Load, NewLoad.getValue(0), NewLoad.getValue(1));
7725 if (
SDValue Shuffle = XformToShuffleWithZero(
N))
7752 EVT MemVT = GN0->getMemoryVT();
7755 if (
SDValue(GN0, 0).hasOneUse() &&
7758 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
7759 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
7762 DAG.
getVTList(VT, MVT::Other), MemVT,
DL,
Ops, GN0->getMemOperand(),
7765 CombineTo(
N, ZExtLoad);
7766 AddToWorklist(ZExtLoad.
getNode());
7775 if (
SDValue Res = reduceLoadWidth(
N))
7783 if (BackwardsPropagateMask(
N))
7787 if (
SDValue Combined = visitANDLike(N0, N1,
N))
7792 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
7823 if (
SDValue Folded = foldBitwiseOpWithNeg(
N,
DL, VT))
7845 X.getOperand(0).getScalarValueSizeInBits() == 1)
7848 X.getOperand(0).getScalarValueSizeInBits() == 1)
7863 EVT MemVT = LN0->getMemoryVT();
7870 ((!LegalOperations && LN0->isSimple()) ||
7874 LN0->getBasePtr(), MemVT, LN0->getMemOperand());
7888 if (
SDValue Shifts = unfoldExtremeBitClearingToShifts(
N))
7908 if (!
C->getAPIntValue().isMask(
7909 LHS.getOperand(0).getValueType().getFixedSizeInBits()))
7916 if (IsAndZeroExtMask(N0, N1))
7925 if (LegalOperations || VT.
isVector())
7938 bool DemandHighBits) {
7939 if (!LegalOperations)
7942 EVT VT =
N->getValueType(0);
7943 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16)
7949 bool LookPassAnd0 =
false;
7950 bool LookPassAnd1 =
false;
7965 LookPassAnd0 =
true;
7975 LookPassAnd1 =
true;
8001 LookPassAnd0 =
true;
8015 LookPassAnd1 =
true;
8024 if (OpSizeInBits > 16) {
8028 if (DemandHighBits && !LookPassAnd0)
8035 if (!LookPassAnd1) {
8036 unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
8044 if (OpSizeInBits > 16) {
8059 if (!
N->hasOneUse())
8062 unsigned Opc =
N.getOpcode();
8080 unsigned MaskByteOffset;
8084 case 0xFF: MaskByteOffset = 0;
break;
8085 case 0xFF00: MaskByteOffset = 1;
break;
8094 case 0xFF0000: MaskByteOffset = 2;
break;
8095 case 0xFF000000: MaskByteOffset = 3;
break;
8100 if (MaskByteOffset == 0 || MaskByteOffset == 2) {
8106 if (!
C ||
C->getZExtValue() != 8)
8114 if (!
C ||
C->getZExtValue() != 8)
8120 if (MaskByteOffset != 0 && MaskByteOffset != 2)
8123 if (!
C ||
C->getZExtValue() != 8)
8128 if (MaskByteOffset != 1 && MaskByteOffset != 3)
8131 if (!
C ||
C->getZExtValue() != 8)
8135 if (Parts[MaskByteOffset])
8150 if (!
C ||
C->getAPIntValue() != 16)
8152 Parts[0] = Parts[1] =
N.getOperand(0).getOperand(0).getNode();
8167 "MatchBSwapHWordOrAndAnd: expecting i32");
8177 if (!Mask0 || !Mask1)
8188 if (!ShiftAmt0 || !ShiftAmt1)
8208 if (!LegalOperations)
8211 EVT VT =
N->getValueType(0);
8229 SDNode *Parts[4] = {};
8249 if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
8277 if (
SDValue V = foldLogicOfSetCCs(
false, N0, N1,
DL))
8286 if (
const ConstantSDNode *N0O1C =
8288 if (
const ConstantSDNode *N1O1C =
8292 const APInt &LHSMask = N0O1C->getAPIntValue();
8293 const APInt &RHSMask = N1O1C->getAPIntValue();
8327 auto peekThroughResize = [](
SDValue V) {
8329 return V->getOperand(0);
8333 SDValue N0Resized = peekThroughResize(N0);
8335 SDValue N1Resized = peekThroughResize(N1);
8340 if (N00 == N1Resized || N01 == N1Resized)
8347 if (peekThroughResize(NotOperand) == N1Resized)
8355 if (peekThroughResize(NotOperand) == N1Resized)
8376 auto peekThroughZext = [](
SDValue V) {
8378 return V->getOperand(0);
8400 Lo.getScalarValueSizeInBits() == (BW / 2) &&
8401 Lo.getValueType() ==
Hi.getValueType()) {
8417SDValue DAGCombiner::visitOR(SDNode *
N) {
8438 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
8460 if ((ZeroN00 != ZeroN01) && (ZeroN10 != ZeroN11)) {
8461 assert((!ZeroN00 || !ZeroN01) &&
"Both inputs zero!");
8462 assert((!ZeroN10 || !ZeroN11) &&
"Both inputs zero!");
8463 bool CanFold =
true;
8465 SmallVector<int, 4>
Mask(NumElts, -1);
8467 for (
int i = 0; i != NumElts; ++i) {
8468 int M0 = SV0->getMaskElt(i);
8469 int M1 = SV1->getMaskElt(i);
8472 bool M0Zero =
M0 < 0 || (ZeroN00 == (
M0 < NumElts));
8473 bool M1Zero =
M1 < 0 || (ZeroN10 == (
M1 < NumElts));
8477 if ((M0Zero &&
M1 < 0) || (M1Zero &&
M0 < 0))
8481 if (M0Zero == M1Zero) {
8486 assert((
M0 >= 0 ||
M1 >= 0) &&
"Undef index!");
8492 Mask[i] = M1Zero ?
M0 % NumElts : (
M1 % NumElts) + NumElts;
8501 return LegalShuffle;
8515 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
8526 if (
SDValue Combined = visitORLike(N0, N1,
DL))
8533 if (
SDValue BSwap = MatchBSwapHWord(
N, N0, N1))
8535 if (
SDValue BSwap = MatchBSwapHWordLow(
N, N0, N1))
8549 auto MatchIntersect = [](ConstantSDNode *C1, ConstantSDNode *C2) {
8569 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
8573 if (
SDValue Rot = MatchRotate(N0, N1,
DL,
false))
8576 if (
SDValue Load = MatchLoadCombine(
N))
8586 if (
SDValue Combined = visitADDLike(
N))
8591 if (LegalOperations || VT.
isVector())
8606 Mask =
Op.getOperand(1);
8607 return Op.getOperand(0);
8650 assert(OppShift && ExtractFrom &&
"Empty SDValue");
8678 bool IsMulOrDiv =
false;
8681 auto SelectOpcode = [&](
unsigned NeededShift,
unsigned MulOrDivVariant) {
8682 IsMulOrDiv = ExtractFrom.
getOpcode() == MulOrDivVariant;
8683 if (!IsMulOrDiv && ExtractFrom.
getOpcode() != NeededShift)
8685 Opcode = NeededShift;
8735 if (Rem != 0 || ResultAmt != OppLHSAmt)
8741 if (OppLHSAmt != ExtractFromAmt - NeededShiftAmt.
zextOrTrunc(
8750 return DAG.
getNode(Opcode,
DL, ResVT, OppShiftLHS, NewShiftNode);
8804 unsigned MaskLoBits = 0;
8806 unsigned Bits =
Log2_64(EltSize);
8808 if (NegBits >= Bits) {
8831 if (PosBits >= MaskLoBits) {
8853 if ((Pos == NegOp1) ||
8877 return Width.
getLoBits(MaskLoBits) == 0;
8878 return Width == EltSize;
8888 SDValue InnerNeg,
bool FromAdd,
8889 bool HasPos,
unsigned PosOpcode,
8890 unsigned NegOpcode,
const SDLoc &
DL) {
8901 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, Shifted,
8902 HasPos ? Pos : Neg);
8915 SDValue InnerNeg,
bool FromAdd,
8916 bool HasPos,
unsigned PosOpcode,
8917 unsigned NegOpcode,
const SDLoc &
DL) {
8930 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, N0, N1,
8931 HasPos ? Pos : Neg);
8976 EVT VT =
LHS.getValueType();
8981 bool HasROTL = hasOperation(
ISD::ROTL, VT);
8982 bool HasROTR = hasOperation(
ISD::ROTR, VT);
8983 bool HasFSHL = hasOperation(
ISD::FSHL, VT);
8984 bool HasFSHR = hasOperation(
ISD::FSHR, VT);
8995 if (LegalOperations && !HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9000 LHS.getOperand(0).getValueType() ==
RHS.getOperand(0).getValueType()) {
9003 MatchRotate(
LHS.getOperand(0),
RHS.getOperand(0),
DL, FromAdd))
9017 if (!LHSShift && !RHSShift)
9032 RHSShift = NewRHSShift;
9037 LHSShift = NewLHSShift;
9040 if (!RHSShift || !LHSShift)
9065 auto MatchRotateSum = [EltSizeInBits](ConstantSDNode *
LHS,
9066 ConstantSDNode *
RHS) {
9067 return (
LHS->getAPIntValue() +
RHS->getAPIntValue()) == EltSizeInBits;
9070 auto ApplyMasks = [&](
SDValue Res) {
9094 bool IsRotate = LHSShiftArg == RHSShiftArg;
9095 if (!IsRotate && !(HasFSHL || HasFSHR)) {
9104 if (CommonOp ==
Or.getOperand(0)) {
9106 Y =
Or.getOperand(1);
9109 if (CommonOp ==
Or.getOperand(1)) {
9111 Y =
Or.getOperand(0);
9118 if (matchOr(LHSShiftArg, RHSShiftArg)) {
9123 }
else if (matchOr(RHSShiftArg, LHSShiftArg)) {
9132 return ApplyMasks(Res);
9145 if (IsRotate && (HasROTL || HasROTR || !(HasFSHL || HasFSHR))) {
9146 bool UseROTL = !LegalOperations || HasROTL;
9148 UseROTL ? LHSShiftAmt : RHSShiftAmt);
9150 bool UseFSHL = !LegalOperations || HasFSHL;
9152 RHSShiftArg, UseFSHL ? LHSShiftAmt : RHSShiftAmt);
9155 return ApplyMasks(Res);
9160 if (!HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9169 SDValue LExtOp0 = LHSShiftAmt;
9170 SDValue RExtOp0 = RHSShiftAmt;
9183 if (IsRotate && (HasROTL || HasROTR)) {
9184 if (
SDValue TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
9185 LExtOp0, RExtOp0, FromAdd, HasROTL,
9189 if (
SDValue TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
9190 RExtOp0, LExtOp0, FromAdd, HasROTR,
9195 if (
SDValue TryL = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt,
9196 RHSShiftAmt, LExtOp0, RExtOp0, FromAdd,
9200 if (
SDValue TryR = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt,
9201 LHSShiftAmt, RExtOp0, LExtOp0, FromAdd,
9251static std::optional<SDByteProvider>
9253 std::optional<uint64_t> VectorIndex,
9254 unsigned StartingIndex = 0) {
9258 return std::nullopt;
9262 if (
Depth && !
Op.hasOneUse() &&
9263 (
Op.getOpcode() !=
ISD::LOAD || !
Op.getValueType().isVector()))
9264 return std::nullopt;
9268 if (
Op.getOpcode() !=
ISD::LOAD && VectorIndex.has_value())
9269 return std::nullopt;
9271 unsigned BitWidth =
Op.getScalarValueSizeInBits();
9273 return std::nullopt;
9275 assert(Index < ByteWidth &&
"invalid index requested");
9278 switch (
Op.getOpcode()) {
9283 return std::nullopt;
9287 return std::nullopt;
9289 if (
LHS->isConstantZero())
9291 if (
RHS->isConstantZero())
9293 return std::nullopt;
9298 return std::nullopt;
9300 uint64_t BitShift = ShiftOp->getZExtValue();
9302 if (BitShift % 8 != 0)
9303 return std::nullopt;
9309 return Index < ByteShift
9312 Depth + 1, VectorIndex, Index);
9319 if (NarrowBitWidth % 8 != 0)
9320 return std::nullopt;
9321 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9323 if (Index >= NarrowByteWidth)
9325 ? std::optional<SDByteProvider>(
9333 Depth + 1, VectorIndex, StartingIndex);
9337 return std::nullopt;
9339 VectorIndex =
OffsetOp->getZExtValue();
9343 if (NarrowBitWidth % 8 != 0)
9344 return std::nullopt;
9345 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9348 if (Index >= NarrowByteWidth)
9349 return std::nullopt;
9357 if (*VectorIndex * NarrowByteWidth > StartingIndex)
9358 return std::nullopt;
9359 if ((*VectorIndex + 1) * NarrowByteWidth <= StartingIndex)
9360 return std::nullopt;
9363 VectorIndex, StartingIndex);
9367 if (!L->isSimple() || L->isIndexed())
9368 return std::nullopt;
9370 unsigned NarrowBitWidth = L->getMemoryVT().getScalarSizeInBits();
9371 if (NarrowBitWidth % 8 != 0)
9372 return std::nullopt;
9373 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9378 if (Index >= NarrowByteWidth)
9380 ? std::optional<SDByteProvider>(
9384 unsigned BPVectorIndex = VectorIndex.value_or(0U);
9389 return std::nullopt;
9404 int64_t FirstOffset) {
9406 unsigned Width = ByteOffsets.
size();
9408 return std::nullopt;
9410 bool BigEndian =
true, LittleEndian =
true;
9411 for (
unsigned i = 0; i < Width; i++) {
9412 int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
9415 if (!BigEndian && !LittleEndian)
9416 return std::nullopt;
9419 assert((BigEndian != LittleEndian) &&
"It should be either big endian or"
9426 switch (
Value.getOpcode()) {
9431 return Value.getOperand(0);
9458SDValue DAGCombiner::mergeTruncStores(StoreSDNode *
N) {
9469 EVT MemVT =
N->getMemoryVT();
9470 if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
9471 !
N->isSimple() ||
N->isIndexed())
9478 unsigned MaxWideNumBits = 64;
9479 unsigned MaxStores = MaxWideNumBits / NarrowNumBits;
9488 if (
Store->getMemoryVT() != MemVT || !
Store->isSimple() ||
9492 Chain =
Store->getChain();
9493 if (MaxStores < Stores.
size())
9497 if (Stores.
size() < 2)
9502 unsigned NumStores = Stores.
size();
9503 unsigned WideNumBits = NumStores * NarrowNumBits;
9504 if (WideNumBits != 16 && WideNumBits != 32 && WideNumBits != 64)
9512 StoreSDNode *FirstStore =
nullptr;
9513 std::optional<BaseIndexOffset>
Base;
9514 for (
auto *Store : Stores) {
9533 if (ShiftAmtC % NarrowNumBits != 0)
9540 Offset = ShiftAmtC / NarrowNumBits;
9546 SourceValue = WideVal;
9547 else if (SourceValue != WideVal) {
9555 SourceValue = WideVal;
9564 int64_t ByteOffsetFromBase = 0;
9567 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9571 if (ByteOffsetFromBase < FirstOffset) {
9573 FirstOffset = ByteOffsetFromBase;
9579 OffsetMap[
Offset] = ByteOffsetFromBase;
9585 assert(FirstStore &&
"First store must be set");
9592 if (!Allowed || !
Fast)
9597 auto checkOffsets = [&](
bool MatchLittleEndian) {
9598 if (MatchLittleEndian) {
9599 for (
unsigned i = 0; i != NumStores; ++i)
9600 if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
9603 for (
unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --
j)
9604 if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
9611 bool NeedBswap =
false;
9612 bool NeedRotate =
false;
9615 if (NarrowNumBits == 8 && checkOffsets(Layout.
isBigEndian()))
9617 else if (NumStores == 2 && checkOffsets(Layout.
isBigEndian()))
9626 "Unexpected store value to merge");
9635 }
else if (NeedRotate) {
9636 assert(WideNumBits % 2 == 0 &&
"Unexpected type for rotate");
9680SDValue DAGCombiner::MatchLoadCombine(SDNode *
N) {
9682 "Can only match load combining against OR nodes");
9685 EVT VT =
N->getValueType(0);
9686 if (VT != MVT::i16 && VT != MVT::i32 && VT != MVT::i64)
9692 assert(
P.hasSrc() &&
"Must be a memory byte provider");
9695 unsigned LoadBitWidth =
Load->getMemoryVT().getScalarSizeInBits();
9697 assert(LoadBitWidth % 8 == 0 &&
9698 "can only analyze providers for individual bytes not bit");
9699 unsigned LoadByteWidth = LoadBitWidth / 8;
9704 std::optional<BaseIndexOffset>
Base;
9707 SmallPtrSet<LoadSDNode *, 8> Loads;
9708 std::optional<SDByteProvider> FirstByteProvider;
9714 unsigned ZeroExtendedBytes = 0;
9715 for (
int i = ByteWidth - 1; i >= 0; --i) {
9722 if (
P->isConstantZero()) {
9725 if (++ZeroExtendedBytes != (ByteWidth -
static_cast<unsigned>(i)))
9729 assert(
P->hasSrc() &&
"provenance should either be memory or zero");
9736 else if (Chain != LChain)
9741 int64_t ByteOffsetFromBase = 0;
9750 if (
L->getMemoryVT().isVector()) {
9751 unsigned LoadWidthInBit =
L->getMemoryVT().getScalarSizeInBits();
9752 if (LoadWidthInBit % 8 != 0)
9754 unsigned ByteOffsetFromVector =
P->SrcOffset * LoadWidthInBit / 8;
9755 Ptr.addToOffset(ByteOffsetFromVector);
9761 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9765 ByteOffsetFromBase += MemoryByteOffset(*
P);
9766 ByteOffsets[i] = ByteOffsetFromBase;
9769 if (ByteOffsetFromBase < FirstOffset) {
9770 FirstByteProvider =
P;
9771 FirstOffset = ByteOffsetFromBase;
9777 assert(!Loads.
empty() &&
"All the bytes of the value must be loaded from "
9778 "memory, so there must be at least one load which produces the value");
9779 assert(
Base &&
"Base address of the accessed memory location must be set");
9782 bool NeedsZext = ZeroExtendedBytes > 0;
9793 if (LegalOperations &&
9801 ArrayRef(ByteOffsets).drop_back(ZeroExtendedBytes), FirstOffset);
9805 assert(FirstByteProvider &&
"must be set");
9809 if (MemoryByteOffset(*FirstByteProvider) != 0)
9818 bool NeedsBswap = IsBigEndianTarget != *IsBigEndian;
9825 if (NeedsBswap && (LegalOperations || NeedsZext) &&
9831 if (NeedsBswap && NeedsZext && LegalOperations &&
9839 *FirstLoad->getMemOperand(), &
Fast);
9840 if (!Allowed || !
Fast)
9845 Chain, FirstLoad->getBasePtr(),
9846 FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
9849 for (LoadSDNode *L : Loads)
9879SDValue DAGCombiner::unfoldMaskedMerge(SDNode *
N) {
9886 EVT VT =
N->getValueType(0);
9908 M =
And.getOperand(XorIdx ? 0 : 1);
9914 if (!matchAndXor(N0, 0, N1) && !matchAndXor(N0, 1, N1) &&
9915 !matchAndXor(N1, 0, N0) && !matchAndXor(N1, 1, N0))
9962SDValue DAGCombiner::visitXOR(SDNode *
N) {
9989 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10001 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10022 if (
SDValue Combined = visitADDLike(
N))
10030 isSetCCEquivalent(N0,
LHS,
RHS, CC,
true) &&
10032 N->use_begin()->getUser()->getOpcode() ==
ISD::AND)) {
10034 LHS.getValueType());
10035 if (!LegalOperations ||
10037 switch (N0Opcode) {
10053 CombineTo(
N, SetCC);
10055 recursivelyDeleteUnusedNodes(N0.
getNode());
10071 AddToWorklist(
V.getNode());
10080 if (isOneUseSetCC(N01) || isOneUseSetCC(N00)) {
10085 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10098 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10108 APInt NotYValue = ~YConst->getAPIntValue();
10124 AddToWorklist(NotX.
getNode());
10129 if (!LegalOperations || hasOperation(
ISD::ABS, VT)) {
10133 SDValue A0 =
A.getOperand(0), A1 =
A.getOperand(1);
10135 if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
10172 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
10183 if (
SDValue MM = unfoldMaskedMerge(
N))
10252 if (!LogicOp.hasOneUse())
10255 unsigned LogicOpcode = LogicOp.getOpcode();
10261 unsigned ShiftOpcode = Shift->
getOpcode();
10264 assert(C1Node &&
"Expected a shift with constant operand");
10267 const APInt *&ShiftAmtVal) {
10268 if (V.getOpcode() != ShiftOpcode || !V.hasOneUse())
10276 ShiftOp = V.getOperand(0);
10281 if (ShiftAmtVal->getBitWidth() != C1Val.
getBitWidth())
10286 bool Overflow =
false;
10287 APInt NewShiftAmt = C1Val.
uadd_ov(*ShiftAmtVal, Overflow);
10292 if (NewShiftAmt.
uge(V.getScalarValueSizeInBits()))
10300 const APInt *C0Val;
10301 if (matchFirstShift(LogicOp.getOperand(0),
X, C0Val))
10302 Y = LogicOp.getOperand(1);
10303 else if (matchFirstShift(LogicOp.getOperand(1),
X, C0Val))
10304 Y = LogicOp.getOperand(0);
10315 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift1, NewShift2,
10325SDValue DAGCombiner::visitShiftByConstant(SDNode *
N) {
10345 switch (
LHS.getOpcode()) {
10369 if (!IsShiftByConstant && !IsCopyOrSelect)
10372 if (IsCopyOrSelect &&
N->hasOneUse())
10377 EVT VT =
N->getValueType(0);
10379 N->getOpcode(),
DL, VT, {LHS.getOperand(1), N->getOperand(1)})) {
10382 return DAG.
getNode(
LHS.getOpcode(),
DL, VT, NewShift, NewRHS);
10388SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *
N) {
10393 EVT TruncVT =
N->getValueType(0);
10394 if (
N->hasOneUse() &&
N->getOperand(0).hasOneUse() &&
10402 AddToWorklist(Trunc00.
getNode());
10403 AddToWorklist(Trunc01.
getNode());
10411SDValue DAGCombiner::visitRotate(SDNode *
N) {
10415 EVT VT =
N->getValueType(0);
10430 bool OutOfRange =
false;
10431 auto MatchOutOfRange = [Bitsize, &OutOfRange](ConstantSDNode *
C) {
10432 OutOfRange |=
C->getAPIntValue().uge(Bitsize);
10440 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, Amt);
10445 if (RotAmtC && RotAmtC->getAPIntValue() == 8 &&
10456 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10457 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, NewOp1);
10469 bool SameSide = (
N->getOpcode() == NextOp);
10476 if (Norm1 && Norm2)
10478 CombineOp, dl, ShiftVT, {Norm1, Norm2})) {
10480 {CombinedShift, BitsizeC});
10482 ISD::UREM, dl, ShiftVT, {CombinedShift, BitsizeC});
10484 CombinedShiftNorm);
10491SDValue DAGCombiner::visitSHL(SDNode *
N) {
10508 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10531 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10541 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10547 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
10548 ConstantSDNode *
RHS) {
10549 APInt c1 =
LHS->getAPIntValue();
10550 APInt c2 =
RHS->getAPIntValue();
10552 return (c1 + c2).uge(OpSizeInBits);
10557 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
10558 ConstantSDNode *
RHS) {
10559 APInt c1 =
LHS->getAPIntValue();
10560 APInt c2 =
RHS->getAPIntValue();
10562 return (c1 + c2).ult(OpSizeInBits);
10584 auto MatchOutOfRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10585 ConstantSDNode *
RHS) {
10586 APInt c1 =
LHS->getAPIntValue();
10587 APInt c2 =
RHS->getAPIntValue();
10589 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10590 (c1 + c2).uge(OpSizeInBits);
10597 auto MatchInRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10598 ConstantSDNode *
RHS) {
10599 APInt c1 =
LHS->getAPIntValue();
10600 APInt c2 =
RHS->getAPIntValue();
10602 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10603 (c1 + c2).ult(OpSizeInBits);
10623 auto MatchEqual = [VT](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
10624 APInt c1 =
LHS->getAPIntValue();
10625 APInt c2 =
RHS->getAPIntValue();
10635 AddToWorklist(NewSHL.
getNode());
10641 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
10642 ConstantSDNode *
RHS) {
10643 const APInt &LHSC =
LHS->getAPIntValue();
10644 const APInt &RHSC =
RHS->getAPIntValue();
10645 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
10717 AddToWorklist(Shl0.
getNode());
10736 {Add.getOperand(1)})) {
10756 if (
SDValue NewSHL = visitShiftByConstant(
N))
10790 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap() &&
10803 APInt NewStep = C0 << ShlVal;
10818 "SRL or SRA node is required here!");
10827 SDValue ShiftOperand =
N->getOperand(0);
10838 if (!IsSignExt && !IsZeroExt)
10845 auto UserOfLowerBits = [NarrowVTSize](
SDNode *U) {
10850 if (!UShiftAmtSrc) {
10854 return UShiftAmt < NarrowVTSize;
10868 unsigned ActiveBits = IsSignExt
10869 ?
Constant->getAPIntValue().getSignificantBits()
10870 :
Constant->getAPIntValue().getActiveBits();
10871 if (ActiveBits > NarrowVTSize)
10888 "Cannot have a multiply node with two different operand types.");
10899 if (ShiftAmt != NarrowVTSize)
10909 EVT TransformVT = NarrowVT;
10920 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
10927 unsigned Opcode =
N->getOpcode();
10932 EVT VT =
N->getValueType(0);
10951SDValue DAGCombiner::visitSRA(SDNode *
N) {
10973 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10976 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10988 auto SumOfShifts = [&](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
10989 APInt c1 =
LHS->getAPIntValue();
10990 APInt c2 =
RHS->getAPIntValue();
10992 APInt Sum = c1 + c2;
10993 unsigned ShiftSum =
10994 Sum.
uge(OpSizeInBits) ? (OpSizeInBits - 1) : Sum.getZExtValue();
11004 "Expected matchBinaryPredicate to return one element for "
11008 ShiftValue = ShiftValues[0];
11022 APInt Sum = C1 + C2;
11026 return DAG.
getNOT(
DL, NewShift, VT);
11052 if ((ShiftAmt > 0) &&
11062 N->getValueType(0), Trunc);
11079 if (ConstantSDNode *AddC =
11097 DAG.
getConstant(AddC->getAPIntValue().lshr(ShiftAmt).trunc(
11114 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11131 if (LargeShift->getAPIntValue() == TruncBits) {
11152 if (
SDValue NewSRA = visitShiftByConstant(
N))
11161 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11170SDValue DAGCombiner::visitSRL(SDNode *
N) {
11187 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11190 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11201 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
11202 ConstantSDNode *
RHS) {
11203 APInt c1 =
LHS->getAPIntValue();
11204 APInt c2 =
RHS->getAPIntValue();
11206 return (c1 + c2).uge(OpSizeInBits);
11211 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
11212 ConstantSDNode *
RHS) {
11213 APInt c1 =
LHS->getAPIntValue();
11214 APInt c2 =
RHS->getAPIntValue();
11216 return (c1 + c2).ult(OpSizeInBits);
11236 if (c1 + OpSizeInBits == InnerShiftSize) {
11237 if (c1 + c2 >= InnerShiftSize)
11247 c1 + c2 < InnerShiftSize) {
11252 OpSizeInBits - c2),
11269 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
11270 ConstantSDNode *
RHS) {
11271 const APInt &LHSC =
LHS->getAPIntValue();
11272 const APInt &RHSC =
RHS->getAPIntValue();
11273 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
11315 AddToWorklist(SmallShift.
getNode());
11343 APInt UnknownBits = ~Known.Zero;
11344 if (UnknownBits == 0)
return DAG.
getConstant(1, SDLoc(N0), VT);
11359 AddToWorklist(
Op.getNode());
11368 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11394 if (
SDValue NewSRL = visitShiftByConstant(
N))
11398 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11425 if (
N->hasOneUse()) {
11426 SDNode *
User = *
N->user_begin();
11434 AddToWorklist(User);
11448SDValue DAGCombiner::visitFunnelShift(SDNode *
N) {
11449 EVT VT =
N->getValueType(0);
11467 return IsFSHL ? N0 : N1;
11469 auto IsUndefOrZero = [](
SDValue V) {
11478 if (Cst->getAPIntValue().uge(
BitWidth)) {
11479 uint64_t RotAmt = Cst->getAPIntValue().urem(
BitWidth);
11480 return DAG.
getNode(
N->getOpcode(),
DL, VT, N0, N1,
11484 unsigned ShAmt = Cst->getZExtValue();
11486 return IsFSHL ? N0 : N1;
11492 if (IsUndefOrZero(N0))
11496 if (IsUndefOrZero(N1))
11510 if (
LHS &&
RHS &&
LHS->isSimple() &&
RHS->isSimple() &&
11511 LHS->getAddressSpace() ==
RHS->getAddressSpace() &&
11512 (
LHS->hasNUsesOfValue(1, 0) ||
RHS->hasNUsesOfValue(1, 0)) &&
11521 RHS->getAddressSpace(), NewAlign,
11522 RHS->getMemOperand()->getFlags(), &
Fast) &&
11526 AddToWorklist(NewPtr.
getNode());
11528 VT,
DL,
RHS->getChain(), NewPtr,
11529 RHS->getPointerInfo().getWithOffset(PtrOff), NewAlign,
11530 RHS->getMemOperand()->getFlags(),
RHS->getAAInfo());
11558 if (N0 == N1 && hasOperation(RotOpc, VT))
11559 return DAG.
getNode(RotOpc,
DL, VT, N0, N2);
11568SDValue DAGCombiner::visitSHLSAT(SDNode *
N) {
11603SDValue DAGCombiner::foldABSToABD(SDNode *
N,
const SDLoc &
DL) {
11604 EVT SrcVT =
N->getValueType(0);
11607 N =
N->getOperand(0).getNode();
11609 EVT VT =
N->getValueType(0);
11615 SDValue AbsOp0 =
N->getOperand(0);
11652 EVT MaxVT = VT0.
bitsGT(VT1) ? VT0 : VT1;
11653 if ((VT0 == MaxVT || Op0->
hasOneUse()) &&
11655 (!LegalTypes || hasOperation(ABDOpcode, MaxVT))) {
11665 if (!LegalOperations || hasOperation(ABDOpcode, VT)) {
11673SDValue DAGCombiner::visitABS(SDNode *
N) {
11675 EVT VT =
N->getValueType(0);
11708SDValue DAGCombiner::visitBSWAP(SDNode *
N) {
11710 EVT VT =
N->getValueType(0);
11735 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
11736 ShAmt->getZExtValue() >= (BW / 2) &&
11737 (ShAmt->getZExtValue() % 16) == 0 && TLI.
isTypeLegal(HalfVT) &&
11739 (!LegalOperations || hasOperation(
ISD::BSWAP, HalfVT))) {
11741 if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2)))
11757 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
11758 ShAmt->getZExtValue() % 8 == 0) {
11771SDValue DAGCombiner::visitBITREVERSE(SDNode *
N) {
11773 EVT VT =
N->getValueType(0);
11799SDValue DAGCombiner::visitCTLZ(SDNode *
N) {
11801 EVT VT =
N->getValueType(0);
11816SDValue DAGCombiner::visitCTLZ_ZERO_UNDEF(SDNode *
N) {
11818 EVT VT =
N->getValueType(0);
11828SDValue DAGCombiner::visitCTTZ(SDNode *
N) {
11830 EVT VT =
N->getValueType(0);
11845SDValue DAGCombiner::visitCTTZ_ZERO_UNDEF(SDNode *
N) {
11847 EVT VT =
N->getValueType(0);
11857SDValue DAGCombiner::visitCTPOP(SDNode *
N) {
11859 EVT VT =
N->getValueType(0);
11871 const APInt &Amt = AmtC->getAPIntValue();
11872 if (Amt.
ult(NumBits)) {
11906 EVT VT =
LHS.getValueType();
11910 return Flags.hasNoSignedZeros() &&
11912 (Flags.hasNoNaNs() ||
11962SDValue DAGCombiner::foldShiftToAvg(SDNode *
N,
const SDLoc &
DL) {
11963 const unsigned Opcode =
N->getOpcode();
11967 EVT VT =
N->getValueType(0);
11968 bool IsUnsigned = Opcode ==
ISD::SRL;
11979 if (!hasOperation(FloorISD, VT))
11983 if ((IsUnsigned && !
Add->getFlags().hasNoUnsignedWrap()) ||
11984 (!IsUnsigned && !
Add->getFlags().hasNoSignedWrap()))
11987 return DAG.
getNode(FloorISD,
DL,
N->getValueType(0), {A, B});
11993SDValue DAGCombiner::foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT) {
11994 unsigned Opc =
N->getOpcode();
12013 if ((
LHS == True &&
RHS == False) || (
LHS == False &&
RHS == True))
12019 True, DAG, LegalOperations, ForCodeSize);
12023 HandleSDNode NegTrueHandle(NegTrue);
12031 if (
LHS == NegTrue) {
12035 RHS, DAG, LegalOperations, ForCodeSize);
12037 HandleSDNode NegRHSHandle(NegRHS);
12038 if (NegRHS == False) {
12040 False, CC, TLI, DAG);
12060 EVT VT =
N->getValueType(0);
12062 VT !=
Cond.getOperand(0).getValueType())
12105SDValue DAGCombiner::foldSelectOfConstants(SDNode *
N) {
12109 EVT VT =
N->getValueType(0);
12110 EVT CondVT =
Cond.getValueType();
12121 if (CondVT != MVT::i1 || LegalOperations) {
12136 C1->
isZero() && C2->isOne()) {
12151 assert(CondVT == MVT::i1 && !LegalOperations);
12154 if (C1->
isOne() && C2->isZero())
12162 if (C1->
isZero() && C2->isOne()) {
12169 if (C1->
isZero() && C2->isAllOnes()) {
12182 const APInt &C1Val = C1->getAPIntValue();
12183 const APInt &C2Val = C2->getAPIntValue();
12186 if (C1Val - 1 == C2Val) {
12192 if (C1Val + 1 == C2Val) {
12212 if (C2->isAllOnes()) {
12224template <
class MatchContextClass>
12228 N->getOpcode() == ISD::VP_SELECT) &&
12229 "Expected a (v)(vp.)select");
12231 SDValue T =
N->getOperand(1),
F =
N->getOperand(2);
12232 EVT VT =
N->getValueType(0);
12234 MatchContextClass matcher(DAG, TLI,
N);
12270 EVT VT =
N->getValueType(0);
12334 EVT VT =
LHS.getValueType();
12336 if (LegalOperations && !hasOperation(ABDOpc, VT))
12349 hasOperation(ABDOpc, VT))
12361 hasOperation(ABDOpc, VT))
12395SDValue DAGCombiner::visitSELECT(SDNode *
N) {
12399 EVT VT =
N->getValueType(0);
12402 SDNodeFlags
Flags =
N->getFlags();
12414 if (
SDValue V = foldSelectOfConstants(
N))
12418 if (SimplifySelectOps(
N, N1, N2))
12421 if (VT0 == MVT::i1) {
12430 bool normalizeToSequence =
12439 if (normalizeToSequence || !InnerSelect.
use_empty())
12441 InnerSelect, N2, Flags);
12444 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12451 Cond1, N1, N2, Flags);
12452 if (normalizeToSequence || !InnerSelect.
use_empty())
12454 InnerSelect, Flags);
12457 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12467 if (!normalizeToSequence) {
12473 if (
SDValue Combined = visitANDLike(N0, N1_0,
N)) {
12486 if (!normalizeToSequence) {
12492 if (
SDValue Combined = visitORLike(N0, N2_0,
DL))
12528 combineMinNumMaxNum(
DL, VT, Cond0, Cond1, N1, N2, CC))
12541 if (
C && NotC &&
C->getAPIntValue() == ~NotC->getAPIntValue()) {
12561 (!LegalOperations &&
12569 if (
SDValue ABD = foldSelectToABD(Cond0, Cond1, N1, N2, CC,
DL))
12572 if (
SDValue NewSel = SimplifySelect(
DL, N0, N1, N2))
12577 if (
SDValue UMin = foldSelectToUMin(Cond0, Cond1, N1, N2, CC,
DL))
12582 if (
SDValue BinOp = foldSelectOfBinops(
N))
12598 EVT VT =
N->getValueType(0);
12606 if (
LHS->getNumOperands() != 2 ||
RHS->getNumOperands() != 2)
12615 for (
int i = 0; i < NumElems / 2; ++i) {
12616 if (
Cond->getOperand(i)->isUndef())
12619 if (BottomHalf ==
nullptr)
12621 else if (
Cond->getOperand(i).getNode() != BottomHalf)
12627 for (
int i = NumElems / 2; i < NumElems; ++i) {
12628 if (
Cond->getOperand(i)->isUndef())
12631 if (TopHalf ==
nullptr)
12633 else if (
Cond->getOperand(i).getNode() != TopHalf)
12637 assert(TopHalf && BottomHalf &&
12638 "One half of the selector was all UNDEFs and the other was all the "
12639 "same value. This should have been addressed before this function.");
12642 BottomHalf->
isZero() ?
RHS->getOperand(0) :
LHS->getOperand(0),
12643 TopHalf->
isZero() ?
RHS->getOperand(1) :
LHS->getOperand(1));
12656 EVT VT = BasePtr.getValueType();
12660 SplatVal.getValueType() == VT) {
12666 if (Index.getOpcode() !=
ISD::ADD)
12693 Index = Index.getOperand(0);
12706 Index = Index.getOperand(0);
12713SDValue DAGCombiner::visitVPSCATTER(SDNode *
N) {
12744SDValue DAGCombiner::visitMSCATTER(SDNode *
N) {
12776SDValue DAGCombiner::visitMSTORE(SDNode *
N) {
12790 MST1->isSimple() && MST1->getBasePtr() == Ptr &&
12793 MST1->getMemoryVT().getStoreSize()) ||
12797 CombineTo(MST1, MST1->getChain());
12814 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
12818 Value.getValueType().isInteger() &&
12821 APInt TruncDemandedBits =
12847 Value.getOperand(0).getValueType());
12857SDValue DAGCombiner::visitVP_STRIDED_STORE(SDNode *
N) {
12859 EVT EltVT = SST->getValue().getValueType().getVectorElementType();
12862 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
12863 return DAG.
getStoreVP(SST->getChain(), SDLoc(
N), SST->getValue(),
12864 SST->getBasePtr(), SST->getOffset(), SST->getMask(),
12865 SST->getVectorLength(), SST->getMemoryVT(),
12866 SST->getMemOperand(), SST->getAddressingMode(),
12867 SST->isTruncatingStore(), SST->isCompressingStore());
12872SDValue DAGCombiner::visitVECTOR_COMPRESS(SDNode *
N) {
12876 SDValue Passthru =
N->getOperand(2);
12879 bool HasPassthru = !Passthru.
isUndef();
12892 unsigned NumSelected = 0;
12894 for (
unsigned I = 0;
I < NumElmts; ++
I) {
12903 Ops.push_back(VecI);
12907 for (
unsigned Rest = NumSelected; Rest < NumElmts; ++Rest) {
12913 Ops.push_back(Val);
12921SDValue DAGCombiner::visitVPGATHER(SDNode *
N) {
12949SDValue DAGCombiner::visitMGATHER(SDNode *
N) {
12962 return CombineTo(
N, PassThru, MGT->
getChain());
12981SDValue DAGCombiner::visitMLOAD(SDNode *
N) {
12997 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13001 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13007SDValue DAGCombiner::visitMHISTOGRAM(SDNode *
N) {
13017 EVT DataVT =
Index.getValueType();
13035SDValue DAGCombiner::visitPARTIAL_REDUCE_MLA(SDNode *
N) {
13036 if (
SDValue Res = foldPartialReduceMLAMulOp(
N))
13038 if (
SDValue Res = foldPartialReduceAdd(
N))
13054SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *
N) {
13086 RHS.getValueType().getScalarType()));
13094 auto IsIntOrFPExtOpcode = [](
unsigned int Opcode) {
13098 unsigned LHSOpcode =
LHS->getOpcode();
13099 if (!IsIntOrFPExtOpcode(LHSOpcode))
13110 EVT OpVT =
Op.getValueType();
13124 unsigned LHSBits =
LHS.getValueType().getScalarSizeInBits();
13141 ApplyPredicate(
C, LHSExtOp);
13142 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, LHSExtOp,
C);
13145 unsigned RHSOpcode =
RHS->getOpcode();
13146 if (!IsIntOrFPExtOpcode(RHSOpcode))
13173 NewOpc !=
N->getOpcode())
13183 ApplyPredicate(RHSExtOp, LHSExtOp);
13184 return DAG.
getNode(NewOpc,
DL,
N->getValueType(0), Acc, LHSExtOp, RHSExtOp);
13194SDValue DAGCombiner::foldPartialReduceAdd(SDNode *
N) {
13219 if (Op1IsSigned != NodeIsSigned &&
13246 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, UnextOp1,
13250SDValue DAGCombiner::visitVP_STRIDED_LOAD(SDNode *
N) {
13255 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13257 SLD->getAddressingMode(), SLD->getExtensionType(), SLD->getValueType(0),
13258 SDLoc(
N), SLD->getChain(), SLD->getBasePtr(), SLD->getOffset(),
13259 SLD->getMask(), SLD->getVectorLength(), SLD->getMemoryVT(),
13260 SLD->getMemOperand(), SLD->isExpandingLoad());
13261 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13268SDValue DAGCombiner::foldVSelectOfConstants(SDNode *
N) {
13272 EVT VT =
N->getValueType(0);
13273 if (!
Cond.hasOneUse() ||
Cond.getScalarValueSizeInBits() != 1 ||
13282 bool AllAddOne =
true;
13283 bool AllSubOne =
true;
13285 for (
unsigned i = 0; i != Elts; ++i) {
13308 if (AllAddOne || AllSubOne) {
13335SDValue DAGCombiner::visitVP_SELECT(SDNode *
N) {
13359 EVT CondVT =
Cond.getValueType();
13360 assert(CondVT.
isVector() &&
"Vector select expects a vector selector!");
13368 if (!IsTAllZero && !IsTAllOne && !IsFAllZero && !IsFAllOne)
13372 if (IsTAllZero && IsFAllZero) {
13381 Cond.getOperand(0).getValueType() == VT && VT.
isSimple() &&
13383 TValAPInt.
isOne() &&
13402 if (!IsTAllOne && !IsFAllZero &&
Cond.hasOneUse() &&
13406 if (IsTAllZero || IsFAllOne) {
13419 "Select condition no longer all-sign bits");
13422 if (IsTAllOne && IsFAllZero)
13451SDValue DAGCombiner::visitVSELECT(SDNode *
N) {
13455 EVT VT =
N->getValueType(0);
13488 bool isAbs =
false;
13507 AddToWorklist(Shift.
getNode());
13508 AddToWorklist(
Add.getNode());
13520 if (
SDValue FMinMax = combineMinNumMaxNum(
DL, VT,
LHS,
RHS, N1, N2, CC))
13535 EVT NarrowVT =
LHS.getValueType();
13543 SetCCWidth != 1 && SetCCWidth < WideWidth &&
13589 (OpLHS == CondLHS || OpRHS == CondLHS))
13592 if (OpRHS.getOpcode() == CondRHS.getOpcode() &&
13595 CondLHS == OpLHS) {
13599 auto MatchUADDSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13600 return Cond->getAPIntValue() == ~Op->getAPIntValue();
13641 if (OpLHS ==
LHS) {
13656 auto MatchUSUBSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13657 return (!
Op && !
Cond) ||
13659 Cond->getAPIntValue() == (-
Op->getAPIntValue() - 1));
13695 if (SimplifySelectOps(
N, N1, N2))
13715 if (
SDValue V = foldVSelectOfConstants(
N))
13731SDValue DAGCombiner::visitSELECT_CC(SDNode *
N) {
13752 AddToWorklist(
SCC.getNode());
13757 return SCCC->isZero() ? N3 : N2;
13761 if (
SCC->isUndef())
13767 SCC.getOperand(0),
SCC.getOperand(1), N2, N3,
13768 SCC.getOperand(2),
SCC->getFlags());
13773 if (SimplifySelectOps(
N, N2, N3))
13777 return SimplifySelectCC(
DL, N0, N1, N2, N3, CC);
13780SDValue DAGCombiner::visitSETCC(SDNode *
N) {
13785 N->hasOneUse() &&
N->user_begin()->getOpcode() ==
ISD::BRCOND;
13788 EVT VT =
N->getValueType(0);
13795 if (PreferSetCC && Combined.getOpcode() !=
ISD::SETCC) {
13796 SDValue NewSetCC = rebuildSetCC(Combined);
13824 A.getOperand(0) ==
B.getOperand(0);
13828 B.getOperand(0) ==
A;
13831 bool IsRotate =
false;
13834 if (IsAndWithShift(N0, N1)) {
13836 ShiftOrRotate = N1;
13837 }
else if (IsAndWithShift(N1, N0)) {
13839 ShiftOrRotate = N0;
13840 }
else if (IsRotateWithOp(N0, N1)) {
13843 ShiftOrRotate = N1;
13844 }
else if (IsRotateWithOp(N1, N0)) {
13847 ShiftOrRotate = N0;
13850 if (AndOrOp && ShiftOrRotate && ShiftOrRotate.hasOneUse() &&
13855 auto GetAPIntValue = [](
SDValue Op) -> std::optional<APInt> {
13858 if (CNode ==
nullptr)
13859 return std::nullopt;
13862 std::optional<APInt> AndCMask =
13863 IsRotate ? std::nullopt : GetAPIntValue(AndOrOp.
getOperand(1));
13864 std::optional<APInt> ShiftCAmt =
13865 GetAPIntValue(ShiftOrRotate.getOperand(1));
13869 if (ShiftCAmt && (IsRotate || AndCMask) && ShiftCAmt->ult(NumBits)) {
13870 unsigned ShiftOpc = ShiftOrRotate.getOpcode();
13872 bool CanTransform = IsRotate;
13873 if (!CanTransform) {
13875 CanTransform = *ShiftCAmt == (~*AndCMask).
popcount();
13877 CanTransform &= (*ShiftCAmt + AndCMask->popcount()) == NumBits;
13885 OpVT, ShiftOpc, ShiftCAmt->isPowerOf2(), *ShiftCAmt, AndCMask);
13887 if (CanTransform && NewShiftOpc != ShiftOpc) {
13889 DAG.
getNode(NewShiftOpc,
DL, OpVT, ShiftOrRotate.getOperand(0),
13890 ShiftOrRotate.getOperand(1));
13897 NumBits - ShiftCAmt->getZExtValue())
13898 : APInt::getLowBitsSet(NumBits,
13899 NumBits - ShiftCAmt->getZExtValue());
13907 return DAG.
getSetCC(
DL, VT, NewAndOrOp, NewShiftOrRotate,
Cond);
13915SDValue DAGCombiner::visitSETCCCARRY(SDNode *
N) {
13936 if (!
N.hasOneUse())
13965 unsigned Opcode =
N->getOpcode();
13967 EVT VT =
N->getValueType(0);
13970 "Expected EXTEND dag node in input!");
14010 unsigned Opcode =
N->getOpcode();
14012 EVT VT =
N->getValueType(0);
14015 "Expected EXTEND dag node in input!");
14021 return DAG.
getNode(Opcode,
DL, VT, N0);
14040 unsigned FoldOpc = Opcode;
14063 for (
unsigned i = 0; i != NumElts; ++i) {
14065 if (
Op.isUndef()) {
14076 APInt C =
Op->getAsAPIntVal().zextOrTrunc(EVTBits);
14094 bool HasCopyToRegUses =
false;
14109 for (
unsigned i = 0; i != 2; ++i) {
14127 HasCopyToRegUses =
true;
14130 if (HasCopyToRegUses) {
14131 bool BothLiveOut =
false;
14134 BothLiveOut =
true;
14141 return !ExtendNodes.
empty();
14146void DAGCombiner::ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
14151 for (SDNode *SetCC : SetCCs) {
14154 for (
unsigned j = 0;
j != 2; ++
j) {
14155 SDValue SOp = SetCC->getOperand(j);
14156 if (SOp == OrigLoad)
14157 Ops.push_back(ExtLoad);
14162 Ops.push_back(SetCC->getOperand(2));
14168SDValue DAGCombiner::CombineExtLoad(SDNode *
N) {
14170 EVT DstVT =
N->getValueType(0);
14175 "Unexpected node type (not an extend)!");
14213 EVT SplitSrcVT = SrcVT;
14214 EVT SplitDstVT = DstVT;
14227 const unsigned NumSplits =
14234 for (
unsigned Idx = 0; Idx < NumSplits; Idx++) {
14235 const unsigned Offset = Idx * Stride;
14253 AddToWorklist(NewChain.
getNode());
14255 CombineTo(
N, NewValue);
14261 ExtendSetCCUses(SetCCs, N0, NewValue, (
ISD::NodeType)
N->getOpcode());
14262 CombineTo(N0.
getNode(), Trunc, NewChain);
14268SDValue DAGCombiner::CombineZExtLogicopShiftLoad(SDNode *
N) {
14270 EVT VT =
N->getValueType(0);
14271 EVT OrigVT =
N->getOperand(0).getValueType();
14293 EVT MemVT =
Load->getMemoryVT();
14314 Load->getChain(),
Load->getBasePtr(),
14315 Load->getMemoryVT(),
Load->getMemOperand());
14328 if (
SDValue(Load, 0).hasOneUse()) {
14332 Load->getValueType(0), ExtLoad);
14333 CombineTo(Load, Trunc, ExtLoad.
getValue(1));
14337 recursivelyDeleteUnusedNodes(N0.
getNode());
14346SDValue DAGCombiner::matchVSelectOpSizesWithSetCC(SDNode *Cast) {
14347 unsigned CastOpcode = Cast->
getOpcode();
14351 "Unexpected opcode for vector select narrowing/widening");
14391 bool LegalOperations,
SDNode *
N,
14402 if ((LegalOperations || !LN0->
isSimple() ||
14413 Combiner.recursivelyDeleteUnusedNodes(LN0);
14426 bool NonNegZExt =
false) {
14433 "Unexpected load type or opcode");
14454 bool DoXform =
true;
14467 Combiner.ExtendSetCCUses(SetCCs, N0, ExtLoad, ExtOpc);
14469 bool NoReplaceTrunc =
SDValue(LN0, 0).hasOneUse();
14471 if (NoReplaceTrunc) {
14473 Combiner.recursivelyDeleteUnusedNodes(LN0);
14518 EVT MemoryVT = ALoad->getMemoryVT();
14527 EVT OrigVT = ALoad->getValueType(0);
14530 ExtLoadType,
SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
14531 ALoad->getBasePtr(), ALoad->getMemOperand()));
14541 bool LegalOperations) {
14553 EVT VT =
N->getValueType(0);
14554 EVT XVT =
X.getValueType();
14570 return DAG.
getNode(ShiftOpcode,
DL, VT, NotX, ShiftAmount);
14576SDValue DAGCombiner::foldSextSetcc(SDNode *
N) {
14584 EVT VT =
N->getValueType(0);
14589 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
14594 if (VT.
isVector() && !LegalOperations &&
14613 if (SVT == MatchingVecType) {
14629 auto IsFreeToExtend = [&](
SDValue V) {
14643 for (SDUse &Use :
V->uses()) {
14645 SDNode *
User =
Use.getUser();
14646 if (
Use.getResNo() != 0 || User == N0.
getNode())
14651 if (
User->getOpcode() != ExtOpcode ||
User->getValueType(0) != VT)
14657 if (IsFreeToExtend(N00) && IsFreeToExtend(N01)) {
14660 return DAG.
getSetCC(
DL, VT, Ext0, Ext1, CC);
14677 SDValue ExtTrueVal = (SetCCWidth == 1)
14681 if (
SDValue SCC = SimplifySelectCC(
DL, N00, N01, ExtTrueVal, Zero, CC,
true))
14693 return DAG.
getSelect(
DL, VT, SetCC, ExtTrueVal, Zero);
14700SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *
N) {
14702 EVT VT =
N->getValueType(0);
14706 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
14752 if (NarrowLoad.getNode() != N0.
getNode()) {
14753 CombineTo(N0.
getNode(), NarrowLoad);
14755 AddToWorklist(oye);
14763 unsigned OpBits =
Op.getScalarValueSizeInBits();
14769 if (OpBits == DestBits) {
14775 if (OpBits < DestBits) {
14784 Flags.setNoSignedWrap(
true);
14792 if (OpBits < DestBits)
14794 else if (OpBits > DestBits)
14814 if (
SDValue ExtLoad = CombineExtLoad(
N))
14849 bool NoReplaceTruncAnd = !N0.
hasOneUse();
14850 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
14853 if (NoReplaceTruncAnd) {
14856 CombineTo(N0.
getNode(), TruncAnd);
14858 if (NoReplaceTrunc) {
14863 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
14882 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
14913 if (NewXor.getNode() == N0.
getNode()) {
14939 "Expected extend op");
14983SDValue DAGCombiner::visitZERO_EXTEND(SDNode *
N) {
14985 EVT VT =
N->getValueType(0);
14989 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15020 APInt TruncatedBits =
15022 APInt(
Op.getScalarValueSizeInBits(), 0) :
15023 APInt::getBitsSet(
Op.getScalarValueSizeInBits(),
15024 N0.getScalarValueSizeInBits(),
15025 std::min(
Op.getScalarValueSizeInBits(),
15028 SDValue ZExtOrTrunc = DAG.getZExtOrTrunc(Op, DL, VT);
15029 DAG.salvageDebugInfo(*N0.getNode());
15031 return ZExtOrTrunc;
15041 if (NarrowLoad.getNode() != N0.
getNode()) {
15042 CombineTo(N0.
getNode(), NarrowLoad);
15044 AddToWorklist(oye);
15052 if (
N->getFlags().hasNonNeg()) {
15060 if (OpBits == DestBits) {
15066 if (OpBits < DestBits) {
15076 Flags.setNoSignedWrap(
true);
15077 Flags.setNoUnsignedWrap(
true);
15089 AddToWorklist(
Op.getNode());
15093 return ZExtOrTrunc;
15099 AddToWorklist(
Op.getNode());
15135 if (
SDValue ExtLoad = CombineExtLoad(
N))
15155 bool DoXform =
true;
15162 if (isAndLoadExtLoad(AndC, LN00, LoadResultTy, ExtVT))
15178 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15179 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15182 if (NoReplaceTruncAnd) {
15185 CombineTo(N0.
getNode(), TruncAnd);
15187 if (NoReplaceTrunc) {
15192 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
15201 if (
SDValue ZExtLoad = CombineZExtLogicopShiftLoad(
N))
15214 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
15217 if (!LegalOperations && VT.
isVector() &&
15249 if (
SDValue SCC = SimplifySelectCC(
15269 if (ShAmtC->getAPIntValue().ugt(KnownZeroBits)) {
15290 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15312SDValue DAGCombiner::visitANY_EXTEND(SDNode *
N) {
15314 EVT VT =
N->getValueType(0);
15348 if (NarrowLoad.getNode() != N0.
getNode()) {
15349 CombineTo(N0.
getNode(), NarrowLoad);
15351 AddToWorklist(oye);
15385 bool DoXform =
true;
15398 CombineTo(
N, ExtLoad);
15399 if (NoReplaceTrunc) {
15401 recursivelyDeleteUnusedNodes(LN0);
15405 CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
15419 if (!LegalOperations || TLI.
isLoadExtLegal(ExtType, VT, MemVT)) {
15423 CombineTo(
N, ExtLoad);
15425 recursivelyDeleteUnusedNodes(LN0);
15432 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
15439 if (VT.
isVector() && !LegalOperations) {
15464 if (
SDValue SCC = SimplifySelectCC(
15480SDValue DAGCombiner::visitAssertExt(SDNode *
N) {
15481 unsigned Opcode =
N->getOpcode();
15501 EVT MinAssertVT = AssertVT.
bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
15516 if (AssertVT.
bitsLT(BigA_AssertVT)) {
15534 if (AssertVT.
bitsLT(BigA_AssertVT) &&
15554SDValue DAGCombiner::visitAssertAlign(SDNode *
N) {
15564 std::max(AL, AAN->getAlign()));
15575 unsigned AlignShift =
Log2(AL);
15580 if (LHSAlignShift >= AlignShift || RHSAlignShift >= AlignShift) {
15581 if (LHSAlignShift < AlignShift)
15583 if (RHSAlignShift < AlignShift)
15597SDValue DAGCombiner::reduceLoadWidth(SDNode *
N) {
15598 unsigned Opc =
N->getOpcode();
15602 EVT VT =
N->getValueType(0);
15612 unsigned ShAmt = 0;
15617 unsigned ShiftedOffset = 0;
15637 uint64_t MemoryWidth = LN->getMemoryVT().getScalarSizeInBits();
15638 if (MemoryWidth <= ShAmt)
15649 LN->getExtensionType() != ExtType)
15658 unsigned ActiveBits = 0;
15659 if (
Mask.isMask()) {
15660 ActiveBits =
Mask.countr_one();
15661 }
else if (
Mask.isShiftedMask(ShAmt, ActiveBits)) {
15662 ShiftedOffset = ShAmt;
15683 if (!
SRL.hasOneUse())
15696 ShAmt = SRL1C->getZExtValue();
15697 uint64_t MemoryWidth = LN->getMemoryVT().getSizeInBits();
15698 if (ShAmt >= MemoryWidth)
15723 SDNode *
Mask = *(
SRL->user_begin());
15726 unsigned Offset, ActiveBits;
15727 const APInt& ShiftMask =
Mask->getConstantOperandAPInt(1);
15728 if (ShiftMask.
isMask()) {
15750 N0 =
SRL.getOperand(0);
15758 unsigned ShLeftAmt = 0;
15762 ShLeftAmt = N01->getZExtValue();
15775 !isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
15778 auto AdjustBigEndianShift = [&](
unsigned ShAmt) {
15779 unsigned LVTStoreBits =
15782 return LVTStoreBits - EVTStoreBits - ShAmt;
15787 unsigned PtrAdjustmentInBits =
15790 uint64_t PtrOff = PtrAdjustmentInBits / 8;
15796 AddToWorklist(NewPtr.
getNode());
15800 const MDNode *OldRanges = LN0->
getRanges();
15801 const MDNode *NewRanges =
nullptr;
15805 if (ShAmt == 0 && OldRanges) {
15813 ConstantRange TruncatedCR = CR.
truncate(BitSize);
15823 NewRanges = OldRanges;
15836 WorklistRemover DeadNodes(*
this);
15841 if (ShLeftAmt != 0) {
15853 if (ShiftedOffset != 0) {
15867SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *
N) {
15870 EVT VT =
N->getValueType(0);
15901 if ((N00Bits <= ExtVTBits ||
15914 if ((N00Bits == ExtVTBits ||
15915 (!IsZext && (N00Bits < ExtVTBits ||
15917 (!LegalOperations ||
15942 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
15950 if (ShAmt->getAPIntValue().ule(VTBits - ExtVTBits)) {
15954 if (((VTBits - ExtVTBits) - ShAmt->getZExtValue()) < InSignBits)
15973 CombineTo(
N, ExtLoad);
15975 AddToWorklist(ExtLoad.
getNode());
15988 CombineTo(
N, ExtLoad);
15996 if (ExtVT == Ld->getMemoryVT() && N0.
hasOneUse() &&
16000 VT,
DL, Ld->getChain(), Ld->getBasePtr(), Ld->getOffset(),
16001 Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->getMemOperand(),
16002 Ld->getAddressingMode(),
ISD::SEXTLOAD, Ld->isExpandingLoad());
16003 CombineTo(
N, ExtMaskedLoad);
16011 if (
SDValue(GN0, 0).hasOneUse() && ExtVT == GN0->getMemoryVT() &&
16013 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
16014 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
16017 DAG.
getVTList(VT, MVT::Other), ExtVT,
DL,
Ops, GN0->getMemOperand(),
16020 CombineTo(
N, ExtLoad);
16022 AddToWorklist(ExtLoad.
getNode());
16045 (!LegalOperations ||
16059 bool LegalOperations) {
16060 unsigned InregOpcode =
N->getOpcode();
16064 EVT VT =
N->getValueType(0);
16066 Src.getValueType().getVectorElementType(),
16070 "Expected EXTEND_VECTOR_INREG dag node in input!");
16079 Src = Src.getOperand(0);
16080 if (Src.getValueType() != SrcVT)
16086 return DAG.
getNode(Opcode,
DL, VT, Src);
16089SDValue DAGCombiner::visitEXTEND_VECTOR_INREG(SDNode *
N) {
16091 EVT VT =
N->getValueType(0);
16115SDValue DAGCombiner::visitTRUNCATE_USAT_U(SDNode *
N) {
16116 EVT VT =
N->getValueType(0);
16137 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16139 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16160 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16162 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16183 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16185 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16208 auto AllowedTruncateSat = [&](
unsigned Opc,
EVT SrcVT,
EVT VT) ->
bool {
16220 }
else if (Src.getOpcode() ==
ISD::UMIN) {
16232SDValue DAGCombiner::visitTRUNCATE(SDNode *
N) {
16234 EVT VT =
N->getValueType(0);
16249 return SaturatedTR;
16301 if (LegalTypes && !LegalOperations && VT.
isScalarInteger() && VT != MVT::i1 &&
16303 EVT TrTy =
N->getValueType(0);
16308 if (Src.getOpcode() ==
ISD::SRL && Src.getOperand(0)->hasOneUse()) {
16311 Src = Src.getOperand(0);
16318 EVT VecTy = Src.getOperand(0).getValueType();
16319 EVT ExTy = Src.getValueType();
16323 auto NewEltCnt = EltCnt * SizeRatio;
16328 SDValue EltNo = Src->getOperand(1);
16331 int Index = isLE ? (Elt * SizeRatio + EltOffset)
16332 : (Elt * SizeRatio + (SizeRatio - 1) - EltOffset);
16343 if (!LegalOperations ||
16366 AddToWorklist(Amt.
getNode());
16415 if (BuildVectEltTy == TruncVecEltTy) {
16419 unsigned TruncEltOffset = BuildVecNumElts / TruncVecNumElts;
16420 unsigned FirstElt = isLE ? 0 : (TruncEltOffset - 1);
16422 assert((BuildVecNumElts % TruncVecNumElts) == 0 &&
16423 "Invalid number of elements");
16426 for (
unsigned i = FirstElt, e = BuildVecNumElts; i <
e;
16427 i += TruncEltOffset)
16437 if (
SDValue Reduced = reduceLoadWidth(
N))
16460 unsigned NumDefs = 0;
16464 if (!
X.isUndef()) {
16481 if (NumDefs == 1) {
16482 assert(
V.getNode() &&
"The single defined operand is empty!");
16484 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
16490 AddToWorklist(
NV.getNode());
16505 (!LegalOperations ||
16533 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
16547 if (!LegalOperations && N0.
hasOneUse() &&
16564 Flags.setNoUnsignedWrap(
true);
16589 if (!LegalOperations && N0.
hasOneUse() &&
16630 if (!LegalOperations && N0.
hasOneUse() &&
16638 bool CanFold =
false;
16646 unsigned NeededBits = SrcBits - TruncBits;
16672SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *
N, EVT VT) {
16685 !LD1->hasOneUse() || !LD2->hasOneUse() ||
16686 LD1->getAddressSpace() != LD2->getAddressSpace())
16689 unsigned LD1Fast = 0;
16690 EVT LD1VT = LD1->getValueType(0);
16695 *LD1->getMemOperand(), &LD1Fast) && LD1Fast)
16696 return DAG.
getLoad(VT, SDLoc(
N), LD1->getChain(), LD1->getBasePtr(),
16697 LD1->getPointerInfo(), LD1->getAlign());
16708SDValue DAGCombiner::foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
16712 EVT VT =
N->getValueType(0);
16749 auto IsBitCastOrFree = [&TLI, FPOpcode](
SDValue Op, EVT VT) {
16763 IsBitCastOrFree(LogicOp0, VT)) {
16766 NumFPLogicOpsConv++;
16775SDValue DAGCombiner::visitBITCAST(SDNode *
N) {
16777 EVT VT =
N->getValueType(0);
16802 if (!LegalOperations ||
16808 if (
C.getNode() !=
N)
16821 auto IsFreeBitcast = [VT](
SDValue V) {
16823 V.getOperand(0).getValueType() == VT) ||
16836 auto CastLoad = [
this, &VT](
SDValue N0,
const SDLoc &
DL) {
16851 if ((LegalOperations || !LN0->
isSimple()) &&
16861 if (
const MDNode *MD = LN0->
getRanges()) {
16873 if (
SDValue NewLd = CastLoad(N0, SDLoc(
N)))
16880 if (
SDValue V = foldBitcastedFPLogic(
N, DAG, TLI))
16900 AddToWorklist(NewConv.
getNode());
16903 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
16910 AddToWorklist(FlipBit.
getNode());
16917 AddToWorklist(
Hi.getNode());
16919 AddToWorklist(FlipBit.
getNode());
16923 AddToWorklist(FlipBits.
getNode());
16953 AddToWorklist(
X.getNode());
16957 if (OrigXWidth < VTWidth) {
16959 AddToWorklist(
X.getNode());
16960 }
else if (OrigXWidth > VTWidth) {
16965 X.getValueType(),
X,
16967 X.getValueType()));
16968 AddToWorklist(
X.getNode());
16970 AddToWorklist(
X.getNode());
16973 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
16976 AddToWorklist(Cst.
getNode());
16978 AddToWorklist(
X.getNode());
16980 AddToWorklist(XorResult.
getNode());
16984 SDLoc(XorResult)));
16985 AddToWorklist(XorResult64.
getNode());
16988 DAG.
getConstant(SignBit, SDLoc(XorResult64), MVT::i64));
16989 AddToWorklist(FlipBit.
getNode());
16992 AddToWorklist(FlipBits.
getNode());
16998 AddToWorklist(
X.getNode());
17003 AddToWorklist(Cst.
getNode());
17011 if (
SDValue CombineLD = CombineConsecutiveLoads(N0.
getNode(), VT))
17034 auto PeekThroughBitcast = [&](
SDValue Op) {
17036 Op.getOperand(0).getValueType() == VT)
17053 SmallVector<int, 8> NewMask;
17055 for (
int i = 0; i != MaskScale; ++i)
17056 NewMask.
push_back(M < 0 ? -1 : M * MaskScale + i);
17061 return LegalShuffle;
17067SDValue DAGCombiner::visitBUILD_PAIR(SDNode *
N) {
17068 EVT VT =
N->getValueType(0);
17069 return CombineConsecutiveLoads(
N, VT);
17072SDValue DAGCombiner::visitFREEZE(SDNode *
N) {
17086 assert(
N->getOperand(0) == FrozenN0 &&
"Expected cycle in DAG");
17114 bool AllowMultipleMaybePoisonOperands =
17142 SmallSet<SDValue, 8> MaybePoisonOperands;
17143 SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
17147 bool HadMaybePoisonOperands = !MaybePoisonOperands.
empty();
17148 bool IsNewMaybePoisonOperand = MaybePoisonOperands.
insert(
Op).second;
17149 if (IsNewMaybePoisonOperand)
17150 MaybePoisonOperandNumbers.
push_back(OpNo);
17151 if (!HadMaybePoisonOperands)
17153 if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
17162 for (
unsigned OpNo : MaybePoisonOperandNumbers) {
17173 SDValue MaybePoisonOperand =
N->getOperand(0).getOperand(OpNo);
17175 if (MaybePoisonOperand.
isUndef())
17182 FrozenMaybePoisonOperand.
getOperand(0) == FrozenMaybePoisonOperand) {
17186 MaybePoisonOperand);
17222 SDNodeFlags SrcFlags = N0->
getFlags();
17223 SDNodeFlags SafeFlags;
17237 N->getFlags().hasAllowContract();
17241template <
class MatchContextClass>
17242SDValue DAGCombiner::visitFADDForFMACombine(SDNode *
N) {
17245 EVT VT =
N->getValueType(0);
17247 MatchContextClass matcher(DAG, TLI,
N);
17250 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17255 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17259 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17263 if (!HasFMAD && !HasFMA)
17266 bool AllowFusionGlobally =
17269 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17295 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17306 return matcher.getNode(PreferredFusedOpcode, SL, VT, N0.
getOperand(0),
17313 return matcher.getNode(PreferredFusedOpcode, SL, VT, N1.
getOperand(0),
17325 bool CanReassociate =
N->getFlags().hasAllowReassociation();
17326 if (CanReassociate) {
17331 }
else if (isFusedOp(N1) && N1.
hasOneUse()) {
17337 while (
E && isFusedOp(TmpFMA) && TmpFMA.
hasOneUse()) {
17342 SDValue CDE = matcher.getNode(PreferredFusedOpcode, SL, VT,
C,
D,
E);
17361 return matcher.getNode(
17362 PreferredFusedOpcode, SL, VT,
17375 return matcher.getNode(
17376 PreferredFusedOpcode, SL, VT,
17388 return matcher.getNode(
17389 PreferredFusedOpcode, SL, VT,
X,
Y,
17390 matcher.getNode(PreferredFusedOpcode, SL, VT,
17394 if (isFusedOp(N0)) {
17415 return matcher.getNode(
17416 PreferredFusedOpcode, SL, VT,
17419 matcher.getNode(PreferredFusedOpcode, SL, VT,
17425 if (isFusedOp(N00)) {
17439 if (isFusedOp(N1)) {
17460 if (isFusedOp(N10)) {
17477template <
class MatchContextClass>
17478SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *
N) {
17481 EVT VT =
N->getValueType(0);
17483 MatchContextClass matcher(DAG, TLI,
N);
17486 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17491 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17495 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17499 if (!HasFMAD && !HasFMA)
17502 const SDNodeFlags
Flags =
N->getFlags();
17503 bool AllowFusionGlobally =
17507 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17516 bool NoSignedZero =
Flags.hasNoSignedZeros();
17523 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17529 return matcher.getNode(PreferredFusedOpcode, SL, VT, XY.
getOperand(0),
17540 return matcher.getNode(
17541 PreferredFusedOpcode, SL, VT,
17542 matcher.getNode(
ISD::FNEG, SL, VT, YZ.getOperand(0)),
17543 YZ.getOperand(1),
X);
17553 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17556 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17560 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17563 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17572 return matcher.
getNode(PreferredFusedOpcode, SL, VT,
17573 matcher.getNode(
ISD::FNEG, SL, VT, N00), N01,
17574 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17586 return matcher.getNode(
17587 PreferredFusedOpcode, SL, VT,
17590 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17602 return matcher.getNode(
17603 PreferredFusedOpcode, SL, VT,
17624 return matcher.getNode(
17627 PreferredFusedOpcode, SL, VT,
17648 return matcher.getNode(
17651 PreferredFusedOpcode, SL, VT,
17668 if (
Aggressive &&
N->getFlags().hasAllowReassociation()) {
17669 bool CanFuse =
N->getFlags().hasAllowContract();
17672 if (CanFuse && isFusedOp(N0) &&
17673 isContractableAndReassociableFMUL(N0.
getOperand(2)) &&
17675 return matcher.getNode(
17677 matcher.
getNode(PreferredFusedOpcode, SL, VT,
17685 if (CanFuse && isFusedOp(N1) &&
17686 isContractableAndReassociableFMUL(N1.
getOperand(2)) &&
17691 PreferredFusedOpcode, SL, VT,
17694 matcher.
getNode(PreferredFusedOpcode, SL, VT,
17695 matcher.getNode(
ISD::FNEG, SL, VT, N20), N21, N0));
17700 if (isFusedOp(N0) && N0->
hasOneUse()) {
17704 if (isContractableAndReassociableFMUL(N020) &&
17707 return matcher.getNode(
17710 PreferredFusedOpcode, SL, VT,
17713 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
17726 if (isFusedOp(N00)) {
17728 if (isContractableAndReassociableFMUL(N002) &&
17731 return matcher.getNode(
17732 PreferredFusedOpcode, SL, VT,
17736 PreferredFusedOpcode, SL, VT,
17739 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
17749 if (isContractableAndReassociableFMUL(N120) &&
17755 PreferredFusedOpcode, SL, VT,
17759 PreferredFusedOpcode, SL, VT,
17777 if (isContractableAndReassociableFMUL(N102) &&
17783 PreferredFusedOpcode, SL, VT,
17788 PreferredFusedOpcode, SL, VT,
17802SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *
N) {
17805 EVT VT =
N->getValueType(0);
17815 if (!
FAdd->getFlags().hasNoInfs())
17826 bool HasFMAD = LegalOperations && TLI.
isFMADLegal(DAG,
N);
17829 if (!HasFMAD && !HasFMA)
17841 if (
C->isExactlyValue(+1.0))
17842 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17844 if (
C->isExactlyValue(-1.0))
17845 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17852 if (
SDValue FMA = FuseFADD(N0, N1))
17854 if (
SDValue FMA = FuseFADD(N1, N0))
17864 if (C0->isExactlyValue(+1.0))
17865 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
17868 if (C0->isExactlyValue(-1.0))
17869 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
17874 if (C1->isExactlyValue(+1.0))
17875 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17877 if (C1->isExactlyValue(-1.0))
17878 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17885 if (
SDValue FMA = FuseFSUB(N0, N1))
17887 if (
SDValue FMA = FuseFSUB(N1, N0))
17893SDValue DAGCombiner::visitVP_FADD(SDNode *
N) {
17894 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
17897 if (
SDValue Fused = visitFADDForFMACombine<VPMatchContext>(
N)) {
17899 AddToWorklist(Fused.getNode());
17905SDValue DAGCombiner::visitFADD(SDNode *
N) {
17910 EVT VT =
N->getValueType(0);
17912 SDNodeFlags
Flags =
N->getFlags();
17913 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
17923 if (N0CFP && !N1CFP)
17928 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
17933 if (N1C && N1C->
isZero())
17938 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
17944 N1, DAG, LegalOperations, ForCodeSize))
17950 N0, DAG, LegalOperations, ForCodeSize))
17957 return C &&
C->isExactlyValue(-2.0);
17961 if (isFMulNegTwo(N0)) {
17967 if (isFMulNegTwo(N1)) {
17978 if (
Flags.hasNoNaNs() && AllowNewConst) {
17991 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18009 if (CFP01 && !CFP00 && N0.
getOperand(0) == N1) {
18030 if (CFP11 && !CFP10 && N1.
getOperand(0) == N0) {
18077 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros()) {
18080 VT, N0, N1, Flags))
18085 if (
SDValue Fused = visitFADDForFMACombine<EmptyMatchContext>(
N)) {
18087 AddToWorklist(Fused.getNode());
18093SDValue DAGCombiner::visitSTRICT_FADD(SDNode *
N) {
18097 EVT VT =
N->getValueType(0);
18098 EVT ChainVT =
N->getValueType(1);
18100 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18105 N1, DAG, LegalOperations, ForCodeSize)) {
18107 {Chain, N0, NegN1});
18113 N0, DAG, LegalOperations, ForCodeSize)) {
18115 {Chain, N1, NegN0});
18120SDValue DAGCombiner::visitFSUB(SDNode *
N) {
18125 EVT VT =
N->getValueType(0);
18127 const SDNodeFlags
Flags =
N->getFlags();
18128 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18139 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18142 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18146 if (N1CFP && N1CFP->
isZero()) {
18155 if (
Flags.hasNoNaNs())
18160 if (N0CFP && N0CFP->
isZero()) {
18178 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18194 if (
SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(
N)) {
18195 AddToWorklist(Fused.getNode());
18217SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *
N) {
18218 EVT VT =
N->getValueType(0);
18224 std::optional<int> Mantissa;
18225 auto GetConstAndPow2Ops = [&](
unsigned ConstOpIdx) {
18226 if (ConstOpIdx == 1 &&
N->getOpcode() ==
ISD::FDIV)
18242 auto IsFPConstValid = [
N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
18243 if (CFP ==
nullptr)
18246 const APFloat &APF = CFP->getValueAPF();
18254 int CurExp =
ilogb(APF);
18257 N->getOpcode() ==
ISD::FMUL ? CurExp : (CurExp - MaxExpChange);
18260 N->getOpcode() ==
ISD::FDIV ? CurExp : (CurExp + MaxExpChange);
18268 Mantissa = ThisMantissa;
18270 return *Mantissa == ThisMantissa && ThisMantissa > 0;
18277 if (!GetConstAndPow2Ops(0) && !GetConstAndPow2Ops(1))
18306 NewIntVT, DAG.
getBitcast(NewIntVT, ConstOp), Shift);
18311SDValue DAGCombiner::visitFMUL(SDNode *
N) {
18315 EVT VT =
N->getValueType(0);
18317 const SDNodeFlags
Flags =
N->getFlags();
18318 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18334 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18337 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18340 if (
Flags.hasAllowReassociation()) {
18366 VT, N0, N1, Flags))
18390 HandleSDNode NegN0Handle(NegN0);
18400 if (
Flags.hasNoNaNs() &&
Flags.hasNoSignedZeros() &&
18411 if (TrueOpnd && FalseOpnd &&
18432 if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
18436 if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
18445 if (
SDValue Fused = visitFMULForFMADistributiveCombine(
N)) {
18446 AddToWorklist(Fused.getNode());
18452 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
18458template <
class MatchContextClass>
SDValue DAGCombiner::visitFMA(SDNode *
N) {
18465 EVT VT =
N->getValueType(0);
18468 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18469 MatchContextClass matcher(DAG, TLI,
N);
18484 HandleSDNode NegN0Handle(NegN0);
18492 if (
N->getFlags().hasNoNaNs() &&
N->getFlags().hasNoInfs()) {
18493 if (
N->getFlags().hasNoSignedZeros() ||
18495 if (N0CFP && N0CFP->
isZero())
18497 if (N1CFP && N1CFP->
isZero())
18506 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18511 return matcher.getNode(
ISD::FMA,
DL, VT, N1, N0, N2);
18513 bool CanReassociate =
N->getFlags().hasAllowReassociation();
18514 if (CanReassociate) {
18519 return matcher.getNode(
18528 return matcher.getNode(
18538 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18543 AddToWorklist(RHSNeg.
getNode());
18544 return matcher.getNode(
ISD::FADD,
DL, VT, N2, RHSNeg);
18558 if (CanReassociate) {
18560 if (N1CFP && N0 == N2) {
18578 SDValue(
N, 0), DAG, LegalOperations, ForCodeSize))
18583SDValue DAGCombiner::visitFMAD(SDNode *
N) {
18587 EVT VT =
N->getValueType(0);
18597SDValue DAGCombiner::visitFMULADD(SDNode *
N) {
18601 EVT VT =
N->getValueType(0);
18619SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *
N) {
18623 const SDNodeFlags
Flags =
N->getFlags();
18624 if (LegalDAG || !
Flags.hasAllowReciprocal())
18639 unsigned NumElts = 1;
18640 EVT VT =
N->getValueType(0);
18644 if (!MinUses || (N1->
use_size() * NumElts) < MinUses)
18649 SetVector<SDNode *>
Users;
18650 for (
auto *U : N1->
users()) {
18651 if (
U->getOpcode() ==
ISD::FDIV &&
U->getOperand(1) == N1) {
18653 if (
U->getOperand(1).getOpcode() ==
ISD::FSQRT &&
18654 U->getOperand(0) ==
U->getOperand(1).getOperand(0) &&
18655 U->getFlags().hasAllowReassociation() &&
18656 U->getFlags().hasNoSignedZeros())
18661 if (
U->getFlags().hasAllowReciprocal())
18668 if ((
Users.size() * NumElts) < MinUses)
18676 for (
auto *U :
Users) {
18677 SDValue Dividend =
U->getOperand(0);
18678 if (Dividend != FPOne) {
18680 Reciprocal, Flags);
18681 CombineTo(U, NewNode);
18682 }
else if (U != Reciprocal.
getNode()) {
18685 CombineTo(U, Reciprocal);
18691SDValue DAGCombiner::visitFDIV(SDNode *
N) {
18694 EVT VT =
N->getValueType(0);
18696 SDNodeFlags
Flags =
N->getFlags();
18697 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18708 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18711 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18728 (!LegalOperations ||
18738 if (
Flags.hasAllowReciprocal()) {
18747 N1AllowReciprocal) {
18778 A =
Y.getOperand(0);
18787 if (
SDValue Rsqrt = buildRsqrtEstimate(AAZ))
18791 recursivelyDeleteUnusedNodes(AAZ.
getNode());
18799 AddToWorklist(Div.
getNode());
18806 if (
Flags.hasNoInfs())
18807 if (
SDValue RV = BuildDivEstimate(N0, N1, Flags))
18813 Flags.hasAllowReassociation())
18825 HandleSDNode NegN0Handle(NegN0);
18833 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
18839SDValue DAGCombiner::visitFREM(SDNode *
N) {
18842 EVT VT =
N->getValueType(0);
18843 SDNodeFlags
Flags =
N->getFlags();
18844 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18854 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18864 bool NeedsCopySign = !
Flags.hasNoSignedZeros() &&
18883SDValue DAGCombiner::visitFSQRT(SDNode *
N) {
18884 SDNodeFlags
Flags =
N->getFlags();
18888 if (!
Flags.hasApproximateFuncs() || !
Flags.hasNoInfs())
18896 SelectionDAG::FlagInserter FlagInserter(DAG, Flags);
18901 return buildSqrtEstimate(N0);
18916 if (YTy == MVT::f128)
18933SDValue DAGCombiner::visitFCOPYSIGN(SDNode *
N) {
18936 EVT VT =
N->getValueType(0);
18974SDValue DAGCombiner::visitFPOW(SDNode *
N) {
18978 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18984 EVT VT =
N->getValueType(0);
18993 SDNodeFlags
Flags =
N->getFlags();
18994 if (!
Flags.hasNoSignedZeros() || !
Flags.hasNoInfs() || !
Flags.hasNoNaNs() ||
18995 !
Flags.hasApproximateFuncs())
19014 if (ExponentIs025 || ExponentIs075) {
19022 SDNodeFlags
Flags =
N->getFlags();
19025 if ((!
Flags.hasNoSignedZeros() && ExponentIs025) || !
Flags.hasNoInfs() ||
19026 !
Flags.hasApproximateFuncs())
19061 EVT VT =
N->getValueType(0);
19089SDValue DAGCombiner::visitSINT_TO_FP(SDNode *
N) {
19091 EVT VT =
N->getValueType(0);
19143SDValue DAGCombiner::visitUINT_TO_FP(SDNode *
N) {
19145 EVT VT =
N->getValueType(0);
19189 EVT VT =
N->getValueType(0);
19195 EVT SrcVT = Src.getValueType();
19210 unsigned ActualSize = std::min(InputSize, OutputSize);
19219 return DAG.
getNode(ExtOp,
DL, VT, Src);
19228SDValue DAGCombiner::visitFP_TO_SINT(SDNode *
N) {
19230 EVT VT =
N->getValueType(0);
19244SDValue DAGCombiner::visitFP_TO_UINT(SDNode *
N) {
19246 EVT VT =
N->getValueType(0);
19260SDValue DAGCombiner::visitXROUND(SDNode *
N) {
19262 EVT VT =
N->getValueType(0);
19278SDValue DAGCombiner::visitFP_ROUND(SDNode *
N) {
19281 EVT VT =
N->getValueType(0);
19294 const bool NIsTrunc =
N->getConstantOperandVal(1) == 1;
19316 if ((
N->getFlags().hasAllowContract() &&
19334 AddToWorklist(Tmp.
getNode());
19338 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19348 EVT VT =
N->getValueType(0);
19350 unsigned NarrowingOp;
19351 switch (
N->getOpcode()) {
19381SDValue DAGCombiner::visitFP_EXTEND(SDNode *
N) {
19382 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19384 EVT VT =
N->getValueType(0);
19388 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
19408 if (
In.getValueType() == VT)
return In;
19422 CombineTo(
N, ExtLoad);
19431 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19435 return CastEliminated;
19440SDValue DAGCombiner::visitFCEIL(SDNode *
N) {
19442 EVT VT =
N->getValueType(0);
19451SDValue DAGCombiner::visitFTRUNC(SDNode *
N) {
19453 EVT VT =
N->getValueType(0);
19476SDValue DAGCombiner::visitFFREXP(SDNode *
N) {
19485SDValue DAGCombiner::visitFFLOOR(SDNode *
N) {
19487 EVT VT =
N->getValueType(0);
19496SDValue DAGCombiner::visitFNEG(SDNode *
N) {
19498 EVT VT =
N->getValueType(0);
19499 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19522 if (
SDValue Cast = foldSignChangeInBitcast(
N))
19528SDValue DAGCombiner::visitFMinMax(SDNode *
N) {
19531 EVT VT =
N->getValueType(0);
19532 const SDNodeFlags
Flags =
N->getFlags();
19533 unsigned Opc =
N->getOpcode();
19535 bool ReturnsOtherForAllNaNs =
19539 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19548 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0);
19560 if (PropAllNaNsToQNaNs) {
19564 }
else if (ReturnsOtherForAllNaNs || !AF.
isSignaling()) {
19565 return N->getOperand(0);
19578 (ReturnsOtherForAllNaNs ||
Flags.hasNoNaNs()))
19579 return N->getOperand(1);
19587 if (IsMin != AF.
isNegative() && (PropAllNaNsToQNaNs ||
Flags.hasNoNaNs()))
19588 return N->getOperand(0);
19596 if (
SDValue SD = reassociateReduction(
19600 Opc, SDLoc(
N), VT, N0, N1, Flags))
19606SDValue DAGCombiner::visitFABS(SDNode *
N) {
19608 EVT VT =
N->getValueType(0);
19618 if (
SDValue Cast = foldSignChangeInBitcast(
N))
19624SDValue DAGCombiner::visitBRCOND(SDNode *
N) {
19651 bool Updated =
false;
19663 return True || False;
19667 if (!IsAlwaysTrueOrFalse(
Cond, S1C)) {
19674 S1 =
S1->getOperand(0);
19705 HandleSDNode ChainHandle(Chain);
19706 if (
SDValue NewN1 = rebuildSetCC(N1))
19708 ChainHandle.getValue(), NewN1, N2,
N->getFlags());
19717 (
N.getOperand(0).hasOneUse() &&
19718 N.getOperand(0).getOpcode() ==
ISD::SRL))) {
19721 N =
N.getOperand(0);
19768 HandleSDNode XORHandle(
N);
19770 SDValue Tmp = visitXOR(
N.getNode());
19777 N = XORHandle.getValue();
19789 bool Equal =
false;
19799 EVT SetCCVT =
N.getValueType();
19808 return DAG.
getSetCC(SDLoc(
N), SetCCVT, Op0, Op1, CC);
19817SDValue DAGCombiner::visitBR_CC(SDNode *
N) {
19829 CondLHS, CondRHS, CC->
get(), SDLoc(
N),
19844 bool &IsLoad,
bool &IsMasked,
SDValue &Ptr,
19847 if (LD->isIndexed())
19849 EVT VT = LD->getMemoryVT();
19852 Ptr = LD->getBasePtr();
19854 if (ST->isIndexed())
19856 EVT VT = ST->getMemoryVT();
19859 Ptr = ST->getBasePtr();
19862 if (LD->isIndexed())
19864 EVT VT = LD->getMemoryVT();
19868 Ptr = LD->getBasePtr();
19871 if (ST->isIndexed())
19873 EVT VT = ST->getMemoryVT();
19877 Ptr = ST->getBasePtr();
19891bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *
N) {
19895 bool IsLoad =
true;
19896 bool IsMasked =
false;
19918 bool Swapped =
false;
19947 if (Val == BasePtr)
19956 SmallPtrSet<const SDNode *, 32> Visited;
19966 for (SDUse &Use :
BasePtr->uses()) {
19969 if (
Use.getUser() == Ptr.
getNode() || Use != BasePtr)
19982 SDValue Op1 =
Use.getUser()->getOperand((
Use.getOperandNo() + 1) & 1);
20001 bool RealUse =
false;
20003 for (SDNode *User : Ptr->
users()) {
20037 WorklistRemover DeadNodes(*
this);
20046 deleteAndRecombine(
N);
20052 for (SDNode *OtherUse : OtherUses) {
20053 unsigned OffsetIdx = 1;
20054 if (OtherUse->getOperand(OffsetIdx).getNode() ==
BasePtr.getNode())
20056 assert(OtherUse->getOperand(!OffsetIdx).getNode() ==
BasePtr.getNode() &&
20057 "Expected BasePtr operand");
20071 const APInt &Offset0 = CN->getAPIntValue();
20072 const APInt &Offset1 =
Offset->getAsAPIntVal();
20073 int X0 = (OtherUse->getOpcode() ==
ISD::SUB && OffsetIdx == 1) ? -1 : 1;
20074 int Y0 = (OtherUse->getOpcode() ==
ISD::SUB && OffsetIdx == 0) ? -1 : 1;
20078 unsigned Opcode = (Y0 * Y1 < 0) ?
ISD::SUB : ISD::
ADD;
20080 APInt CNV = Offset0;
20081 if (X0 < 0) CNV = -CNV;
20082 if (X1 * Y0 * Y1 < 0) CNV = CNV + Offset1;
20083 else CNV = CNV - Offset1;
20085 SDLoc
DL(OtherUse);
20092 DAG.
getNode(Opcode,
DL, OtherUse->getValueType(0), NewOp1, NewOp2);
20094 deleteAndRecombine(OtherUse);
20099 deleteAndRecombine(Ptr.
getNode());
20100 AddToWorklist(
Result.getNode());
20132 bool IsLoad =
true;
20133 bool IsMasked =
false;
20136 IsMasked, OtherPtr, TLI)) {