88#define DEBUG_TYPE "dagcombine"
90STATISTIC(NodesCombined ,
"Number of dag nodes combined");
91STATISTIC(PreIndexedNodes ,
"Number of pre-indexed nodes created");
92STATISTIC(PostIndexedNodes,
"Number of post-indexed nodes created");
93STATISTIC(OpsNarrowed ,
"Number of load/op/store narrowed");
94STATISTIC(LdStFP2Int ,
"Number of fp load/store pairs transformed to int");
96STATISTIC(NumFPLogicOpsConv,
"Number of logic ops converted to fp ops");
99 "Controls whether a DAG combine is performed for a node");
103 cl::desc(
"Enable DAG combiner's use of IR alias analysis"));
107 cl::desc(
"Enable DAG combiner's use of TBAA"));
112 cl::desc(
"Only use DAG-combiner alias analysis in this"
120 cl::desc(
"Bypass the profitability model of load slicing"),
125 cl::desc(
"DAG combiner may split indexing from loads"));
129 cl::desc(
"DAG combiner enable merging multiple stores "
130 "into a wider store"));
134 cl::desc(
"Limit the number of operands to inline for Token Factors"));
138 cl::desc(
"Limit the number of times for the same StoreNode and RootNode "
139 "to bail out in store merging dependence check"));
143 cl::desc(
"DAG combiner enable reducing the width of load/op/store "
146 "combiner-reduce-load-op-store-width-force-narrowing-profitable",
148 cl::desc(
"DAG combiner force override the narrowing profitable check when "
149 "reducing the width of load/op/store sequences"));
153 cl::desc(
"DAG combiner enable load/<replace bytes>/store with "
154 "a narrower store"));
158 cl::desc(
"DAG combiner nodes consistently processed in topological order"));
162 cl::desc(
"Disable the DAG combiner"));
172 bool LegalDAG =
false;
173 bool LegalOperations =
false;
174 bool LegalTypes =
false;
176 bool DisableGenericCombines;
212 void AddUsersToWorklist(
SDNode *
N) {
218 void AddToWorklistWithUsers(SDNode *
N) {
219 AddUsersToWorklist(
N);
226 void clearAddedDanglingWorklistEntries() {
228 while (!PruningList.empty()) {
229 auto *
N = PruningList.pop_back_val();
231 recursivelyDeleteUnusedNodes(
N);
235 SDNode *getNextWorklistEntry() {
237 clearAddedDanglingWorklistEntries();
241 while (!
N && !Worklist.empty()) {
242 N = Worklist.pop_back_val();
246 assert(
N->getCombinerWorklistIndex() >= 0 &&
247 "Found a worklist entry without a corresponding map entry!");
249 N->setCombinerWorklistIndex(-2);
259 : DAG(
D), TLI(
D.getTargetLoweringInfo()),
260 STI(
D.getSubtarget().getSelectionDAGInfo()), OptLevel(OL),
262 ForCodeSize = DAG.shouldOptForSize();
263 DisableGenericCombines =
267 void ConsiderForPruning(SDNode *
N) {
269 PruningList.insert(
N);
274 void AddToWorklist(SDNode *
N,
bool IsCandidateForPruning =
true,
275 bool SkipIfCombinedBefore =
false) {
277 "Deleted Node added to Worklist");
284 if (SkipIfCombinedBefore &&
N->getCombinerWorklistIndex() == -2)
287 if (IsCandidateForPruning)
288 ConsiderForPruning(
N);
290 if (
N->getCombinerWorklistIndex() < 0) {
291 N->setCombinerWorklistIndex(Worklist.size());
292 Worklist.push_back(
N);
297 void removeFromWorklist(SDNode *
N) {
298 PruningList.remove(
N);
299 StoreRootCountMap.erase(
N);
301 int WorklistIndex =
N->getCombinerWorklistIndex();
305 if (WorklistIndex < 0)
309 Worklist[WorklistIndex] =
nullptr;
310 N->setCombinerWorklistIndex(-1);
313 void deleteAndRecombine(SDNode *
N);
314 bool recursivelyDeleteUnusedNodes(SDNode *
N);
322 return CombineTo(
N, &Res, 1, AddTo);
329 return CombineTo(
N, To, 2, AddTo);
332 SDValue CombineTo(SDNode *
N, SmallVectorImpl<SDValue> *To,
334 return CombineTo(
N, To->
data(), To->
size(), AddTo);
337 void CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO);
344 unsigned BitWidth =
Op.getScalarValueSizeInBits();
346 return SimplifyDemandedBits(
Op, DemandedBits);
349 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits) {
350 EVT VT =
Op.getValueType();
354 return SimplifyDemandedBits(
Op, DemandedBits, DemandedElts,
false);
360 bool SimplifyDemandedVectorElts(
SDValue Op) {
362 if (
Op.getValueType().isScalableVector())
365 unsigned NumElts =
Op.getValueType().getVectorNumElements();
367 return SimplifyDemandedVectorElts(
Op, DemandedElts);
370 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
371 const APInt &DemandedElts,
372 bool AssumeSingleUse =
false);
373 bool SimplifyDemandedVectorElts(
SDValue Op,
const APInt &DemandedElts,
374 bool AssumeSingleUse =
false);
376 bool CombineToPreIndexedLoadStore(SDNode *
N);
377 bool CombineToPostIndexedLoadStore(SDNode *
N);
378 SDValue SplitIndexingFromLoad(LoadSDNode *LD);
379 bool SliceUpLoad(SDNode *
N);
385 StoreSDNode *getUniqueStoreFeeding(LoadSDNode *LD, int64_t &
Offset);
387 SDValue ForwardStoreValueToDirectLoad(LoadSDNode *LD);
388 bool getTruncatedStoreValue(StoreSDNode *ST,
SDValue &Val);
389 bool extendLoadedValueToExtension(LoadSDNode *LD,
SDValue &Val);
391 void ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad);
400 SDValue foldShiftToAvg(SDNode *
N,
const SDLoc &
DL);
402 SDValue foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT);
420 SDValue visitTokenFactor(SDNode *
N);
421 SDValue visitMERGE_VALUES(SDNode *
N);
425 SDNode *LocReference);
436 SDValue visitUADDO_CARRY(SDNode *
N);
437 SDValue visitSADDO_CARRY(SDNode *
N);
443 SDValue visitUSUBO_CARRY(SDNode *
N);
444 SDValue visitSSUBO_CARRY(SDNode *
N);
466 SDValue SimplifyVCastOp(SDNode *
N,
const SDLoc &
DL);
467 SDValue SimplifyVBinOp(SDNode *
N,
const SDLoc &
DL);
471 SDValue visitFunnelShift(SDNode *
N);
475 SDValue visitABS_MIN_POISON(SDNode *
N);
480 SDValue visitCTLZ_ZERO_POISON(SDNode *
N);
482 SDValue visitCTTZ_ZERO_POISON(SDNode *
N);
490 SDValue visitSIGN_EXTEND(SDNode *
N);
491 SDValue visitZERO_EXTEND(SDNode *
N);
494 SDValue visitAssertAlign(SDNode *
N);
496 SDValue visitSIGN_EXTEND_INREG(SDNode *
N);
497 SDValue visitEXTEND_VECTOR_INREG(SDNode *
N);
499 SDValue visitTRUNCATE_USAT_U(SDNode *
N);
504 SDValue visitSTRICT_FADD(SDNode *
N);
515 SDValue visitFCANONICALIZE(SDNode *
N);
535 SDValue replaceStoreOfFPConstant(StoreSDNode *ST);
536 SDValue replaceStoreOfInsertLoad(StoreSDNode *ST);
538 bool refineExtractVectorEltIntoMultipleNarrowExtractVectorElts(SDNode *
N);
539 SDValue combineStoreConcatTruncVector(StoreSDNode *
N);
541 SDValue visitATOMIC_STORE(SDNode *
N);
542 SDValue visitLIFETIME_END(SDNode *
N);
543 SDValue visitINSERT_VECTOR_ELT(SDNode *
N);
544 SDValue visitEXTRACT_VECTOR_ELT(SDNode *
N);
545 SDValue visitBUILD_VECTOR(SDNode *
N);
546 SDValue visitCONCAT_VECTORS(SDNode *
N);
547 SDValue visitVECTOR_INTERLEAVE(SDNode *
N);
548 SDValue visitEXTRACT_SUBVECTOR(SDNode *
N);
549 SDValue visitVECTOR_SHUFFLE(SDNode *
N);
550 SDValue visitSCALAR_TO_VECTOR(SDNode *
N);
551 SDValue visitINSERT_SUBVECTOR(SDNode *
N);
552 SDValue visitVECTOR_COMPRESS(SDNode *
N);
558 SDValue visitPARTIAL_REDUCE_MLA(SDNode *
N);
561 SDValue visitVP_STRIDED_LOAD(SDNode *
N);
562 SDValue visitVP_STRIDED_STORE(SDNode *
N);
569 SDValue visitGET_FPENV_MEM(SDNode *
N);
570 SDValue visitSET_FPENV_MEM(SDNode *
N);
572 SDValue visitFADDForFMACombine(SDNode *
N);
573 SDValue visitFSUBForFMACombine(SDNode *
N);
574 SDValue visitFMULForFMADistributiveCombine(SDNode *
N);
576 SDValue XformToShuffleWithZero(SDNode *
N);
577 bool reassociationCanBreakAddressingModePattern(
unsigned Opc,
583 SDValue N1, SDNodeFlags Flags);
585 SDValue N1, SDNodeFlags Flags);
586 SDValue reassociateReduction(
unsigned RedOpc,
unsigned Opc,
const SDLoc &
DL,
588 SDNodeFlags Flags = SDNodeFlags());
590 SDValue visitShiftByConstant(SDNode *
N);
592 SDValue foldSelectOfConstants(SDNode *
N);
593 SDValue foldVSelectOfConstants(SDNode *
N);
594 SDValue foldBinOpIntoSelect(SDNode *BO);
596 SDValue hoistLogicOpWithSameOpcodeHands(SDNode *
N);
600 bool NotExtCompare =
false);
601 SDValue convertSelectOfFPConstantsToLoadOffset(
604 SDValue foldSignChangeInBitcast(SDNode *
N);
607 SDValue foldSelectOfBinops(SDNode *
N);
611 SDValue foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL);
612 SDValue foldABSToABD(SDNode *
N,
const SDLoc &
DL);
617 SDValue unfoldMaskedMerge(SDNode *
N);
618 SDValue unfoldExtremeBitClearingToShifts(SDNode *
N);
620 const SDLoc &
DL,
bool foldBooleans);
624 SDValue &CC,
bool MatchStrict =
false)
const;
625 bool isOneUseSetCC(
SDValue N)
const;
627 SDValue foldAddToAvg(SDNode *
N,
const SDLoc &
DL);
628 SDValue foldSubToAvg(SDNode *
N,
const SDLoc &
DL);
632 SDValue SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
634 SDValue CombineConsecutiveLoads(SDNode *
N, EVT VT);
635 SDValue foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
636 const TargetLowering &TLI);
637 SDValue foldPartialReduceMLAMulOp(SDNode *
N);
638 SDValue foldPartialReduceAdd(SDNode *
N);
641 SDValue CombineZExtLogicopShiftLoad(SDNode *
N);
642 SDValue combineRepeatedFPDivisors(SDNode *
N);
643 SDValue combineFMulOrFDivWithIntPow2(SDNode *
N);
644 SDValue replaceShuffleOfInsert(ShuffleVectorSDNode *Shuf);
645 SDValue mergeInsertEltWithShuffle(SDNode *
N,
unsigned InsIndex);
646 SDValue combineInsertEltToShuffle(SDNode *
N,
unsigned InsIndex);
647 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 convertBuildVecExtToExt(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->hasUniqueMemOperand() &&
1145 LoadStore->getBasePtr().getNode() == N) {
1146 TargetLoweringBase::AddrMode AM;
1147 AM.HasBaseReg = true;
1148 AM.ScalableOffset = ScalableOffset;
1149 EVT VT = LoadStore->getMemoryVT();
1150 unsigned AS = LoadStore->getAddressSpace();
1151 Type *AccessTy = VT.getTypeForEVT(*DAG.getContext());
1152 return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM, AccessTy,
1167 const APInt &C2APIntVal = C2->getAPIntValue();
1175 const APInt &C1APIntVal = C1->getAPIntValue();
1176 const APInt CombinedValueIntVal = C1APIntVal + C2APIntVal;
1179 const int64_t CombinedValue = CombinedValueIntVal.
getSExtValue();
1181 for (SDNode *Node :
N->users()) {
1188 TargetLoweringBase::AddrMode AM;
1190 AM.
BaseOffs = C2APIntVal.getSExtValue();
1192 unsigned AS =
LoadStore->getAddressSpace();
1208 for (SDNode *Node :
N->users()) {
1210 if (!LoadStore || !
LoadStore->hasUniqueMemOperand())
1215 TargetLoweringBase::AddrMode AM;
1217 AM.
BaseOffs = C2APIntVal.getSExtValue();
1219 unsigned AS =
LoadStore->getAddressSpace();
1232SDValue DAGCombiner::reassociateOpsCommutative(
unsigned Opc,
const SDLoc &
DL,
1234 SDNodeFlags Flags) {
1244 SDNodeFlags NewFlags;
1246 Flags.hasNoUnsignedWrap())
1254 return DAG.
getNode(
Opc,
DL, VT, N00, OpNode, NewFlags);
1262 return DAG.
getNode(
Opc,
DL, VT, OpNode, N01, NewFlags);
1272 if (N1 == N00 || N1 == N01)
1318 if (CC1 == CC00 && CC1 != CC01) {
1322 if (CC1 == CC01 && CC1 != CC00) {
1336 SDValue N1, SDNodeFlags Flags) {
1342 if (!
Flags.hasAllowReassociation() || !
Flags.hasNoSignedZeros())
1345 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N0, N1, Flags))
1347 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N1, N0, Flags))
1355SDValue DAGCombiner::reassociateReduction(
unsigned RedOpc,
unsigned Opc,
1357 SDValue N1, SDNodeFlags Flags) {
1363 SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
1385 A.getValueType() ==
C.getValueType() &&
1386 hasOperation(
Opc,
A.getValueType()) &&
1394 SelectionDAG::FlagInserter FlagsInserter(
1405SDValue DAGCombiner::CombineTo(SDNode *
N,
const SDValue *To,
unsigned NumTo,
1407 assert(
N->getNumValues() == NumTo &&
"Broken CombineTo call!");
1411 dbgs() <<
" and " << NumTo - 1 <<
" other values\n");
1412 for (
unsigned i = 0, e = NumTo; i !=
e; ++i)
1414 N->getValueType(i) == To[i].getValueType()) &&
1415 "Cannot combine value to value of different type!");
1417 WorklistRemover DeadNodes(*
this);
1421 for (
unsigned i = 0, e = NumTo; i !=
e; ++i) {
1423 AddToWorklistWithUsers(To[i].
getNode());
1431 deleteAndRecombine(
N);
1436CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO) {
1449 recursivelyDeleteUnusedNodes(TLO.
Old.
getNode());
1454bool DAGCombiner::SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
1455 const APInt &DemandedElts,
1456 bool AssumeSingleUse) {
1457 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1464 AddToWorklist(
Op.getNode());
1466 CommitTargetLoweringOpt(TLO);
1473bool DAGCombiner::SimplifyDemandedVectorElts(
SDValue Op,
1474 const APInt &DemandedElts,
1475 bool AssumeSingleUse) {
1476 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1477 APInt KnownUndef, KnownZero;
1479 TLO, 0, AssumeSingleUse))
1483 AddToWorklist(
Op.getNode());
1485 CommitTargetLoweringOpt(TLO);
1489void DAGCombiner::ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad) {
1491 EVT VT =
Load->getValueType(0);
1500 AddToWorklist(Trunc.
getNode());
1501 recursivelyDeleteUnusedNodes(Load);
1509 EVT MemVT =
LD->getMemoryVT();
1511 :
LD->getExtensionType();
1514 LD->getChain(),
LD->getBasePtr(),
1515 MemVT,
LD->getMemOperand());
1518 unsigned Opc =
Op.getOpcode();
1522 if (
SDValue Op0 = SExtPromoteOperand(
Op.getOperand(0), PVT))
1526 if (
SDValue Op0 = ZExtPromoteOperand(
Op.getOperand(0), PVT))
1544 EVT OldVT =
Op.getValueType();
1550 AddToWorklist(NewOp.
getNode());
1553 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1559 EVT OldVT =
Op.getValueType();
1565 AddToWorklist(NewOp.
getNode());
1568 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1576 if (!LegalOperations)
1579 EVT VT =
Op.getValueType();
1585 unsigned Opc =
Op.getOpcode();
1593 assert(PVT != VT &&
"Don't know what type to promote to!");
1597 bool Replace0 =
false;
1599 SDValue NN0 = PromoteOperand(N0, PVT, Replace0);
1601 bool Replace1 =
false;
1603 SDValue NN1 = PromoteOperand(N1, PVT, Replace1);
1615 Replace1 &= (N0 != N1) && !N1->
hasOneUse();
1618 CombineTo(
Op.getNode(), RV);
1644 if (!LegalOperations)
1647 EVT VT =
Op.getValueType();
1653 unsigned Opc =
Op.getOpcode();
1661 assert(PVT != VT &&
"Don't know what type to promote to!");
1665 SDNodeFlags TruncFlags;
1669 N0 = SExtPromoteOperand(N0, PVT);
1671 N0 = ZExtPromoteOperand(N0, PVT);
1673 if (
Op->getFlags().hasNoUnsignedWrap()) {
1674 N0 = ZExtPromoteOperand(N0, PVT);
1676 }
else if (
Op->getFlags().hasNoSignedWrap()) {
1677 N0 = SExtPromoteOperand(N0, PVT);
1680 N0 = PromoteOperand(N0, PVT,
Replace);
1693 ReplaceLoadWithPromotedLoad(
Op.getOperand(0).getNode(), N0.
getNode());
1703 if (!LegalOperations)
1706 EVT VT =
Op.getValueType();
1712 unsigned Opc =
Op.getOpcode();
1720 assert(PVT != VT &&
"Don't know what type to promote to!");
1725 return DAG.
getNode(
Op.getOpcode(), SDLoc(
Op), VT,
Op.getOperand(0));
1730bool DAGCombiner::PromoteLoad(
SDValue Op) {
1731 if (!LegalOperations)
1737 EVT VT =
Op.getValueType();
1743 unsigned Opc =
Op.getOpcode();
1751 assert(PVT != VT &&
"Don't know what type to promote to!");
1754 SDNode *
N =
Op.getNode();
1756 EVT MemVT =
LD->getMemoryVT();
1758 :
LD->getExtensionType();
1760 LD->getChain(),
LD->getBasePtr(),
1761 MemVT,
LD->getMemOperand());
1770 AddToWorklist(
Result.getNode());
1771 recursivelyDeleteUnusedNodes(
N);
1784bool DAGCombiner::recursivelyDeleteUnusedNodes(SDNode *
N) {
1785 if (!
N->use_empty())
1788 SmallSetVector<SDNode *, 16> Nodes;
1795 if (
N->use_empty()) {
1796 for (
const SDValue &ChildN :
N->op_values())
1797 Nodes.
insert(ChildN.getNode());
1799 removeFromWorklist(
N);
1804 }
while (!Nodes.
empty());
1823 WorklistInserter AddNodes(*
this);
1825 if (UseTopologicalSorting)
1834 if (UseTopologicalSorting) {
1836 AddToWorklist(&Node,
Node.use_empty());
1838 for (SDNode &Node : DAG.
allnodes())
1839 AddToWorklist(&Node,
Node.use_empty());
1845 HandleSDNode Dummy(DAG.
getRoot());
1848 while (SDNode *
N = getNextWorklistEntry()) {
1852 if (recursivelyDeleteUnusedNodes(
N))
1855 WorklistRemover DeadNodes(*
this);
1860 SmallSetVector<SDNode *, 16> UpdatedNodes;
1863 for (SDNode *LN : UpdatedNodes)
1864 AddToWorklistWithUsers(LN);
1876 for (
const SDValue &ChildN :
N->op_values())
1877 AddToWorklist(ChildN.getNode(),
true,
1888 ChainsWithoutMergeableStores.
clear();
1899 "Node was deleted but visit returned new node!");
1907 N->getNumValues() == 1 &&
"Type mismatch");
1917 AddToWorklistWithUsers(RV.
getNode());
1923 recursivelyDeleteUnusedNodes(
N);
1927 DAG.
setRoot(Dummy.getValue());
1931SDValue DAGCombiner::visit(SDNode *
N) {
1933 switch (
N->getOpcode()) {
2082 return visitPARTIAL_REDUCE_MLA(
N);
2108#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) case ISD::SDOPC:
2109#include "llvm/IR/VPIntrinsics.def"
2110 return visitVPOp(
N);
2116SDValue DAGCombiner::combine(SDNode *
N) {
2121 if (!DisableGenericCombines)
2127 "Node was deleted but visit returned NULL!");
2133 TargetLowering::DAGCombinerInfo
2134 DagCombineInfo(DAG, Level,
false,
this);
2142 switch (
N->getOpcode()) {
2150 RV = PromoteIntBinOp(
SDValue(
N, 0));
2155 RV = PromoteIntShiftOp(
SDValue(
N, 0));
2191 if (
unsigned NumOps =
N->getNumOperands()) {
2192 if (
N->getOperand(0).getValueType() == MVT::Other)
2193 return N->getOperand(0);
2194 if (
N->getOperand(
NumOps-1).getValueType() == MVT::Other)
2195 return N->getOperand(
NumOps-1);
2196 for (
unsigned i = 1; i <
NumOps-1; ++i)
2197 if (
N->getOperand(i).getValueType() == MVT::Other)
2198 return N->getOperand(i);
2203SDValue DAGCombiner::visitFCANONICALIZE(SDNode *
N) {
2204 SDValue Operand =
N->getOperand(0);
2216SDValue DAGCombiner::visitTokenFactor(SDNode *
N) {
2219 if (
N->getNumOperands() == 2) {
2221 return N->getOperand(0);
2223 return N->getOperand(1);
2238 AddToWorklist(*(
N->user_begin()));
2242 SmallPtrSet<SDNode*, 16> SeenOps;
2250 for (
unsigned i = 0; i < TFs.
size(); ++i) {
2255 for (
unsigned j = i;
j < TFs.
size();
j++)
2256 Ops.emplace_back(TFs[j], 0);
2263 SDNode *TF = TFs[i];
2266 switch (
Op.getOpcode()) {
2284 if (SeenOps.
insert(
Op.getNode()).second)
2295 for (
unsigned i = 1, e = TFs.
size(); i < e; i++)
2296 AddToWorklist(TFs[i]);
2306 SmallVector<unsigned, 8> OpWorkCount;
2307 SmallPtrSet<SDNode *, 16> SeenChains;
2308 bool DidPruneOps =
false;
2310 unsigned NumLeftToConsider = 0;
2312 Worklist.
push_back(std::make_pair(
Op.getNode(), NumLeftToConsider++));
2316 auto AddToWorklist = [&](
unsigned CurIdx, SDNode *
Op,
unsigned OpNumber) {
2322 unsigned OrigOpNumber = 0;
2323 while (OrigOpNumber <
Ops.size() &&
Ops[OrigOpNumber].getNode() !=
Op)
2326 "expected to find TokenFactor Operand");
2328 for (
unsigned i = CurIdx + 1; i < Worklist.
size(); ++i) {
2329 if (Worklist[i].second == OrigOpNumber) {
2330 Worklist[i].second = OpNumber;
2333 OpWorkCount[OpNumber] += OpWorkCount[OrigOpNumber];
2334 OpWorkCount[OrigOpNumber] = 0;
2335 NumLeftToConsider--;
2338 if (SeenChains.
insert(
Op).second) {
2339 OpWorkCount[OpNumber]++;
2344 for (
unsigned i = 0; i < Worklist.
size() && i < 1024; ++i) {
2346 if (NumLeftToConsider <= 1)
2348 auto CurNode = Worklist[i].first;
2349 auto CurOpNumber = Worklist[i].second;
2350 assert((OpWorkCount[CurOpNumber] > 0) &&
2351 "Node should not appear in worklist");
2352 switch (CurNode->getOpcode()) {
2358 NumLeftToConsider++;
2361 for (
const SDValue &
Op : CurNode->op_values())
2362 AddToWorklist(i,
Op.getNode(), CurOpNumber);
2368 AddToWorklist(i, CurNode->getOperand(0).getNode(), CurOpNumber);
2372 AddToWorklist(i, MemNode->getChain().getNode(), CurOpNumber);
2375 OpWorkCount[CurOpNumber]--;
2376 if (OpWorkCount[CurOpNumber] == 0)
2377 NumLeftToConsider--;
2391 if (SeenChains.
count(
Op.getNode()) == 0)
2405SDValue DAGCombiner::visitMERGE_VALUES(SDNode *
N) {
2406 WorklistRemover DeadNodes(*
this);
2412 AddUsersToWorklist(
N);
2417 }
while (!
N->use_empty());
2418 deleteAndRecombine(
N);
2426 return Const !=
nullptr && !Const->isOpaque() ? Const :
nullptr;
2436 Op =
N->getOperand(0);
2438 if (
N->getFlags().hasNoUnsignedWrap())
2443 if (
N.getValueType().getScalarType() != MVT::i1 ||
2460 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2462 VT = LD->getMemoryVT();
2463 AS = LD->getAddressSpace();
2465 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2467 VT = ST->getMemoryVT();
2468 AS = ST->getAddressSpace();
2470 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2472 VT = LD->getMemoryVT();
2473 AS = LD->getAddressSpace();
2475 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2477 VT = ST->getMemoryVT();
2478 AS = ST->getAddressSpace();
2484 if (
N->isAnyAdd()) {
2493 }
else if (
N->getOpcode() ==
ISD::SUB) {
2515 bool ShouldCommuteOperands) {
2521 if (ShouldCommuteOperands)
2535 unsigned Opcode =
N->getOpcode();
2536 EVT VT =
N->getValueType(0);
2541 unsigned OpNo = ShouldCommuteOperands ? 0 : 1;
2561SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
2564 "Unexpected binary operator");
2576 unsigned SelOpNo = 0;
2613 bool CanFoldNonConst =
2619 if (!CanFoldNonConst &&
2628 if (CanFoldNonConst) {
2647 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CT, CBO});
2652 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CF, CBO});
2663 "Expecting add or sub");
2668 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2669 SDValue C = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2670 SDValue Z = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2676 if (Z.getOperand(0).getValueType() != MVT::i1)
2688 EVT VT =
C.getValueType();
2696SDValue DAGCombiner::foldSubToAvg(SDNode *
N,
const SDLoc &
DL) {
2701 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
2706 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
2717SDValue DAGCombiner::visitPTRADD(SDNode *
N) {
2727 "PTRADD with different operand types is not supported");
2738 !reassociationCanBreakAddressingModePattern(
ISD::PTRADD,
DL,
N, N0, N1)) {
2749 if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
2754 AddToWorklist(
Add.getNode());
2778 if (
const GlobalAddressSDNode *GA =
2793 AddToWorklist(Inner.
getNode());
2815 SDNodeFlags CommonFlags =
N->getFlags() & N1->
getFlags();
2823 if (ZIsConstant != YIsConstant) {
2827 AddToWorklist(Inner.
getNode());
2837 bool TransformCannotBreakAddrMode =
none_of(
N->users(), [&](SDNode *User) {
2838 return canFoldInAddressingMode(N, User, DAG, TLI);
2841 if (TransformCannotBreakAddrMode)
2853 "Expecting add or sub");
2857 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2858 SDValue ConstantOp = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2859 SDValue ShiftOp = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2881 {ConstantOp, DAG.getConstant(1, DL, VT)})) {
2883 Not.getOperand(0), ShAmt);
2899SDValue DAGCombiner::visitADDLike(SDNode *
N) {
2925 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
2957 if ((!LegalOperations ||
2960 X.getScalarValueSizeInBits() == 1) {
2976 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
2980 if (!reassociationCanBreakAddressingModePattern(
ISD::ADD,
DL,
N, N0, N1)) {
2992 SDNodeFlags NewFlags =
3082 auto MatchUSUBSAT = [](ConstantSDNode *
Max, ConstantSDNode *
Op) {
3083 return (!Max && !
Op) ||
3084 (
Max &&
Op &&
Max->getAPIntValue() == (-
Op->getAPIntValue()));
3125 !
N->getFlags().hasNoSignedWrap()))) {
3146 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3150 if (
N->getFlags().hasNoUnsignedWrap() &&
3154 if (
N->getFlags().hasNoSignedWrap() &&
3163 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3171 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3177 if (
N->getFlags().hasNoUnsignedWrap() &&
3182 if (
N->getFlags().hasNoSignedWrap() &&
3193 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3198 if (
SDValue Combined = visitADDLikeCommutative(N0, N1,
N))
3201 if (
SDValue Combined = visitADDLikeCommutative(N1, N0,
N))
3210SDValue DAGCombiner::foldAddToAvg(SDNode *
N,
const SDLoc &
DL) {
3236 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
3243 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
3254SDValue DAGCombiner::visitADD(SDNode *
N) {
3260 if (
SDValue Combined = visitADDLike(
N))
3269 if (
SDValue V = MatchRotate(N0, N1, SDLoc(
N),
true))
3303 APInt NewStep = C0 + C1;
3313 APInt NewStep = SV0 + SV1;
3321SDValue DAGCombiner::visitADDSAT(SDNode *
N) {
3322 unsigned Opcode =
N->getOpcode();
3340 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
3344 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
3364 bool ForceCarryReconstruction =
false) {
3369 if (ForceCarryReconstruction && V.getValueType() == MVT::i1)
3373 V = V.getOperand(0);
3378 if (ForceCarryReconstruction)
3382 V = V.getOperand(0);
3390 if (V.getResNo() != 1)
3397 EVT VT = V->getValueType(0);
3441 SDNode *LocReference) {
3443 SDLoc
DL(LocReference);
3505 if (TN->
getVT() == MVT::i1) {
3522 DAG.
getVTList(VT, Carry.getValueType()), N0,
3528SDValue DAGCombiner::visitADDC(SDNode *
N) {
3535 if (!
N->hasAnyUseOfValue(1))
3575 return V.getOperand(0);
3581SDValue DAGCombiner::visitADDO(SDNode *
N) {
3587 EVT CarryVT =
N->getValueType(1);
3591 if (!
N->hasAnyUseOfValue(1))
3598 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
3623 if (
SDValue Combined = visitUADDOLike(N0, N1,
N))
3626 if (
SDValue Combined = visitUADDOLike(N1, N0,
N))
3657SDValue DAGCombiner::visitADDE(SDNode *
N) {
3676SDValue DAGCombiner::visitUADDO_CARRY(SDNode *
N) {
3690 if (!LegalOperations ||
3700 AddToWorklist(CarryExt.
getNode());
3706 if (
SDValue Combined = visitUADDO_CARRYLike(N0, N1, CarryIn,
N))
3709 if (
SDValue Combined = visitUADDO_CARRYLike(N1, N0, CarryIn,
N))
3856 EVT CarryOutType =
N->getValueType(0);
3872 unsigned CarryInOperandNum =
3874 if (Opcode ==
ISD::USUBO && CarryInOperandNum != 1)
3927 EVT IntVT =
A.getValueType();
3992SDValue DAGCombiner::visitSADDO_CARRY(SDNode *
N) {
4006 if (!LegalOperations ||
4011 if (
SDValue Combined = visitSADDO_CARRYLike(N0, N1, CarryIn,
N))
4014 if (
SDValue Combined = visitSADDO_CARRYLike(N1, N0, CarryIn,
N))
4026 "Illegal truncation");
4050SDValue DAGCombiner::foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL) {
4052 !(!LegalOperations || hasOperation(
ISD::USUBSAT, DstVT)))
4055 EVT SubVT =
N->getValueType(0);
4123template <
class MatchContextClass>
4146 if ((
BitWidth - Src.getValueType().getScalarSizeInBits()) != BitWidthDiff)
4157 unsigned AndMaskWidth =
BitWidth - BitWidthDiff;
4158 if (!(AndMask.
isMask(AndMaskWidth) && XorMask.
countr_one() >= AndMaskWidth))
4193 if (
SDValue Res = CheckAndFoldMulCase(Mul0, Mul1))
4196 if (
SDValue Res = CheckAndFoldMulCase(Mul1, Mul0))
4234SDValue DAGCombiner::visitSUB(SDNode *
N) {
4254 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4281 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4304 if (
N->getFlags().hasNoUnsignedWrap())
4310 if (
N->getFlags().hasNoSignedWrap())
4336 if (hasOperation(NewOpc, VT))
4478 if (!reassociationCanBreakAddressingModePattern(
ISD::SUB,
DL,
N, N0, N1) &&
4516 if ((!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4526 if (GA->getGlobal() == GB->getGlobal())
4527 return DAG.
getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
4534 if (TN->
getVT() == MVT::i1) {
4545 if (!
IntVal.isPowerOf2() ||
4590 DAG.
getVTList(VT, Carry.getValueType()), NegX, Zero,
4596 const APInt &C0Val = C0->getAPIntValue();
4599 if (
N->getFlags().hasNoUnsignedWrap() && C0Val.
isMask())
4604 if (!C0->isOpaque()) {
4605 const APInt &MaybeOnes = ~DAG.computeKnownBits(N1).Zero;
4606 if ((C0Val - MaybeOnes) == (C0Val ^ MaybeOnes))
4612 if ((!LegalOperations || hasOperation(
ISD::ABDS, VT)) &&
4624 if ((!LegalOperations || hasOperation(
ISD::ABDU, VT)) &&
4638SDValue DAGCombiner::visitSUBSAT(SDNode *
N) {
4639 unsigned Opcode =
N->getOpcode();
4660 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4679SDValue DAGCombiner::visitSUBC(SDNode *
N) {
4686 if (!
N->hasAnyUseOfValue(1))
4707SDValue DAGCombiner::visitSUBO(SDNode *
N) {
4713 EVT CarryVT =
N->getValueType(1);
4717 if (!
N->hasAnyUseOfValue(1))
4749SDValue DAGCombiner::visitSUBE(SDNode *
N) {
4761SDValue DAGCombiner::visitUSUBO_CARRY(SDNode *
N) {
4768 if (!LegalOperations ||
4776SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *
N) {
4783 if (!LegalOperations ||
4793SDValue DAGCombiner::visitMULFIX(SDNode *
N) {
4806 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0, Scale);
4815SDValue DAGCombiner::visitMUL(SDNode *
N) {
4835 bool N1IsConst =
false;
4836 bool N1IsOpaqueConst =
false;
4841 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4846 "Splat APInt should be element width");
4856 if (N1IsConst && ConstValue1.
isZero())
4860 if (N1IsConst && ConstValue1.
isOne())
4863 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4867 if (N1IsConst && ConstValue1.
isAllOnes())
4873 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
4877 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap());
4880 if (
N->getFlags().hasNoSignedWrap() && N1IsConst &&
4882 Flags.setNoSignedWrap(
true);
4889 unsigned Log2Val = (-ConstValue1).logBase2();
4903 SDVTList LoHiVT = DAG.
getVTList(VT, VT);
4906 if (LoHi->hasAnyUseOfValue(1))
4909 if (LoHi->hasAnyUseOfValue(1))
4934 APInt MulC = ConstValue1.
abs();
4936 unsigned TZeros = MulC == 2 ? 0 : MulC.
countr_zero();
4938 if ((MulC - 1).isPowerOf2())
4940 else if ((MulC + 1).isPowerOf2())
4945 MathOp ==
ISD::ADD ? (MulC - 1).logBase2() : (MulC + 1).logBase2();
4948 "multiply-by-constant generated out of bounds shift");
4952 TZeros ? DAG.
getNode(MathOp,
DL, VT, Shl,
5007 APInt NewStep = C0 * MulVal;
5013 if ((!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
5026 SmallBitVector ClearMask;
5028 auto IsClearMask = [&ClearMask](ConstantSDNode *
V) {
5029 if (!V ||
V->isZero()) {
5043 for (
unsigned I = 0;
I != NumElts; ++
I)
5070 EVT NodeType =
Node->getValueType(0);
5071 if (!NodeType.isSimple())
5073 switch (NodeType.getSimpleVT().SimpleTy) {
5074 default:
return false;
5075 case MVT::i8: LC=
isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
5076 case MVT::i16: LC=
isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
5077 case MVT::i32: LC=
isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
5078 case MVT::i64: LC=
isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
5079 case MVT::i128: LC=
isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
5086SDValue DAGCombiner::useDivRem(SDNode *Node) {
5087 if (
Node->use_empty())
5090 unsigned Opcode =
Node->getOpcode();
5095 EVT VT =
Node->getValueType(0);
5109 unsigned OtherOpcode = 0;
5123 for (SDNode *User : Op0->
users()) {
5130 unsigned UserOpc =
User->getOpcode();
5131 if ((UserOpc == Opcode || UserOpc == OtherOpcode || UserOpc == DivRemOpc) &&
5132 User->getOperand(0) == Op0 &&
5133 User->getOperand(1) == Op1) {
5135 if (UserOpc == OtherOpcode) {
5137 combined = DAG.
getNode(DivRemOpc, SDLoc(Node), VTs, Op0, Op1);
5138 }
else if (UserOpc == DivRemOpc) {
5141 assert(UserOpc == Opcode);
5146 CombineTo(User, combined);
5148 CombineTo(User, combined.
getValue(1));
5157 EVT VT =
N->getValueType(0);
5160 unsigned Opc =
N->getOpcode();
5179 if (N0C && N0C->
isZero())
5199SDValue DAGCombiner::visitSDIV(SDNode *
N) {
5202 EVT VT =
N->getValueType(0);
5212 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5229 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5237 if (
SDValue V = visitSDIVLike(N0, N1,
N)) {
5244 if (!
N->getFlags().hasExact()) {
5247 AddToWorklist(
Mul.getNode());
5248 AddToWorklist(
Sub.getNode());
5249 CombineTo(RemNode,
Sub);
5270 if (
C->isZero() ||
C->isOpaque())
5272 if (
C->getAPIntValue().isPowerOf2())
5274 if (
C->getAPIntValue().isNegatedPowerOf2())
5285 EVT VT =
N->getValueType(0);
5296 if ((!
N->getFlags().hasExact() ||
BitWidth > MaxLegalDivRemBitWidth) &&
5314 AddToWorklist(Sign.
getNode());
5320 AddToWorklist(
Add.getNode());
5331 Sra = DAG.
getSelect(
DL, VT, IsOneOrAllOnes, N0, Sra);
5357SDValue DAGCombiner::visitUDIV(SDNode *
N) {
5360 EVT VT =
N->getValueType(0);
5370 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5384 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5387 if (
SDValue V = visitUDIVLike(N0, N1,
N)) {
5394 if (!
N->getFlags().hasExact()) {
5397 AddToWorklist(
Mul.getNode());
5398 AddToWorklist(
Sub.getNode());
5399 CombineTo(RemNode,
Sub);
5424 EVT VT =
N->getValueType(0);
5429 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5430 AddToWorklist(LogBase2.getNode());
5434 AddToWorklist(Trunc.
getNode());
5444 if (
SDValue LogBase2 = BuildLogBase2(N10,
DL)) {
5445 AddToWorklist(LogBase2.getNode());
5449 AddToWorklist(Trunc.
getNode());
5451 AddToWorklist(
Add.getNode());
5479SDValue DAGCombiner::visitREM(SDNode *
N) {
5480 unsigned Opcode =
N->getOpcode();
5483 EVT VT =
N->getValueType(0);
5505 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5518 AddToWorklist(
Add.getNode());
5535 if (
SDValue OptimizedRem = buildOptimizedSREM(N0, N1,
N))
5536 return OptimizedRem;
5540 isSigned ? visitSDIVLike(N0, N1,
N) : visitUDIVLike(N0, N1,
N);
5543 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
5544 if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
5546 CombineTo(DivNode, OptimizedDiv);
5549 AddToWorklist(OptimizedDiv.
getNode());
5550 AddToWorklist(
Mul.getNode());
5557 return DivRem.getValue(1);
5580SDValue DAGCombiner::visitMULHS(SDNode *
N) {
5583 EVT VT =
N->getValueType(0);
5596 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5639SDValue DAGCombiner::visitMULHU(SDNode *
N) {
5642 EVT VT =
N->getValueType(0);
5655 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5679 (!LegalOperations || hasOperation(
ISD::SRL, VT))) {
5680 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5695 unsigned SimpleSize =
Simple.getSizeInBits();
5716SDValue DAGCombiner::visitAVG(SDNode *
N) {
5717 unsigned Opcode =
N->getOpcode();
5720 EVT VT =
N->getValueType(0);
5731 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5734 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5760 X.getValueType() ==
Y.getValueType() &&
5761 hasOperation(Opcode,
X.getValueType())) {
5767 X.getValueType() ==
Y.getValueType() &&
5768 hasOperation(Opcode,
X.getValueType())) {
5801 if (IsSigned &&
Add->getFlags().hasNoSignedWrap())
5804 if (!IsSigned &&
Add->getFlags().hasNoUnsignedWrap())
5818SDValue DAGCombiner::visitABD(SDNode *
N) {
5819 unsigned Opcode =
N->getOpcode();
5822 EVT VT =
N->getValueType(0);
5832 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5835 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5850 (!LegalOperations || hasOperation(
ISD::ABS, VT)))
5865 EVT SmallVT =
X.getScalarValueSizeInBits() >
Y.getScalarValueSizeInBits()
5868 if (!LegalOperations || hasOperation(Opcode, SmallVT)) {
5880 EVT SmallVT =
X.getValueType();
5881 if (!LegalOperations || hasOperation(Opcode, SmallVT)) {
5883 unsigned RelevantBits =
5890 const APInt &YConst =
C->getAsAPIntVal();
5897 if (RelevantBits <= Bits && TruncatingYIsCheap) {
5911SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
5914 bool HiExists =
N->hasAnyUseOfValue(1);
5915 if (!HiExists && (!LegalOperations ||
5918 return CombineTo(
N, Res, Res);
5922 bool LoExists =
N->hasAnyUseOfValue(0);
5923 if (!LoExists && (!LegalOperations ||
5926 return CombineTo(
N, Res, Res);
5930 if (LoExists && HiExists)
5936 AddToWorklist(
Lo.getNode());
5939 (!LegalOperations ||
5941 return CombineTo(
N, LoOpt, LoOpt);
5946 AddToWorklist(
Hi.getNode());
5949 (!LegalOperations ||
5951 return CombineTo(
N, HiOpt, HiOpt);
5957SDValue DAGCombiner::visitSMUL_LOHI(SDNode *
N) {
5963 EVT VT =
N->getValueType(0);
5979 unsigned SimpleSize =
Simple.getSizeInBits();
5991 return CombineTo(
N,
Lo,
Hi);
5998SDValue DAGCombiner::visitUMUL_LOHI(SDNode *
N) {
6004 EVT VT =
N->getValueType(0);
6019 return CombineTo(
N, Zero, Zero);
6025 return CombineTo(
N, N0, Zero);
6032 unsigned SimpleSize =
Simple.getSizeInBits();
6044 return CombineTo(
N,
Lo,
Hi);
6051SDValue DAGCombiner::visitMULO(SDNode *
N) {
6057 EVT CarryVT =
N->getValueType(1);
6078 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
6090 N->getVTList(), N0, N0);
6097 return CombineTo(
N,
And, Cmp);
6135 unsigned Opcode0 = isSignedMinMax(N0, N1, N2, N3, CC);
6189 unsigned Opcode1 = isSignedMinMax(N00, N01, N02, N03, N0CC);
6190 if (!Opcode1 || Opcode0 == Opcode1)
6200 APInt MinCPlus1 = MinC + 1;
6201 if (-MaxC == MinCPlus1 && MinCPlus1.
isPowerOf2()) {
6207 if (MaxC == 0 && MinC != 0 && MinCPlus1.
isPowerOf2()) {
6256 unsigned BW = (C1 + 1).exactLogBase2();
6270SDValue DAGCombiner::visitIMINMAX(SDNode *
N) {
6274 unsigned Opcode =
N->getOpcode();
6288 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
6292 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
6296 if (
SDValue RMINMAX = reassociateOps(Opcode,
DL, N0, N1,
N->getFlags()))
6307 if (IsSatBroken || IsOpIllegal) {
6309 if (
A.isUndef() ||
B.isUndef())
6322 if (HasKnownSameSign(N0, N1)) {
6325 return DAG.
getNode(AltOpcode,
DL, VT, N0, N1);
6338 auto ReductionOpcode = [](
unsigned Opcode) {
6352 if (
SDValue SD = reassociateReduction(ReductionOpcode(Opcode), Opcode,
6353 SDLoc(
N), VT, N0, N1))
6361 return C0 > C1 ? N0 : N1;
6363 return C0 > C1 ? N1 : N0;
6372 const APInt &C1V = C1->getAPIntValue();
6391SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *
N) {
6394 unsigned LogicOpcode =
N->getOpcode();
6419 if (XVT !=
Y.getValueType())
6423 if ((VT.
isVector() || LegalOperations) &&
6433 SDNodeFlags LogicFlags;
6439 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6449 if (XVT !=
Y.getValueType())
6461 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6482 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6497 return DAG.
getNode(HandOpcode,
DL, VT, Logic0, Logic1, S);
6510 if (XVT.
isInteger() && XVT ==
Y.getValueType() &&
6514 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6533 assert(
X.getValueType() ==
Y.getValueType() &&
6534 "Inputs to shuffles are not the same type");
6540 if (!SVN0->hasOneUse() || !SVN1->hasOneUse() ||
6541 !SVN0->getMask().equals(SVN1->getMask()))
6577 SDValue LL, LR, RL, RR, N0CC, N1CC;
6578 if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
6579 !isSetCCEquivalent(N1, RL, RR, N1CC))
6583 "Unexpected operand types for bitwise logic op");
6586 "Unexpected operand types for setcc");
6602 if (LR == RR && CC0 == CC1 && IsInteger) {
6607 bool AndEqZero = IsAnd && CC1 ==
ISD::SETEQ && IsZero;
6609 bool AndGtNeg1 = IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6611 bool OrNeZero = !IsAnd && CC1 ==
ISD::SETNE && IsZero;
6613 bool OrLtZero = !IsAnd && CC1 ==
ISD::SETLT && IsZero;
6619 if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
6621 AddToWorklist(
Or.getNode());
6626 bool AndEqNeg1 = IsAnd && CC1 ==
ISD::SETEQ && IsNeg1;
6628 bool AndLtZero = IsAnd && CC1 ==
ISD::SETLT && IsZero;
6630 bool OrNeNeg1 = !IsAnd && CC1 ==
ISD::SETNE && IsNeg1;
6632 bool OrGtNeg1 = !IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6638 if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
6640 AddToWorklist(
And.getNode());
6654 AddToWorklist(
Add.getNode());
6675 auto MatchDiffPow2 = [&](ConstantSDNode *C0, ConstantSDNode *C1) {
6681 return !C0->
isOpaque() && !C1->isOpaque() && (CMax - CMin).isPowerOf2();
6699 if (LL == RR && LR == RL) {
6706 if (LL == RL && LR == RR) {
6710 (!LegalOperations ||
6747 unsigned OrAndOpcode,
SelectionDAG &DAG,
bool isFMAXNUMFMINNUM_IEEE,
6748 bool isFMAXNUMFMINNUM) {
6759 isFMAXNUMFMINNUM_IEEE
6767 isFMAXNUMFMINNUM_IEEE
6785 isFMAXNUMFMINNUM_IEEE
6794 isFMAXNUMFMINNUM_IEEE
6805 (LogicOp->getOpcode() ==
ISD::AND || LogicOp->getOpcode() ==
ISD::OR) &&
6806 "Invalid Op to combine SETCC with");
6812 !
LHS->hasOneUse() || !
RHS->hasOneUse())
6819 LogicOp,
LHS.getNode(),
RHS.getNode());
6831 EVT VT = LogicOp->getValueType(0);
6854 (isFMAXNUMFMINNUM_IEEE || isFMAXNUMFMINNUM))) &&
6860 SDValue CommonValue, Operand1, Operand2;
6868 }
else if (LHS1 == RHS1) {
6881 }
else if (RHS0 == LHS1) {
6898 bool IsSigned = isSignedIntSetCC(CC);
6902 bool IsOr = (LogicOp->getOpcode() ==
ISD::OR);
6911 LogicOp->getOpcode(), DAG, isFMAXNUMFMINNUM_IEEE, isFMAXNUMFMINNUM);
6917 DAG.
getNode(NewOpcode,
DL, OpVT, Operand1, Operand2, Flags);
6918 return DAG.
getSetCC(
DL, VT, MinMaxValue, CommonValue, CC, {},
6924 if (LHS0 == LHS1 && RHS0 == RHS1 && CCL == CCR &&
6928 return DAG.
getSetCC(
DL, VT, LHS0, RHS0, CCL);
6935 LHS0 == RHS0 && LHS1C && RHS1C && OpVT.
isInteger()) {
6936 const APInt &APLhs = LHS1C->getAPIntValue();
6937 const APInt &APRhs = RHS1C->getAPIntValue();
6941 if (APLhs == (-APRhs) &&
6952 }
else if (TargetPreference &
6973 APInt Dif = MaxC - MinC;
7007 EVT CondVT =
Cond.getValueType();
7018 EVT OpVT =
T.getValueType();
7037 if (
SDValue V = foldLogicOfSetCCs(
true, N0, N1,
DL))
7054 APInt
ADDC = ADDI->getAPIntValue();
7055 APInt SRLC = SRLI->getAPIntValue();
7067 CombineTo(N0.
getNode(), NewAdd);
7080bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
7081 EVT LoadResultTy, EVT &ExtVT) {
7090 if (ExtVT == LoadedVT &&
7091 (!LegalOperations ||
7108 if (LegalOperations &&
7119bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
7128 const unsigned ByteShAmt = ShAmt / 8;
7147 if (LdStMemVT.
bitsLT(MemVT))
7162 if (PtrType == MVT::Untyped || PtrType.
isExtended())
7169 if (!
SDValue(Load, 0).hasOneUse())
7172 if (LegalOperations &&
7174 Load->getAddressSpace(), ExtType,
false))
7182 if (
Load->getNumValues() > 2)
7201 if (LegalOperations &&
7203 Store->getAlign(),
Store->getAddressSpace()))
7209bool DAGCombiner::SearchForAndLoads(SDNode *
N,
7210 SmallVectorImpl<LoadSDNode*> &Loads,
7211 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
7212 ConstantSDNode *Mask,
7213 SDNode *&NodeToMask) {
7217 if (
Op.getValueType().isVector())
7223 "Expected bitwise logic operation");
7224 if (!
C->getAPIntValue().isSubsetOf(
Mask->getAPIntValue()))
7229 if (!
Op.hasOneUse())
7232 switch(
Op.getOpcode()) {
7236 if (isAndLoadExtLoad(Mask, Load,
Load->getValueType(0), ExtVT) &&
7254 unsigned ActiveBits =
Mask->getAPIntValue().countr_one();
7258 Op.getOperand(0).getValueType();
7269 if (!SearchForAndLoads(
Op.getNode(), Loads, NodesWithConsts, Mask,
7280 NodeToMask =
Op.getNode();
7283 for (
unsigned i = 0, e = NodeToMask->
getNumValues(); i < e; ++i) {
7284 MVT VT =
SDValue(NodeToMask, i).getSimpleValueType();
7285 if (VT != MVT::Glue && VT != MVT::Other) {
7287 NodeToMask =
nullptr;
7299bool DAGCombiner::BackwardsPropagateMask(SDNode *
N) {
7304 if (!
Mask->getAPIntValue().isMask())
7312 SmallPtrSet<SDNode*, 2> NodesWithConsts;
7313 SDNode *FixupNode =
nullptr;
7314 if (SearchForAndLoads(
N, Loads, NodesWithConsts, Mask, FixupNode)) {
7327 SDValue(FixupNode, 0), MaskOp);
7329 if (
And.getOpcode() == ISD ::AND)
7334 for (
auto *LogicN : NodesWithConsts) {
7340 if (LogicN->getOpcode() ==
ISD::AND &&
7359 for (
auto *Load : Loads) {
7364 if (
And.getOpcode() == ISD ::AND)
7367 SDValue NewLoad = reduceLoadWidth(
And.getNode());
7369 "Shouldn't be masking the load if it can't be narrowed");
7370 CombineTo(Load, NewLoad, NewLoad.
getValue(1));
7383SDValue DAGCombiner::unfoldExtremeBitClearingToShifts(SDNode *
N) {
7394 unsigned OuterShift;
7395 unsigned InnerShift;
7397 auto matchMask = [&OuterShift, &InnerShift, &
Y](
SDValue M) ->
bool {
7400 OuterShift =
M->getOpcode();
7409 Y =
M->getOperand(1);
7416 else if (matchMask(N0))
7422 EVT VT =
N->getValueType(0);
7439 SDValue And0 =
And->getOperand(0), And1 =
And->getOperand(1);
7449 bool FoundNot =
false;
7452 Src = Src.getOperand(0);
7458 Src = Src.getOperand(0);
7462 if (Src.getOpcode() !=
ISD::SRL || !Src.hasOneUse())
7466 EVT SrcVT = Src.getValueType();
7475 if (!ShiftAmtC || !ShiftAmtC->getAPIntValue().ult(
BitWidth))
7479 Src = Src.getOperand(0);
7486 Src = Src.getOperand(0);
7510 EVT VT =
N->getValueType(0);
7536 unsigned LogicOpcode =
N->getOpcode();
7538 "Expected bitwise logic operation");
7540 if (!LogicOp.hasOneUse() || !ShiftOp.
hasOneUse())
7544 unsigned ShiftOpcode = ShiftOp.
getOpcode();
7545 if (LogicOp.getOpcode() != LogicOpcode ||
7557 if (LogicOp.getOperand(0).getOpcode() == ShiftOpcode &&
7558 LogicOp.getOperand(0).getOperand(1) ==
Y) {
7560 Z = LogicOp.getOperand(1);
7561 }
else if (LogicOp.getOperand(1).getOpcode() == ShiftOpcode &&
7562 LogicOp.getOperand(1).getOperand(1) ==
Y) {
7564 Z = LogicOp.getOperand(0);
7569 EVT VT =
N->getValueType(0);
7573 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift, Z);
7584 unsigned LogicOpcode =
N->getOpcode();
7586 "Expected bitwise logic operation");
7587 if (LeftHand.
getOpcode() != LogicOpcode ||
7608 EVT VT =
N->getValueType(0);
7610 return DAG.
getNode(LogicOpcode,
DL, VT, CombinedShifts, W);
7622 "Must be called with ISD::OR or ISD::AND node");
7636 EVT VT = M.getValueType();
7644SDValue DAGCombiner::visitAND(SDNode *
N) {
7668 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
7685 if (BV0 && BV1 && !BV0->getSplatValue() && !BV1->getSplatValue() &&
7687 BV0->getOperand(0).getValueType() ==
7688 BV1->getOperand(0).getValueType()) {
7691 EVT EltVT = BV0->getOperand(0).getValueType();
7692 for (
unsigned I = 0;
I != NumElts; ++
I) {
7698 else if (C0 && C0->
isZero())
7700 else if (C1 && C1->isZero())
7704 else if (C1 && C1->isAllOnes())
7706 else if (BV0->getOperand(
I) == BV1->getOperand(
I))
7711 if (MergedOps.
size() == NumElts)
7720 EVT MemVT =
MLoad->getMemoryVT();
7731 MLoad->isExpandingLoad());
7732 CombineTo(
N, Frozen ? N0 : NewLoad);
7733 CombineTo(MLoad, NewLoad, NewLoad.
getValue(1));
7753 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
7766 auto MatchSubset = [](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
7767 return RHS->getAPIntValue().isSubsetOf(
LHS->getAPIntValue());
7777 APInt
Mask = ~N1C->getAPIntValue();
7802 {N0Op0.getOperand(1)})) {
7835 unsigned EltBitWidth =
Vector->getValueType(0).getScalarSizeInBits();
7836 APInt SplatValue, SplatUndef;
7837 unsigned SplatBitSize;
7844 const bool IsBigEndian =
false;
7846 Vector->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
7847 HasAnyUndefs, EltBitWidth, IsBigEndian);
7851 if (IsSplat && (SplatBitSize % EltBitWidth) == 0) {
7854 SplatValue |= SplatUndef;
7861 for (
unsigned i = 0, n = (SplatBitSize / EltBitWidth); i < n; ++i)
7862 Constant &= SplatValue.
extractBits(EltBitWidth, i * EltBitWidth);
7870 Load->getValueType(0),
Load->getMemoryVT(),
Load->getAlign(),
7879 switch (
Load->getExtensionType()) {
7880 default:
B =
false;
break;
7892 CombineTo(
N, (N0.
getNode() == Load) ? NewLoad : N0);
7896 Load->getValueType(0), SDLoc(Load),
7897 Load->getChain(),
Load->getBasePtr(),
7898 Load->getOffset(),
Load->getMemoryVT(),
7899 Load->getMemOperand());
7901 if (
Load->getNumValues() == 3) {
7903 SDValue To[] = { NewLoad.getValue(0), NewLoad.getValue(1),
7904 NewLoad.getValue(2) };
7905 CombineTo(Load, To, 3,
true);
7907 CombineTo(Load, NewLoad.getValue(0), NewLoad.getValue(1));
7917 if (
SDValue Shuffle = XformToShuffleWithZero(
N))
7944 EVT MemVT = GN0->getMemoryVT();
7947 if (
SDValue(GN0, 0).hasOneUse() &&
7950 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
7951 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
7954 DAG.
getVTList(VT, MVT::Other), MemVT,
DL,
Ops, GN0->getMemOperand(),
7957 CombineTo(
N, ZExtLoad);
7958 AddToWorklist(ZExtLoad.
getNode());
7971 if (
SDValue Res = reduceLoadWidth(
N))
7980 if (BackwardsPropagateMask(
N))
7984 if (
SDValue Combined = visitANDLike(N0, N1,
N))
7989 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
8020 if (
SDValue Folded = foldBitwiseOpWithNeg(
N,
DL, VT))
8042 X.getOperand(0).getScalarValueSizeInBits() == 1)
8045 X.getOperand(0).getScalarValueSizeInBits() == 1)
8060 EVT MemVT = LN0->getMemoryVT();
8067 ((!LegalOperations && LN0->isSimple()) ||
8068 TLI.
isLoadLegal(VT, MemVT, LN0->getAlign(), LN0->getAddressSpace(),
8072 LN0->getBasePtr(), MemVT, LN0->getMemOperand());
8086 if (
SDValue Shifts = unfoldExtremeBitClearingToShifts(
N))
8106 if (!
C->getAPIntValue().isMask(
8107 LHS.getOperand(0).getValueType().getScalarSizeInBits()))
8114 if (IsAndZeroExtMask(N0, N1) &&
8124 if (LegalOperations || VT.
isVector())
8137 bool DemandHighBits) {
8138 if (!LegalOperations)
8141 EVT VT =
N->getValueType(0);
8142 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16)
8148 bool LookPassAnd0 =
false;
8149 bool LookPassAnd1 =
false;
8164 LookPassAnd0 =
true;
8174 LookPassAnd1 =
true;
8200 LookPassAnd0 =
true;
8214 LookPassAnd1 =
true;
8223 if (OpSizeInBits > 16) {
8227 if (DemandHighBits && !LookPassAnd0)
8234 if (!LookPassAnd1) {
8235 unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
8243 if (OpSizeInBits > 16) {
8258 if (!
N->hasOneUse())
8261 unsigned Opc =
N.getOpcode();
8279 unsigned MaskByteOffset;
8283 case 0xFF: MaskByteOffset = 0;
break;
8284 case 0xFF00: MaskByteOffset = 1;
break;
8293 case 0xFF0000: MaskByteOffset = 2;
break;
8294 case 0xFF000000: MaskByteOffset = 3;
break;
8299 if (MaskByteOffset == 0 || MaskByteOffset == 2) {
8305 if (!
C ||
C->getZExtValue() != 8)
8313 if (!
C ||
C->getZExtValue() != 8)
8319 if (MaskByteOffset != 0 && MaskByteOffset != 2)
8322 if (!
C ||
C->getZExtValue() != 8)
8327 if (MaskByteOffset != 1 && MaskByteOffset != 3)
8330 if (!
C ||
C->getZExtValue() != 8)
8334 if (Parts[MaskByteOffset])
8349 if (!
C ||
C->getAPIntValue() != 16)
8351 Parts[0] = Parts[1] =
N.getOperand(0).getOperand(0).getNode();
8366 "MatchBSwapHWordOrAndAnd: expecting i32");
8376 if (!Mask0 || !Mask1)
8387 if (!ShiftAmt0 || !ShiftAmt1)
8407 if (!LegalOperations)
8410 EVT VT =
N->getValueType(0);
8428 SDNode *Parts[4] = {};
8448 if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
8476 if (
SDValue V = foldLogicOfSetCCs(
false, N0, N1,
DL))
8485 if (
const ConstantSDNode *N0O1C =
8487 if (
const ConstantSDNode *N1O1C =
8491 const APInt &LHSMask = N0O1C->getAPIntValue();
8492 const APInt &RHSMask = N1O1C->getAPIntValue();
8526 auto peekThroughResize = [](
SDValue V) {
8528 return V->getOperand(0);
8532 SDValue N0Resized = peekThroughResize(N0);
8534 SDValue N1Resized = peekThroughResize(N1);
8539 if (N00 == N1Resized || N01 == N1Resized)
8546 if (peekThroughResize(NotOperand) == N1Resized)
8554 if (peekThroughResize(NotOperand) == N1Resized)
8575 auto peekThroughZext = [](
SDValue V) {
8577 return V->getOperand(0);
8617 if (S0 &&
S1 && S0->getZExtValue() < BW &&
S1->getZExtValue() < BW &&
8618 S0->getZExtValue() == (BW -
S1->getZExtValue())) {
8635 Lo.getScalarValueSizeInBits() == (BW / 2) &&
8636 Lo.getValueType() ==
Hi.getValueType()) {
8652SDValue DAGCombiner::visitOR(SDNode *
N) {
8673 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
8689 if (BV0 && BV1 && !BV0->getSplatValue() && !BV1->getSplatValue() &&
8691 BV0->getOperand(0).getValueType() ==
8692 BV1->getOperand(0).getValueType()) {
8695 EVT EltVT = BV0->getOperand(0).getValueType();
8696 for (
unsigned I = 0;
I != NumElts; ++
I) {
8702 else if (C0 && C0->
isZero())
8704 else if (C1 && C1->isZero())
8708 else if (C1 && C1->isAllOnes())
8710 else if (BV0->getOperand(
I) == BV1->getOperand(
I))
8715 if (MergedOps.
size() == NumElts)
8729 if ((ZeroN00 != ZeroN01) && (ZeroN10 != ZeroN11)) {
8730 assert((!ZeroN00 || !ZeroN01) &&
"Both inputs zero!");
8731 assert((!ZeroN10 || !ZeroN11) &&
"Both inputs zero!");
8732 bool CanFold =
true;
8734 SmallVector<int, 4>
Mask(NumElts, -1);
8736 for (
int i = 0; i != NumElts; ++i) {
8737 int M0 = SV0->getMaskElt(i);
8738 int M1 = SV1->getMaskElt(i);
8741 bool M0Zero =
M0 < 0 || (ZeroN00 == (
M0 < NumElts));
8742 bool M1Zero =
M1 < 0 || (ZeroN10 == (
M1 < NumElts));
8746 if ((M0Zero &&
M1 < 0) || (M1Zero &&
M0 < 0))
8750 if (M0Zero == M1Zero) {
8755 assert((
M0 >= 0 ||
M1 >= 0) &&
"Undef index!");
8761 Mask[i] = M1Zero ?
M0 % NumElts : (
M1 % NumElts) + NumElts;
8770 return LegalShuffle;
8784 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
8795 if (
SDValue Combined = visitORLike(N0, N1,
DL))
8805 if (
SDValue BSwap = MatchBSwapHWord(
N, N0, N1))
8807 if (
SDValue BSwap = MatchBSwapHWordLow(
N, N0, N1))
8821 auto MatchIntersect = [](ConstantSDNode *C1, ConstantSDNode *C2) {
8841 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
8845 if (
SDValue Rot = MatchRotate(N0, N1,
DL,
false))
8848 if (
SDValue Load = MatchLoadCombine(
N))
8858 if (
SDValue Combined = visitADDLike(
N))
8863 if (LegalOperations || VT.
isVector())
8878 Mask =
Op.getOperand(1);
8879 return Op.getOperand(0);
8922 assert(OppShift && ExtractFrom &&
"Empty SDValue");
8950 bool IsMulOrDiv =
false;
8953 auto SelectOpcode = [&](
unsigned NeededShift,
unsigned MulOrDivVariant) {
8954 IsMulOrDiv = ExtractFrom.
getOpcode() == MulOrDivVariant;
8955 if (!IsMulOrDiv && ExtractFrom.
getOpcode() != NeededShift)
8957 Opcode = NeededShift;
9007 if (Rem != 0 || ResultAmt != OppLHSAmt)
9013 if (OppLHSAmt != ExtractFromAmt - NeededShiftAmt.
zextOrTrunc(
9022 return DAG.
getNode(Opcode,
DL, ResVT, OppShiftLHS, NewShiftNode);
9076 unsigned MaskLoBits = 0;
9078 unsigned Bits =
Log2_64(EltSize);
9080 if (NegBits >= Bits) {
9103 if (PosBits >= MaskLoBits) {
9125 if ((Pos == NegOp1) ||
9149 return Width.
getLoBits(MaskLoBits) == 0;
9150 return Width == EltSize;
9160 SDValue InnerNeg,
bool FromAdd,
9161 bool HasPos,
unsigned PosOpcode,
9162 unsigned NegOpcode,
const SDLoc &
DL) {
9173 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, Shifted,
9174 HasPos ? Pos : Neg);
9187 SDValue InnerNeg,
bool FromAdd,
9188 bool HasPos,
unsigned PosOpcode,
9189 unsigned NegOpcode,
const SDLoc &
DL) {
9202 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, N0, N1,
9203 HasPos ? Pos : Neg);
9248 EVT VT =
LHS.getValueType();
9253 bool HasROTL = hasOperation(
ISD::ROTL, VT);
9254 bool HasROTR = hasOperation(
ISD::ROTR, VT);
9255 bool HasFSHL = hasOperation(
ISD::FSHL, VT);
9256 bool HasFSHR = hasOperation(
ISD::FSHR, VT);
9267 if (LegalOperations && !HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9272 LHS.getOperand(0).getValueType() ==
RHS.getOperand(0).getValueType()) {
9275 MatchRotate(
LHS.getOperand(0),
RHS.getOperand(0),
DL, FromAdd))
9289 if (!LHSShift && !RHSShift)
9304 RHSShift = NewRHSShift;
9309 LHSShift = NewLHSShift;
9312 if (!RHSShift || !LHSShift)
9337 auto MatchRotateSum = [EltSizeInBits](ConstantSDNode *
LHS,
9338 ConstantSDNode *
RHS) {
9339 return (
LHS->getAPIntValue() +
RHS->getAPIntValue()) == EltSizeInBits;
9342 auto ApplyMasks = [&](
SDValue Res) {
9366 bool IsRotate = LHSShiftArg == RHSShiftArg;
9367 if (!IsRotate && !(HasFSHL || HasFSHR)) {
9376 if (CommonOp ==
Or.getOperand(0)) {
9378 Y =
Or.getOperand(1);
9381 if (CommonOp ==
Or.getOperand(1)) {
9383 Y =
Or.getOperand(0);
9390 if (matchOr(LHSShiftArg, RHSShiftArg)) {
9395 }
else if (matchOr(RHSShiftArg, LHSShiftArg)) {
9404 return ApplyMasks(Res);
9417 if (IsRotate && (HasROTL || HasROTR || !(HasFSHL || HasFSHR))) {
9418 bool UseROTL = !LegalOperations || HasROTL;
9420 UseROTL ? LHSShiftAmt : RHSShiftAmt);
9422 bool UseFSHL = !LegalOperations || HasFSHL;
9424 RHSShiftArg, UseFSHL ? LHSShiftAmt : RHSShiftAmt);
9427 return ApplyMasks(Res);
9432 if (!HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9441 SDValue LExtOp0 = LHSShiftAmt;
9442 SDValue RExtOp0 = RHSShiftAmt;
9455 if (IsRotate && (HasROTL || HasROTR)) {
9456 if (
SDValue TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
9457 LExtOp0, RExtOp0, FromAdd, HasROTL,
9461 if (
SDValue TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
9462 RExtOp0, LExtOp0, FromAdd, HasROTR,
9467 if (
SDValue TryL = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt,
9468 RHSShiftAmt, LExtOp0, RExtOp0, FromAdd,
9472 if (
SDValue TryR = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt,
9473 LHSShiftAmt, RExtOp0, LExtOp0, FromAdd,
9523static std::optional<SDByteProvider>
9525 std::optional<uint64_t> VectorIndex,
9526 unsigned StartingIndex = 0) {
9530 return std::nullopt;
9534 if (
Depth && !
Op.hasOneUse() &&
9535 (
Op.getOpcode() !=
ISD::LOAD || !
Op.getValueType().isVector()))
9536 return std::nullopt;
9540 if (
Op.getOpcode() !=
ISD::LOAD && VectorIndex.has_value())
9541 return std::nullopt;
9543 unsigned BitWidth =
Op.getScalarValueSizeInBits();
9545 return std::nullopt;
9547 assert(Index < ByteWidth &&
"invalid index requested");
9550 switch (
Op.getOpcode()) {
9555 return std::nullopt;
9559 return std::nullopt;
9561 if (
LHS->isConstantZero())
9563 if (
RHS->isConstantZero())
9565 return std::nullopt;
9570 return std::nullopt;
9572 uint64_t BitShift = ShiftOp->getZExtValue();
9574 if (BitShift % 8 != 0)
9575 return std::nullopt;
9581 return Index < ByteShift
9584 Depth + 1, VectorIndex, Index);
9591 if (NarrowBitWidth % 8 != 0)
9592 return std::nullopt;
9593 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9595 if (Index >= NarrowByteWidth)
9597 ? std::optional<SDByteProvider>(
9605 Depth + 1, VectorIndex, StartingIndex);
9609 return std::nullopt;
9611 VectorIndex =
OffsetOp->getZExtValue();
9615 if (NarrowBitWidth % 8 != 0)
9616 return std::nullopt;
9617 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9620 if (Index >= NarrowByteWidth)
9621 return std::nullopt;
9629 if (*VectorIndex * NarrowByteWidth > StartingIndex)
9630 return std::nullopt;
9631 if ((*VectorIndex + 1) * NarrowByteWidth <= StartingIndex)
9632 return std::nullopt;
9635 VectorIndex, StartingIndex);
9639 if (!L->isSimple() || L->isIndexed())
9640 return std::nullopt;
9642 unsigned NarrowBitWidth = L->getMemoryVT().getScalarSizeInBits();
9643 if (NarrowBitWidth % 8 != 0)
9644 return std::nullopt;
9645 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9650 if (Index >= NarrowByteWidth)
9652 ? std::optional<SDByteProvider>(
9656 unsigned BPVectorIndex = VectorIndex.value_or(0U);
9661 return std::nullopt;
9676 int64_t FirstOffset) {
9678 unsigned Width = ByteOffsets.
size();
9680 return std::nullopt;
9682 bool BigEndian =
true, LittleEndian =
true;
9683 for (
unsigned i = 0; i < Width; i++) {
9684 int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
9687 if (!BigEndian && !LittleEndian)
9688 return std::nullopt;
9691 assert((BigEndian != LittleEndian) &&
"It should be either big endian or"
9698 switch (
Value.getOpcode()) {
9703 return Value.getOperand(0);
9730SDValue DAGCombiner::mergeTruncStores(StoreSDNode *
N) {
9741 EVT MemVT =
N->getMemoryVT();
9742 if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
9743 !
N->isSimple() ||
N->isIndexed())
9750 unsigned MaxWideNumBits = 64;
9751 unsigned MaxStores = MaxWideNumBits / NarrowNumBits;
9760 if (
Store->getMemoryVT() != MemVT || !
Store->isSimple() ||
9764 Chain =
Store->getChain();
9765 if (MaxStores < Stores.
size())
9769 if (Stores.
size() < 2)
9774 unsigned NumStores = Stores.
size();
9775 unsigned WideNumBits = NumStores * NarrowNumBits;
9776 if (WideNumBits != 16 && WideNumBits != 32 && WideNumBits != 64)
9784 StoreSDNode *FirstStore =
nullptr;
9785 std::optional<BaseIndexOffset>
Base;
9786 for (
auto *Store : Stores) {
9805 if (ShiftAmtC % NarrowNumBits != 0)
9812 Offset = ShiftAmtC / NarrowNumBits;
9818 SourceValue = WideVal;
9819 else if (SourceValue != WideVal) {
9827 SourceValue = WideVal;
9836 int64_t ByteOffsetFromBase = 0;
9839 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9843 if (ByteOffsetFromBase < FirstOffset) {
9845 FirstOffset = ByteOffsetFromBase;
9851 OffsetMap[
Offset] = ByteOffsetFromBase;
9857 assert(FirstStore &&
"First store must be set");
9864 if (!Allowed || !
Fast)
9869 auto checkOffsets = [&](
bool MatchLittleEndian) {
9870 if (MatchLittleEndian) {
9871 for (
unsigned i = 0; i != NumStores; ++i)
9872 if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
9875 for (
unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --
j)
9876 if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
9883 bool NeedBswap =
false;
9884 bool NeedRotate =
false;
9887 if (NarrowNumBits == 8 && checkOffsets(Layout.
isBigEndian()))
9889 else if (NumStores == 2 && checkOffsets(Layout.
isBigEndian()))
9898 "Unexpected store value to merge");
9907 }
else if (NeedRotate) {
9908 assert(WideNumBits % 2 == 0 &&
"Unexpected type for rotate");
9952SDValue DAGCombiner::MatchLoadCombine(SDNode *
N) {
9954 "Can only match load combining against OR nodes");
9957 EVT VT =
N->getValueType(0);
9958 if (VT != MVT::i16 && VT != MVT::i32 && VT != MVT::i64)
9964 assert(
P.hasSrc() &&
"Must be a memory byte provider");
9967 unsigned LoadBitWidth =
Load->getMemoryVT().getScalarSizeInBits();
9969 assert(LoadBitWidth % 8 == 0 &&
9970 "can only analyze providers for individual bytes not bit");
9971 unsigned LoadByteWidth = LoadBitWidth / 8;
9976 std::optional<BaseIndexOffset>
Base;
9979 SmallPtrSet<LoadSDNode *, 8> Loads;
9980 std::optional<SDByteProvider> FirstByteProvider;
9986 unsigned ZeroExtendedBytes = 0;
9987 for (
int i = ByteWidth - 1; i >= 0; --i) {
9994 if (
P->isConstantZero()) {
9997 if (++ZeroExtendedBytes != (ByteWidth -
static_cast<unsigned>(i)))
10001 assert(
P->hasSrc() &&
"provenance should either be memory or zero");
10008 else if (Chain != LChain)
10013 int64_t ByteOffsetFromBase = 0;
10022 if (
L->getMemoryVT().isVector()) {
10023 unsigned LoadWidthInBit =
L->getMemoryVT().getScalarSizeInBits();
10024 if (LoadWidthInBit % 8 != 0)
10026 unsigned ByteOffsetFromVector =
P->SrcOffset * LoadWidthInBit / 8;
10027 Ptr.addToOffset(ByteOffsetFromVector);
10033 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
10037 ByteOffsetFromBase += MemoryByteOffset(*
P);
10038 ByteOffsets[i] = ByteOffsetFromBase;
10041 if (ByteOffsetFromBase < FirstOffset) {
10042 FirstByteProvider =
P;
10043 FirstOffset = ByteOffsetFromBase;
10049 assert(!Loads.
empty() &&
"All the bytes of the value must be loaded from "
10050 "memory, so there must be at least one load which produces the value");
10051 assert(
Base &&
"Base address of the accessed memory location must be set");
10054 bool NeedsZext = ZeroExtendedBytes > 0;
10065 ArrayRef(ByteOffsets).drop_back(ZeroExtendedBytes), FirstOffset);
10069 assert(FirstByteProvider &&
"must be set");
10073 if (MemoryByteOffset(*FirstByteProvider) != 0)
10081 if (LegalOperations &&
10082 !TLI.
isLoadLegal(VT, MemVT, FirstLoad->getAlign(),
10083 FirstLoad->getAddressSpace(),
10092 bool NeedsBswap = IsBigEndianTarget != *IsBigEndian;
10099 if (NeedsBswap && (LegalOperations || NeedsZext) &&
10105 if (NeedsBswap && NeedsZext && LegalOperations &&
10113 *FirstLoad->getMemOperand(), &
Fast);
10114 if (!Allowed || !
Fast)
10119 Chain, FirstLoad->getBasePtr(),
10120 FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
10123 for (LoadSDNode *L : Loads)
10153SDValue DAGCombiner::unfoldMaskedMerge(SDNode *
N) {
10160 EVT VT =
N->getValueType(0);
10182 M =
And.getOperand(XorIdx ? 0 : 1);
10188 if (!matchAndXor(N0, 0, N1) && !matchAndXor(N0, 1, N1) &&
10189 !matchAndXor(N1, 0, N0) && !matchAndXor(N1, 1, N0))
10236SDValue DAGCombiner::visitXOR(SDNode *
N) {
10263 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10275 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10296 if (
SDValue Combined = visitADDLike(
N))
10304 isSetCCEquivalent(N0,
LHS,
RHS, CC,
true) &&
10306 N->use_begin()->getUser()->getOpcode() ==
ISD::AND)) {
10308 LHS.getValueType());
10309 if (!LegalOperations ||
10313 switch (N0Opcode) {
10330 CombineTo(
N, SetCC);
10332 recursivelyDeleteUnusedNodes(N0.
getNode());
10348 AddToWorklist(
V.getNode());
10357 if (isOneUseSetCC(N01) || isOneUseSetCC(N00)) {
10362 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10375 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10385 APInt NotYValue = ~YConst->getAPIntValue();
10401 AddToWorklist(NotX.
getNode());
10406 if (!LegalOperations || hasOperation(
ISD::ABS, VT)) {
10410 SDValue A0 =
A.getOperand(0), A1 =
A.getOperand(1);
10412 if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
10449 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
10460 if (
SDValue MM = unfoldMaskedMerge(
N))
10529 if (!LogicOp.hasOneUse())
10532 unsigned LogicOpcode = LogicOp.getOpcode();
10538 unsigned ShiftOpcode = Shift->
getOpcode();
10541 assert(C1Node &&
"Expected a shift with constant operand");
10544 const APInt *&ShiftAmtVal) {
10545 if (V.getOpcode() != ShiftOpcode || !V.hasOneUse())
10553 ShiftOp = V.getOperand(0);
10558 if (ShiftAmtVal->getBitWidth() != C1Val.
getBitWidth())
10563 bool Overflow =
false;
10564 APInt NewShiftAmt = C1Val.
uadd_ov(*ShiftAmtVal, Overflow);
10569 if (NewShiftAmt.
uge(V.getScalarValueSizeInBits()))
10577 const APInt *C0Val;
10578 if (matchFirstShift(LogicOp.getOperand(0),
X, C0Val))
10579 Y = LogicOp.getOperand(1);
10580 else if (matchFirstShift(LogicOp.getOperand(1),
X, C0Val))
10581 Y = LogicOp.getOperand(0);
10592 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift1, NewShift2,
10602SDValue DAGCombiner::visitShiftByConstant(SDNode *
N) {
10622 switch (
LHS.getOpcode()) {
10646 if (!IsShiftByConstant && !IsCopyOrSelect)
10649 if (IsCopyOrSelect &&
N->hasOneUse())
10654 EVT VT =
N->getValueType(0);
10656 N->getOpcode(),
DL, VT, {LHS.getOperand(1), N->getOperand(1)})) {
10659 return DAG.
getNode(
LHS.getOpcode(),
DL, VT, NewShift, NewRHS);
10665SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *
N) {
10670 EVT TruncVT =
N->getValueType(0);
10671 if (
N->hasOneUse() &&
N->getOperand(0).hasOneUse() &&
10679 AddToWorklist(Trunc00.
getNode());
10680 AddToWorklist(Trunc01.
getNode());
10688SDValue DAGCombiner::visitRotate(SDNode *
N) {
10692 EVT VT =
N->getValueType(0);
10707 bool OutOfRange =
false;
10708 auto MatchOutOfRange = [Bitsize, &OutOfRange](ConstantSDNode *
C) {
10709 OutOfRange |=
C->getAPIntValue().uge(Bitsize);
10717 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, Amt);
10722 if (RotAmtC && RotAmtC->getAPIntValue() == 8 &&
10733 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10734 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, NewOp1);
10746 bool SameSide = (
N->getOpcode() == NextOp);
10753 if (Norm1 && Norm2)
10755 CombineOp, dl, ShiftVT, {Norm1, Norm2})) {
10757 {CombinedShift, BitsizeC});
10759 ISD::UREM, dl, ShiftVT, {CombinedShift, BitsizeC});
10761 CombinedShiftNorm);
10768SDValue DAGCombiner::visitSHL(SDNode *
N) {
10785 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10808 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10818 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10824 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
10825 ConstantSDNode *
RHS) {
10826 APInt c1 =
LHS->getAPIntValue();
10827 APInt c2 =
RHS->getAPIntValue();
10829 return (c1 + c2).uge(OpSizeInBits);
10834 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
10835 ConstantSDNode *
RHS) {
10836 APInt c1 =
LHS->getAPIntValue();
10837 APInt c2 =
RHS->getAPIntValue();
10839 return (c1 + c2).ult(OpSizeInBits);
10861 auto MatchOutOfRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10862 ConstantSDNode *
RHS) {
10863 APInt c1 =
LHS->getAPIntValue();
10864 APInt c2 =
RHS->getAPIntValue();
10866 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10867 (c1 + c2).uge(OpSizeInBits);
10874 auto MatchInRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10875 ConstantSDNode *
RHS) {
10876 APInt c1 =
LHS->getAPIntValue();
10877 APInt c2 =
RHS->getAPIntValue();
10879 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10880 (c1 + c2).ult(OpSizeInBits);
10900 auto MatchEqual = [VT](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
10901 APInt c1 =
LHS->getAPIntValue();
10902 APInt c2 =
RHS->getAPIntValue();
10912 AddToWorklist(NewSHL.
getNode());
10918 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
10919 ConstantSDNode *
RHS) {
10920 const APInt &LHSC =
LHS->getAPIntValue();
10921 const APInt &RHSC =
RHS->getAPIntValue();
10922 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
10994 AddToWorklist(Shl0.
getNode());
11013 {Add.getOperand(1)})) {
11033 if (
SDValue NewSHL = visitShiftByConstant(
N))
11067 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap() &&
11080 APInt NewStep = C0 << ShlVal;
11095 "SRL or SRA node is required here!");
11104 SDValue ShiftOperand =
N->getOperand(0);
11119 if (!IsSignExt && !IsZeroExt)
11126 auto UserOfLowerBits = [NarrowVTSize](
SDNode *U) {
11131 if (!UShiftAmtSrc) {
11135 return UShiftAmt < NarrowVTSize;
11149 if (IsZeroExt && ShiftOperand.
hasOneUse() &&
11152 }
else if (IsSignExt && ShiftOperand.
hasOneUse() &&
11168 "Cannot have a multiply node with two different operand types.");
11179 if (ShiftAmt != NarrowVTSize)
11189 EVT TransformVT = NarrowVT;
11200 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
11207 unsigned Opcode =
N->getOpcode();
11212 EVT VT =
N->getValueType(0);
11231SDValue DAGCombiner::visitSRA(SDNode *
N) {
11253 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11256 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11268 auto SumOfShifts = [&](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
11269 APInt c1 =
LHS->getAPIntValue();
11270 APInt c2 =
RHS->getAPIntValue();
11272 APInt Sum = c1 + c2;
11273 unsigned ShiftSum =
11274 Sum.
uge(OpSizeInBits) ? (OpSizeInBits - 1) : Sum.getZExtValue();
11284 "Expected matchBinaryPredicate to return one element for "
11288 ShiftValue = ShiftValues[0];
11302 APInt Sum = C1 + C2;
11306 return DAG.
getNOT(
DL, NewShift, VT);
11330 if ((ShiftAmt > 0) &&
11340 N->getValueType(0), Trunc);
11357 if (ConstantSDNode *AddC =
11374 DAG.
getConstant(AddC->getAPIntValue().lshr(ShiftAmt).trunc(
11391 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11408 if (LargeShift->getAPIntValue() == TruncBits) {
11426 const APInt &AddVal = AddC->getAPIntValue();
11428 SDNodeFlags ShiftFlags =
N->getFlags();
11432 SDNodeFlags AddFlags = N0->
getFlags();
11447 if (
SDValue NewSRA = visitShiftByConstant(
N))
11456 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11465SDValue DAGCombiner::visitSRL(SDNode *
N) {
11482 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11485 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11496 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
11497 ConstantSDNode *
RHS) {
11498 APInt c1 =
LHS->getAPIntValue();
11499 APInt c2 =
RHS->getAPIntValue();
11501 return (c1 + c2).uge(OpSizeInBits);
11506 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
11507 ConstantSDNode *
RHS) {
11508 APInt c1 =
LHS->getAPIntValue();
11509 APInt c2 =
RHS->getAPIntValue();
11511 return (c1 + c2).ult(OpSizeInBits);
11531 if (c1 + OpSizeInBits == InnerShiftSize) {
11532 if (c1 + c2 >= InnerShiftSize)
11542 c1 + c2 < InnerShiftSize) {
11547 OpSizeInBits - c2),
11564 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
11565 ConstantSDNode *
RHS) {
11566 const APInt &LHSC =
LHS->getAPIntValue();
11567 const APInt &RHSC =
RHS->getAPIntValue();
11568 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
11610 AddToWorklist(SmallShift.
getNode());
11638 APInt UnknownBits = ~Known.Zero;
11639 if (UnknownBits == 0)
return DAG.
getConstant(1, SDLoc(N0), VT);
11654 AddToWorklist(
Op.getNode());
11663 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11693 if (N1C->
getZExtValue() == (NumElts - 1) * EltSizeInBits) {
11696 "Expected BUILD_VECTOR operand as wide as element type");
11712 const APInt &AddVal = AddC->getAPIntValue();
11714 SDNodeFlags ShiftFlags =
N->getFlags();
11718 SDNodeFlags AddFlags = N0->
getFlags();
11730 if (
SDValue NewSRL = visitShiftByConstant(
N))
11734 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11761 if (
N->hasOneUse()) {
11762 SDNode *
User = *
N->user_begin();
11770 AddToWorklist(User);
11786 X.getScalarValueSizeInBits() == HalfBW &&
11787 Y.getScalarValueSizeInBits() == HalfBW) {
11789 (!LegalOperations ||
11795 (!LegalOperations ||
11813SDValue DAGCombiner::visitFunnelShift(SDNode *
N) {
11814 EVT VT =
N->getValueType(0);
11832 return IsFSHL ? N0 : N1;
11834 auto IsUndefOrZero = [](
SDValue V) {
11843 if (Cst->getAPIntValue().uge(
BitWidth)) {
11844 uint64_t RotAmt = Cst->getAPIntValue().urem(
BitWidth);
11845 return DAG.
getNode(
N->getOpcode(),
DL, VT, N0, N1,
11851 return IsFSHL ? N0 : N1;
11857 if (IsUndefOrZero(N0))
11861 if (IsUndefOrZero(N1))
11875 "ShAmt must be in [1, BW-1] for the identity fold to be valid");
11877 unsigned C0Expected = IsFSHL ? ShAmt :
BitWidth - ShAmt;
11878 unsigned C1Expected = IsFSHL ?
BitWidth - ShAmt : ShAmt;
11901 if (
LHS &&
RHS &&
LHS->isSimple() &&
RHS->isSimple() &&
11902 LHS->getAddressSpace() ==
RHS->getAddressSpace() &&
11903 (
LHS->hasNUsesOfValue(1, 0) ||
RHS->hasNUsesOfValue(1, 0)) &&
11912 RHS->getAddressSpace(), NewAlign,
11913 RHS->getMemOperand()->getFlags(), &
Fast) &&
11917 AddToWorklist(NewPtr.
getNode());
11919 VT,
DL,
RHS->getChain(), NewPtr,
11920 RHS->getPointerInfo().getWithOffset(PtrOff), NewAlign,
11921 RHS->getMemOperand()->getFlags(),
RHS->getAAInfo());
11949 if (N0 == N1 && hasOperation(RotOpc, VT))
11950 return DAG.
getNode(RotOpc,
DL, VT, N0, N2);
11959SDValue DAGCombiner::visitSHLSAT(SDNode *
N) {
11994SDValue DAGCombiner::foldABSToABD(SDNode *
N,
const SDLoc &
DL) {
11995 EVT SrcVT =
N->getValueType(0);
11998 N =
N->getOperand(0).getNode();
12000 EVT VT =
N->getValueType(0);
12007 SDValue AbsOp0 =
N->getOperand(0);
12012 auto IsNotMinSignedInt = [VT](ConstantSDNode *
C) {
12015 return !
C->getAPIntValue()
12017 .isMinSignedValue();
12033 auto CreateZextedAbd = [&](
unsigned AbdOpc) {
12042 bool AbsOpWillNSW =
12054 bool AbsOpWillNUW = !IsAdd && DAG.
SignBitIsZero(Op0) && Op1SignBitIsOne;
12056 if (hasOperation(
ISD::ABDU, VT) && AbsOpWillNUW)
12065 assert(!IsAdd &&
"Unexpected abs(add(x,y)) pattern");
12079 EVT MaxVT = VT0.
bitsGT(VT1) ? VT0 : VT1;
12080 if ((VT0 == MaxVT || Op0->
hasOneUse()) &&
12082 (!LegalTypes || hasOperation(ABDOpcode, MaxVT))) {
12092 if (!LegalOperations || hasOperation(ABDOpcode, VT)) {
12100SDValue DAGCombiner::visitABS(SDNode *
N) {
12102 EVT VT =
N->getValueType(0);
12136SDValue DAGCombiner::visitABS_MIN_POISON(SDNode *
N) {
12138 EVT VT =
N->getValueType(0);
12182SDValue DAGCombiner::visitCLMUL(SDNode *
N) {
12183 unsigned Opcode =
N->getOpcode();
12186 EVT VT =
N->getValueType(0);
12196 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
12217SDValue DAGCombiner::visitBSWAP(SDNode *
N) {
12219 EVT VT =
N->getValueType(0);
12244 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
12245 ShAmt->getZExtValue() >= (BW / 2) && (ShAmt->getZExtValue() % 8) == 0 &&
12247 (!LegalOperations || hasOperation(
ISD::BSWAP, HalfVT))) {
12249 if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2)))
12265 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
12266 ShAmt->getZExtValue() % 8 == 0) {
12287 if (BW - (LZ + TZ) == 8) {
12292 if (!LegalOperations || hasOperation(
Opc, VT)) {
12294 SDNodeFlags
Flags =
12304SDValue DAGCombiner::visitBITREVERSE(SDNode *
N) {
12306 EVT VT =
N->getValueType(0);
12340 EVT VT = Src.getValueType();
12350 bool NeedAdd =
true;
12372SDValue DAGCombiner::visitCTLZ(SDNode *
N) {
12374 EVT VT =
N->getValueType(0);
12386 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
12392SDValue DAGCombiner::visitCTLZ_ZERO_POISON(SDNode *
N) {
12394 EVT VT =
N->getValueType(0);
12402 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
12408SDValue DAGCombiner::visitCTTZ(SDNode *
N) {
12410 EVT VT =
N->getValueType(0);
12425SDValue DAGCombiner::visitCTTZ_ZERO_POISON(SDNode *
N) {
12427 EVT VT =
N->getValueType(0);
12437SDValue DAGCombiner::visitCTPOP(SDNode *
N) {
12439 EVT VT =
N->getValueType(0);
12451 const APInt &Amt = AmtC->getAPIntValue();
12452 if (Amt.
ult(NumBits)) {
12486 EVT VT =
LHS.getValueType();
12490 return Flags.hasNoSignedZeros() &&
12492 (Flags.hasNoNaNs() ||
12542SDValue DAGCombiner::foldShiftToAvg(SDNode *
N,
const SDLoc &
DL) {
12543 const unsigned Opcode =
N->getOpcode();
12547 EVT VT =
N->getValueType(0);
12548 bool IsUnsigned = Opcode ==
ISD::SRL;
12555 SDNodeFlags
Flags =
12562 if (hasOperation(FloorISD, VT))
12569SDValue DAGCombiner::foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT) {
12570 unsigned Opc =
N->getOpcode();
12589 if ((
LHS == True &&
RHS == False) || (
LHS == False &&
RHS == True))
12595 True, DAG, LegalOperations, ForCodeSize);
12599 HandleSDNode NegTrueHandle(NegTrue);
12607 if (
LHS == NegTrue) {
12611 RHS, DAG, LegalOperations, ForCodeSize);
12613 HandleSDNode NegRHSHandle(NegRHS);
12614 if (NegRHS == False) {
12616 False, CC, TLI, DAG);
12636 EVT VT =
N->getValueType(0);
12638 VT !=
Cond.getOperand(0).getValueType())
12681SDValue DAGCombiner::foldSelectOfConstants(SDNode *
N) {
12685 EVT VT =
N->getValueType(0);
12686 EVT CondVT =
Cond.getValueType();
12697 if (CondVT != MVT::i1 || LegalOperations) {
12712 if (C1->
isZero() && C2->isOne()) {
12721 if (C1->
isOne() && C2->isZero() && CondVT == VT)
12732 assert(CondVT == MVT::i1 && !LegalOperations);
12735 if (C1->
isOne() && C2->isZero())
12743 if (C1->
isZero() && C2->isOne()) {
12750 if (C1->
isZero() && C2->isAllOnes()) {
12763 const APInt &C1Val = C1->getAPIntValue();
12764 const APInt &C2Val = C2->getAPIntValue();
12767 if (C1Val - 1 == C2Val) {
12773 if (C1Val + 1 == C2Val) {
12793 if (C2->isAllOnes()) {
12805template <
class MatchContextClass>
12809 N->getOpcode() == ISD::VP_SELECT) &&
12810 "Expected a (v)(vp.)select");
12812 SDValue T =
N->getOperand(1),
F =
N->getOperand(2);
12813 EVT VT =
N->getValueType(0);
12815 MatchContextClass matcher(DAG, TLI,
N);
12851 EVT VT =
N->getValueType(0);
12915 EVT VT =
LHS.getValueType();
12917 if (LegalOperations && !hasOperation(ABDOpc, VT))
12935 bool IsTypeLegalOrPromote =
12953 IsTypeLegalOrPromote)
12969 IsTypeLegalOrPromote)
13003SDValue DAGCombiner::visitSELECT(SDNode *
N) {
13007 EVT VT =
N->getValueType(0);
13010 SDNodeFlags
Flags =
N->getFlags();
13022 if (
SDValue V = foldSelectOfConstants(
N))
13026 if (SimplifySelectOps(
N, N1, N2))
13029 if (VT0 == MVT::i1) {
13038 bool normalizeToSequence =
13047 if (normalizeToSequence || !InnerSelect.
use_empty())
13049 InnerSelect, N2, Flags);
13052 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
13059 Cond1, N1, N2, Flags);
13060 if (normalizeToSequence || !InnerSelect.
use_empty())
13062 InnerSelect, Flags);
13065 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
13075 if (!normalizeToSequence) {
13081 if (
SDValue Combined = visitANDLike(N0, N1_0,
N)) {
13094 if (!normalizeToSequence) {
13100 if (
SDValue Combined = visitORLike(N0, N2_0,
DL))
13136 combineMinNumMaxNum(
DL, VT, Cond0, Cond1, N1, N2, CC))
13149 if (
C && NotC &&
C->getAPIntValue() == ~NotC->getAPIntValue()) {
13169 (!LegalOperations &&
13177 if (
SDValue ABD = foldSelectToABD(Cond0, Cond1, N1, N2, CC,
DL))
13180 if (
SDValue NewSel = SimplifySelect(
DL, N0, N1, N2))
13185 if (
SDValue UMin = foldSelectToUMin(Cond0, Cond1, N1, N2, CC,
DL))
13190 if (
SDValue BinOp = foldSelectOfBinops(
N))
13206 EVT VT =
N->getValueType(0);
13214 if (
LHS->getNumOperands() != 2 ||
RHS->getNumOperands() != 2)
13223 for (
int i = 0; i < NumElems / 2; ++i) {
13224 if (
Cond->getOperand(i)->isUndef())
13227 if (BottomHalf ==
nullptr)
13229 else if (
Cond->getOperand(i).getNode() != BottomHalf)
13235 for (
int i = NumElems / 2; i < NumElems; ++i) {
13236 if (
Cond->getOperand(i)->isUndef())
13239 if (TopHalf ==
nullptr)
13241 else if (
Cond->getOperand(i).getNode() != TopHalf)
13245 assert(TopHalf && BottomHalf &&
13246 "One half of the selector was all UNDEFs and the other was all the "
13247 "same value. This should have been addressed before this function.");
13250 BottomHalf->
isZero() ?
RHS->getOperand(0) :
LHS->getOperand(0),
13251 TopHalf->
isZero() ?
RHS->getOperand(1) :
LHS->getOperand(1));
13264 EVT VT = BasePtr.getValueType();
13268 SplatVal.getValueType() == VT) {
13274 if (Index.getOpcode() !=
ISD::ADD)
13301 Index = Index.getOperand(0);
13314 Index = Index.getOperand(0);
13321SDValue DAGCombiner::visitVPSCATTER(SDNode *
N) {
13352SDValue DAGCombiner::visitMSCATTER(SDNode *
N) {
13384SDValue DAGCombiner::visitMSTORE(SDNode *
N) {
13398 MST1->isSimple() && MST1->getBasePtr() == Ptr &&
13401 MST1->getMemoryVT().getStoreSize()) ||
13405 CombineTo(MST1, MST1->getChain());
13422 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13426 Value.getValueType().isInteger() &&
13429 APInt TruncDemandedBits =
13456 Value.getOperand(0).getValueType());
13466SDValue DAGCombiner::visitVP_STRIDED_STORE(SDNode *
N) {
13471 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13472 return DAG.
getStoreVP(SST->getChain(), SDLoc(
N), SST->getValue(),
13473 SST->getBasePtr(), SST->getOffset(), SST->getMask(),
13474 SST->getVectorLength(), SST->getMemoryVT(),
13475 SST->getMemOperand(), SST->getAddressingMode(),
13476 SST->isTruncatingStore(), SST->isCompressingStore());
13481SDValue DAGCombiner::visitVECTOR_COMPRESS(SDNode *
N) {
13485 SDValue Passthru =
N->getOperand(2);
13488 bool HasPassthru = !Passthru.
isUndef();
13501 unsigned NumSelected = 0;
13503 for (
unsigned I = 0;
I < NumElmts; ++
I) {
13512 Ops.push_back(VecI);
13516 for (
unsigned Rest = NumSelected; Rest < NumElmts; ++Rest) {
13522 Ops.push_back(Val);
13530SDValue DAGCombiner::visitVPGATHER(SDNode *
N) {
13558SDValue DAGCombiner::visitMGATHER(SDNode *
N) {
13571 return CombineTo(
N, PassThru, MGT->
getChain());
13590SDValue DAGCombiner::visitMLOAD(SDNode *
N) {
13606 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13610 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13616SDValue DAGCombiner::visitMHISTOGRAM(SDNode *
N) {
13626 EVT DataVT =
Index.getValueType();
13644SDValue DAGCombiner::visitPARTIAL_REDUCE_MLA(SDNode *
N) {
13645 if (
SDValue Res = foldPartialReduceMLAMulOp(
N))
13647 if (
SDValue Res = foldPartialReduceAdd(
N))
13663SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *
N) {
13682 bool IsMLS =
false;
13712 RHS.getValueType().getScalarType()));
13720 auto IsIntOrFPExtOpcode = [](
unsigned int Opcode) {
13724 unsigned LHSOpcode =
LHS->getOpcode();
13725 if (!IsIntOrFPExtOpcode(LHSOpcode))
13736 EVT OpVT =
Op.getValueType();
13747 EVT AccVT = Acc.getValueType();
13758 unsigned LHSBits =
LHS.getValueType().getScalarSizeInBits();
13775 ApplyPredicate(
C, LHSExtOp);
13776 return GetMLA(NewOpcode, Acc, LHSExtOp,
C);
13779 unsigned RHSOpcode =
RHS->getOpcode();
13780 if (!IsIntOrFPExtOpcode(RHSOpcode))
13805 EVT AccElemVT = Acc.getValueType().getVectorElementType();
13807 NewOpc !=
N->getOpcode())
13817 ApplyPredicate(RHSExtOp, LHSExtOp);
13818 return GetMLA(NewOpc, Acc, LHSExtOp, RHSExtOp);
13828SDValue DAGCombiner::foldPartialReduceAdd(SDNode *
N) {
13848 bool IsMLS =
false;
13862 if (Op1IsSigned != NodeIsSigned &&
13891 : DAG.
getNode(NewOpcode,
DL, AccVT, Acc, UnextOp1, Constant);
13894SDValue DAGCombiner::visitVP_STRIDED_LOAD(SDNode *
N) {
13899 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13901 SLD->getAddressingMode(), SLD->getExtensionType(), SLD->getValueType(0),
13902 SDLoc(
N), SLD->getChain(), SLD->getBasePtr(), SLD->getOffset(),
13903 SLD->getMask(), SLD->getVectorLength(), SLD->getMemoryVT(),
13904 SLD->getMemOperand(), SLD->isExpandingLoad());
13905 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13912SDValue DAGCombiner::foldVSelectOfConstants(SDNode *
N) {
13916 EVT VT =
N->getValueType(0);
13917 if (!
Cond.hasOneUse() ||
Cond.getScalarValueSizeInBits() != 1 ||
13926 bool AllAddOne =
true;
13927 bool AllSubOne =
true;
13929 for (
unsigned i = 0; i != Elts; ++i) {
13952 if (AllAddOne || AllSubOne) {
13979SDValue DAGCombiner::visitVP_SELECT(SDNode *
N) {
14003 EVT CondVT =
Cond.getValueType();
14004 assert(CondVT.
isVector() &&
"Vector select expects a vector selector!");
14012 if (!IsTAllZero && !IsTAllOne && !IsFAllZero && !IsFAllOne)
14016 if (IsTAllZero && IsFAllZero) {
14025 Cond.getOperand(0).getValueType() == VT && VT.
isSimple() &&
14027 TValAPInt.
isOne() &&
14051 if (!IsTAllOne && !IsFAllZero &&
Cond.hasOneUse() &&
14055 if (IsTAllZero || IsFAllOne) {
14068 "Select condition no longer all-sign bits");
14071 if (IsTAllOne && IsFAllZero)
14100SDValue DAGCombiner::visitVSELECT(SDNode *
N) {
14104 EVT VT =
N->getValueType(0);
14137 bool isAbs =
false;
14156 AddToWorklist(Shift.
getNode());
14157 AddToWorklist(
Add.getNode());
14169 if (
SDValue FMinMax = combineMinNumMaxNum(
DL, VT,
LHS,
RHS, N1, N2, CC))
14184 EVT NarrowVT =
LHS.getValueType();
14192 SetCCWidth < WideWidth &&
14208 DAG.
getSetCC(
DL, WideSetCCVT, WideLHS, WideRHS, CC);
14244 (OpLHS == CondLHS || OpRHS == CondLHS))
14247 if (OpRHS.getOpcode() == CondRHS.getOpcode() &&
14250 CondLHS == OpLHS) {
14254 auto MatchUADDSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
14255 return Cond->getAPIntValue() == ~Op->getAPIntValue();
14296 if (OpLHS ==
LHS) {
14311 auto MatchUSUBSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
14312 return (!
Op && !
Cond) ||
14314 Cond->getAPIntValue() == (-
Op->getAPIntValue() - 1));
14350 if (SimplifySelectOps(
N, N1, N2))
14370 if (
SDValue V = foldVSelectOfConstants(
N))
14386SDValue DAGCombiner::visitSELECT_CC(SDNode *
N) {
14407 AddToWorklist(
SCC.getNode());
14412 return SCCC->isZero() ? N3 : N2;
14416 if (
SCC->isUndef())
14422 SCC.getOperand(0),
SCC.getOperand(1), N2, N3,
14423 SCC.getOperand(2),
SCC->getFlags());
14428 if (SimplifySelectOps(
N, N2, N3))
14432 return SimplifySelectCC(
DL, N0, N1, N2, N3, CC);
14435SDValue DAGCombiner::visitSETCC(SDNode *
N) {
14444 EVT VT =
N->getValueType(0);
14451 if (PreferSetCC && Combined.getOpcode() !=
ISD::SETCC) {
14452 SDValue NewSetCC = rebuildSetCC(Combined);
14480 A.getOperand(0) ==
B.getOperand(0);
14484 B.getOperand(0) ==
A;
14487 bool IsRotate =
false;
14490 if (IsAndWithShift(N0, N1)) {
14492 ShiftOrRotate = N1;
14493 }
else if (IsAndWithShift(N1, N0)) {
14495 ShiftOrRotate = N0;
14496 }
else if (IsRotateWithOp(N0, N1)) {
14499 ShiftOrRotate = N1;
14500 }
else if (IsRotateWithOp(N1, N0)) {
14503 ShiftOrRotate = N0;
14506 if (AndOrOp && ShiftOrRotate && ShiftOrRotate.hasOneUse() &&
14511 auto GetAPIntValue = [](
SDValue Op) -> std::optional<APInt> {
14514 if (CNode ==
nullptr)
14515 return std::nullopt;
14518 std::optional<APInt> AndCMask =
14519 IsRotate ? std::nullopt : GetAPIntValue(AndOrOp.
getOperand(1));
14520 std::optional<APInt> ShiftCAmt =
14521 GetAPIntValue(ShiftOrRotate.getOperand(1));
14525 if (ShiftCAmt && (IsRotate || AndCMask) && ShiftCAmt->ult(NumBits)) {
14526 unsigned ShiftOpc = ShiftOrRotate.getOpcode();
14528 bool CanTransform = IsRotate;
14529 if (!CanTransform) {
14531 CanTransform = *ShiftCAmt == (~*AndCMask).
popcount();
14533 CanTransform &= (*ShiftCAmt + AndCMask->popcount()) == NumBits;
14541 OpVT, ShiftOpc, ShiftCAmt->isPowerOf2(), *ShiftCAmt, AndCMask);
14543 if (CanTransform && NewShiftOpc != ShiftOpc) {
14545 DAG.
getNode(NewShiftOpc,
DL, OpVT, ShiftOrRotate.getOperand(0),
14546 ShiftOrRotate.getOperand(1));
14553 NumBits - ShiftCAmt->getZExtValue())
14554 : APInt::getLowBitsSet(NumBits,
14555 NumBits - ShiftCAmt->getZExtValue());
14563 return DAG.
getSetCC(
DL, VT, NewAndOrOp, NewShiftOrRotate,
Cond);
14571SDValue DAGCombiner::visitSETCCCARRY(SDNode *
N) {
14592 if (!
N.hasOneUse())
14621 unsigned Opcode =
N->getOpcode();
14623 EVT VT =
N->getValueType(0);
14626 "Expected EXTEND dag node in input!");
14668 unsigned Opcode =
N->getOpcode();
14670 EVT VT =
N->getValueType(0);
14673 "Expected EXTEND dag node in input!");
14679 return DAG.
getNode(Opcode,
DL, VT, N0);
14698 unsigned FoldOpc = Opcode;
14721 for (
unsigned i = 0; i != NumElts; ++i) {
14723 if (
Op.isUndef()) {
14734 APInt C =
Op->getAsAPIntVal().zextOrTrunc(EVTBits);
14752 bool HasCopyToRegUses =
false;
14767 for (
unsigned i = 0; i != 2; ++i) {
14785 HasCopyToRegUses =
true;
14788 if (HasCopyToRegUses) {
14789 bool BothLiveOut =
false;
14792 BothLiveOut =
true;
14799 return !ExtendNodes.
empty();
14804void DAGCombiner::ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
14809 for (SDNode *SetCC : SetCCs) {
14812 for (
unsigned j = 0;
j != 2; ++
j) {
14813 SDValue SOp = SetCC->getOperand(j);
14814 if (SOp == OrigLoad)
14815 Ops.push_back(ExtLoad);
14820 Ops.push_back(SetCC->getOperand(2));
14826SDValue DAGCombiner::CombineExtLoad(SDNode *
N) {
14828 EVT DstVT =
N->getValueType(0);
14833 "Unexpected node type (not an extend)!");
14871 EVT SplitSrcVT = SrcVT;
14872 EVT SplitDstVT = DstVT;
14887 const unsigned NumSplits =
14894 for (
unsigned Idx = 0; Idx < NumSplits; Idx++) {
14895 const unsigned Offset = Idx * Stride;
14913 AddToWorklist(NewChain.
getNode());
14915 CombineTo(
N, NewValue);
14921 ExtendSetCCUses(SetCCs, N0, NewValue, (
ISD::NodeType)
N->getOpcode());
14922 CombineTo(N0.
getNode(), Trunc, NewChain);
14928SDValue DAGCombiner::CombineZExtLogicopShiftLoad(SDNode *
N) {
14930 EVT VT =
N->getValueType(0);
14931 EVT OrigVT =
N->getOperand(0).getValueType();
14953 EVT MemVT =
Load->getMemoryVT();
14975 Load->getChain(),
Load->getBasePtr(),
14976 Load->getMemoryVT(),
Load->getMemOperand());
14989 if (
SDValue(Load, 0).hasOneUse()) {
14993 Load->getValueType(0), ExtLoad);
14994 CombineTo(Load, Trunc, ExtLoad.
getValue(1));
14998 recursivelyDeleteUnusedNodes(N0.
getNode());
15007SDValue DAGCombiner::matchVSelectOpSizesWithSetCC(SDNode *Cast) {
15008 unsigned CastOpcode = Cast->
getOpcode();
15012 "Unexpected opcode for vector select narrowing/widening");
15052 bool LegalOperations,
SDNode *
N,
15066 EVT MemVT = OldExtLoad->getMemoryVT();
15067 if ((LegalOperations || !OldExtLoad->isSimple() || VT.
isVector()) &&
15068 !TLI.
isLoadLegal(VT, MemVT, OldExtLoad->getAlign(),
15069 OldExtLoad->getAddressSpace(), ExtLoadType,
false))
15074 OldExtLoad->getBasePtr(), MemVT,
15075 OldExtLoad->getMemOperand());
15082 DAG.
getValueType(OldExtLoad->getValueType(0).getScalarType()));
15100 bool NonNegZExt =
false) {
15107 (Frozen && !Load->hasNUsesOfValue(1, 0)))
15113 "Unexpected load type or opcode");
15130 !TLI.
isLoadLegal(VT, Load->getValueType(0), Load->getAlign(),
15131 Load->getAddressSpace(), ExtLoadType,
false))
15134 bool DoXform =
true;
15138 ExtOpc, SetCCs, TLI);
15147 unsigned OldBits,
unsigned NewBits,
15152 bool IsVariadic = Dbg->isVariadic();
15155 for (
unsigned I = 0,
E = Locs.
size();
I !=
E; ++
I) {
15160 if (
Op.getSDNode() == Old.getNode() &&
Op.getResNo() == Old.getResNo()) {
15184 for (
unsigned ArgNo : AffectedArgs)
15191 Dbg->getAdditionalDependencies(), Dbg->isIndirect(), Dbg->getDebugLoc(),
15192 Dbg->getOrder(), Dbg->isVariadic());
15194 Dbg->setIsInvalidated();
15195 Dbg->setIsEmitted();
15203 auto SalvageToOldLoadSize = [&](
SDValue Old,
SDValue New,
bool IsSigned) {
15208 unsigned VarBitsOld = Old.getValueSizeInBits();
15209 unsigned VarBitsNew = New.getValueSizeInBits();
15212 if (Dbg->isInvalidated())
15215 SalvageDbgValue(Dbg, Old, New, VarBitsOld, VarBitsNew, IsSigned);
15220 DAG.
getExtLoad(ExtLoadType,
DL, VT, Load->getChain(), Load->getBasePtr(),
15221 Load->getValueType(0), Load->getMemOperand());
15228 DAG.
getValueType(Load->getValueType(0).getScalarType()));
15230 Combiner.ExtendSetCCUses(SetCCs, N0, Res, ExtOpc);
15233 if (
N->getHasDebugValue()) {
15237 if (NoReplaceTrunc) {
15239 if (Load->getHasDebugValue()) {
15241 SalvageToOldLoadSize(OldLoadVal, ExtLoad, IsSigned);
15296 EVT MemoryVT = ALoad->getMemoryVT();
15297 if (!TLI.
isLoadLegal(VT, MemoryVT, ALoad->getAlign(),
15298 ALoad->getAddressSpace(), ExtLoadType,
true))
15306 EVT OrigVT = ALoad->getValueType(0);
15309 ExtLoadType,
SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
15310 ALoad->getBasePtr(), ALoad->getMemOperand()));
15320 bool LegalOperations) {
15332 EVT VT =
N->getValueType(0);
15333 EVT XVT =
X.getValueType();
15349 return DAG.
getNode(ShiftOpcode,
DL, VT, NotX, ShiftAmount);
15355SDValue DAGCombiner::foldSextSetcc(SDNode *
N) {
15363 EVT VT =
N->getValueType(0);
15373 if (VT.
isVector() && !LegalOperations &&
15386 return DAG.
getSetCC(
DL, VT, N00, N01, CC, {},
15393 if (SVT == MatchingVecType) {
15410 auto IsFreeToExtend = [&](
SDValue V) {
15429 for (SDUse &Use :
V->uses()) {
15431 SDNode *
User =
Use.getUser();
15432 if (
Use.getResNo() != 0 || User == N0.
getNode())
15437 if (
User->getOpcode() != ExtOpcode ||
User->getValueType(0) != VT)
15443 if (IsFreeToExtend(N00) && IsFreeToExtend(N01)) {
15446 return DAG.
getSetCC(
DL, VT, Ext0, Ext1, CC, {},
15464 SDValue ExtTrueVal = (SetCCWidth == 1)
15468 if (
SDValue SCC = SimplifySelectCC(
DL, N00, N01, ExtTrueVal, Zero, CC,
true))
15481 return DAG.
getSelect(
DL, VT, SetCC, ExtTrueVal, Zero, Flags);
15488SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *
N) {
15490 EVT VT =
N->getValueType(0);
15494 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15540 if (NarrowLoad.getNode() != N0.
getNode()) {
15541 CombineTo(N0.
getNode(), NarrowLoad);
15543 AddToWorklist(oye);
15551 unsigned OpBits =
Op.getScalarValueSizeInBits();
15557 if (OpBits == DestBits) {
15563 if (OpBits < DestBits) {
15572 Flags.setNoSignedWrap(
true);
15580 if (OpBits < DestBits)
15582 else if (OpBits > DestBits)
15602 if (
SDValue ExtLoad = CombineExtLoad(
N))
15638 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15639 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15642 if (NoReplaceTruncAnd) {
15645 CombineTo(N0.
getNode(), TruncAnd);
15647 if (NoReplaceTrunc) {
15652 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
15671 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15702 if (NewXor.getNode() == N0.
getNode()) {
15728 "Expected extend op");
15773SDValue DAGCombiner::visitZERO_EXTEND(SDNode *
N) {
15775 EVT VT =
N->getValueType(0);
15779 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15810 APInt TruncatedBits =
15812 APInt(
Op.getScalarValueSizeInBits(), 0) :
15813 APInt::getBitsSet(
Op.getScalarValueSizeInBits(),
15814 N0.getScalarValueSizeInBits(),
15815 std::
min(
Op.getScalarValueSizeInBits(),
15818 SDValue ZExtOrTrunc = DAG.getZExtOrTrunc(Op, DL, VT);
15819 DAG.salvageDebugInfo(*N0.getNode());
15821 return ZExtOrTrunc;
15831 if (NarrowLoad.getNode() != N0.
getNode()) {
15832 CombineTo(N0.
getNode(), NarrowLoad);
15834 AddToWorklist(oye);
15842 if (
N->getFlags().hasNonNeg()) {
15850 if (OpBits == DestBits) {
15856 if (OpBits < DestBits) {
15866 Flags.setNoSignedWrap(
true);
15867 Flags.setNoUnsignedWrap(
true);
15879 AddToWorklist(
Op.getNode());
15883 return ZExtOrTrunc;
15889 AddToWorklist(
Op.getNode());
15915 EVT SrcVT = Src.getValueType();
15944 if (
SDValue ExtLoad = CombineExtLoad(
N))
15965 bool DoXform =
true;
15972 if (isAndLoadExtLoad(AndC, LN00, LoadResultTy, ExtVT))
15988 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15989 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15992 if (NoReplaceTruncAnd) {
15995 CombineTo(N0.
getNode(), TruncAnd);
15997 if (NoReplaceTrunc) {
16002 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
16011 if (
SDValue ZExtLoad = CombineZExtLogicopShiftLoad(
N))
16024 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
16027 if (!LegalOperations && VT.
isVector() &&
16059 if (
SDValue SCC = SimplifySelectCC(
16079 if (ShAmtC->getAPIntValue().ugt(KnownZeroBits)) {
16100 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
16122SDValue DAGCombiner::visitANY_EXTEND(SDNode *
N) {
16124 EVT VT =
N->getValueType(0);
16158 if (NarrowLoad.getNode() != N0.
getNode()) {
16159 CombineTo(N0.
getNode(), NarrowLoad);
16161 AddToWorklist(oye);
16187 EVT SrcVT = Src.getValueType();
16218 bool DoXform =
true;
16230 CombineTo(
N, ExtLoad);
16231 if (NoReplaceTrunc) {
16233 recursivelyDeleteUnusedNodes(LN0);
16237 CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
16252 if (!LegalOperations ||
16258 CombineTo(
N, ExtLoad);
16260 recursivelyDeleteUnusedNodes(LN0);
16268 SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
16275 if (VT.
isVector() && !LegalOperations) {
16302 if (
SDValue SCC = SimplifySelectCC(
16318SDValue DAGCombiner::visitAssertExt(SDNode *
N) {
16319 unsigned Opcode =
N->getOpcode();
16343 EVT MinAssertVT = AssertVT.
bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
16358 if (AssertVT.
bitsLT(BigA_AssertVT)) {
16376 if (AssertVT.
bitsLT(BigA_AssertVT) &&
16396SDValue DAGCombiner::visitAssertAlign(SDNode *
N) {
16406 std::max(AL, AAN->getAlign()));
16417 unsigned AlignShift =
Log2(AL);
16422 if (LHSAlignShift >= AlignShift || RHSAlignShift >= AlignShift) {
16423 if (LHSAlignShift < AlignShift)
16425 if (RHSAlignShift < AlignShift)
16436SDValue DAGCombiner::visitIS_FPCLASS(SDNode *
N) {
16439 EVT VT =
N->getValueType(0);
16468SDValue DAGCombiner::reduceLoadWidth(SDNode *
N) {
16469 unsigned Opc =
N->getOpcode();
16473 EVT VT =
N->getValueType(0);
16483 unsigned ShAmt = 0;
16488 unsigned ShiftedOffset = 0;
16508 uint64_t MemoryWidth = LN->getMemoryVT().getScalarSizeInBits();
16509 if (MemoryWidth <= ShAmt)
16520 LN->getExtensionType() != ExtType)
16529 unsigned ActiveBits = 0;
16530 if (
Mask.isMask()) {
16531 ActiveBits =
Mask.countr_one();
16532 }
else if (
Mask.isShiftedMask(ShAmt, ActiveBits)) {
16533 ShiftedOffset = ShAmt;
16554 if (!
SRL.hasOneUse())
16567 ShAmt = SRL1C->getZExtValue();
16568 uint64_t MemoryWidth = LN->getMemoryVT().getSizeInBits();
16569 if (ShAmt >= MemoryWidth)
16594 SDNode *
Mask = *(
SRL->user_begin());
16597 unsigned Offset, ActiveBits;
16598 const APInt& ShiftMask =
Mask->getConstantOperandAPInt(1);
16599 if (ShiftMask.
isMask()) {
16605 LN->getAddressSpace(), ExtType,
false))
16615 LN->getAddressSpace(), ExtType,
false)) {
16623 N0 =
SRL.getOperand(0);
16631 unsigned ShLeftAmt = 0;
16635 ShLeftAmt = N01->getZExtValue();
16656 !isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
16662 if (FreezeNode && !FreezeNode.
hasOneUse() &&
16668 auto AdjustBigEndianShift = [&](
unsigned ShAmt) {
16669 unsigned LVTStoreBits =
16672 return LVTStoreBits - EVTStoreBits - ShAmt;
16677 unsigned PtrAdjustmentInBits =
16680 uint64_t PtrOff = PtrAdjustmentInBits / 8;
16686 AddToWorklist(NewPtr.
getNode());
16690 const MDNode *OldRanges = LN0->
getRanges();
16691 const MDNode *NewRanges =
nullptr;
16695 if (ShAmt == 0 && OldRanges) {
16703 ConstantRange TruncatedCR = CR.
truncate(BitSize);
16713 NewRanges = OldRanges;
16726 WorklistRemover DeadNodes(*
this);
16730 if (FreezeNode && !FreezeNode.
hasOneUse())
16747 if (ShLeftAmt != 0) {
16759 if (ShiftedOffset != 0) {
16773SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *
N) {
16776 EVT VT =
N->getValueType(0);
16807 if ((N00Bits <= ExtVTBits ||
16820 if ((N00Bits == ExtVTBits ||
16821 (!IsZext && (N00Bits < ExtVTBits ||
16823 (!LegalOperations ||
16848 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
16856 if (ShAmt->getAPIntValue().ule(VTBits - ExtVTBits)) {
16860 if (((VTBits - ExtVTBits) - ShAmt->getZExtValue()) < InSignBits)
16879 CombineTo(
N, ExtLoad);
16881 AddToWorklist(ExtLoad.
getNode());
16891 ((!LegalOperations && LN0->
isSimple()) &&
16897 CombineTo(
N, ExtLoad);
16913 Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->
getMemOperand(),
16915 CombineTo(
N, Frozen ? N0 : ExtMaskedLoad);
16916 CombineTo(Ld, ExtMaskedLoad, ExtMaskedLoad.
getValue(1));
16923 if (
SDValue(GN0, 0).hasOneUse() && ExtVT == GN0->getMemoryVT() &&
16925 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
16926 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
16929 DAG.
getVTList(VT, MVT::Other), ExtVT,
DL,
Ops, GN0->getMemOperand(),
16932 CombineTo(
N, ExtLoad);
16934 AddToWorklist(ExtLoad.
getNode());
16957 (!LegalOperations ||
16971 bool LegalOperations) {
16972 unsigned InregOpcode =
N->getOpcode();
16976 EVT VT =
N->getValueType(0);
16978 *DAG.
getContext(), Src.getValueType().getVectorElementType());
16981 "Expected EXTEND_VECTOR_INREG dag node in input!");
16990 Src = Src.getOperand(0);
16991 if (Src.getValueType() != SrcVT)
16997 return DAG.
getNode(Opcode,
DL, VT, Src);
17000SDValue DAGCombiner::visitEXTEND_VECTOR_INREG(SDNode *
N) {
17002 EVT VT =
N->getValueType(0);
17026SDValue DAGCombiner::visitTRUNCATE_USAT_U(SDNode *
N) {
17027 EVT VT =
N->getValueType(0);
17048 unsigned NumSrcBits = In.getScalarValueSizeInBits();
17050 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
17071 unsigned NumSrcBits = In.getScalarValueSizeInBits();
17073 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
17094 unsigned NumSrcBits = In.getScalarValueSizeInBits();
17096 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
17119 auto AllowedTruncateSat = [&](
unsigned Opc,
EVT SrcVT,
EVT VT) ->
bool {
17131 }
else if (Src.getOpcode() ==
ISD::UMIN) {
17143SDValue DAGCombiner::visitTRUNCATE(SDNode *
N) {
17145 EVT VT =
N->getValueType(0);
17160 return SaturatedTR;
17212 if (LegalTypes && !LegalOperations && VT.
isScalarInteger() && VT != MVT::i1 &&
17214 EVT TrTy =
N->getValueType(0);
17219 if (Src.getOpcode() ==
ISD::SRL && Src.getOperand(0)->hasOneUse()) {
17222 Src = Src.getOperand(0);
17229 EVT VecTy = Src.getOperand(0).getValueType();
17230 EVT ExTy = Src.getValueType();
17234 auto NewEltCnt = EltCnt * SizeRatio;
17239 SDValue EltNo = Src->getOperand(1);
17242 int Index = isLE ? (Elt * SizeRatio + EltOffset)
17243 : (Elt * SizeRatio + (SizeRatio - 1) - EltOffset);
17254 if (!LegalOperations ||
17277 AddToWorklist(Amt.
getNode());
17327 if (BuildVectEltTy == TruncVecEltTy) {
17331 unsigned TruncEltOffset = BuildVecNumElts / TruncVecNumElts;
17332 unsigned FirstElt = isLE ? 0 : (TruncEltOffset - 1);
17334 assert((BuildVecNumElts % TruncVecNumElts) == 0 &&
17335 "Invalid number of elements");
17338 for (
unsigned i = FirstElt, e = BuildVecNumElts; i <
e;
17339 i += TruncEltOffset)
17349 if (
SDValue Reduced = reduceLoadWidth(
N))
17372 unsigned NumDefs = 0;
17376 if (!
X.isUndef()) {
17393 if (NumDefs == 1) {
17394 assert(
V.getNode() &&
"The single defined operand is empty!");
17396 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
17402 AddToWorklist(
NV.getNode());
17417 (!LegalOperations ||
17445 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
17459 if (!LegalOperations && N0.
hasOneUse() &&
17476 Flags.setNoUnsignedWrap(
true);
17501 if (!LegalOperations && N0.
hasOneUse() &&
17542 if (!LegalOperations && N0.
hasOneUse() &&
17550 bool CanFold =
false;
17558 unsigned NeededBits = SrcBits - TruncBits;
17584SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *
N, EVT VT) {
17597 !LD1->hasOneUse() || !LD2->hasOneUse() ||
17598 LD1->getAddressSpace() != LD2->getAddressSpace())
17601 unsigned LD1Fast = 0;
17602 EVT LD1VT = LD1->getValueType(0);
17607 *LD1->getMemOperand(), &LD1Fast) && LD1Fast)
17608 return DAG.
getLoad(VT, SDLoc(
N), LD1->getChain(), LD1->getBasePtr(),
17609 LD1->getPointerInfo(), LD1->getAlign());
17620SDValue DAGCombiner::foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
17624 EVT VT =
N->getValueType(0);
17661 auto IsBitCastOrFree = [&TLI, FPOpcode](
SDValue Op, EVT VT) {
17675 IsBitCastOrFree(LogicOp0, VT)) {
17678 NumFPLogicOpsConv++;
17687SDValue DAGCombiner::visitBITCAST(SDNode *
N) {
17689 EVT VT =
N->getValueType(0);
17714 if (!LegalOperations ||
17720 if (
C.getNode() !=
N)
17733 auto IsFreeBitcast = [VT](
SDValue V) {
17735 V.getOperand(0).getValueType() == VT) ||
17748 auto CastLoad = [
this, &VT](
SDValue N0,
const SDLoc &
DL) {
17770 if ((LegalOperations || !LN0->
isSimple()) &&
17780 if (
const MDNode *MD = LN0->
getRanges()) {
17792 if (
SDValue NewLd = CastLoad(N0, SDLoc(
N)))
17799 if (
SDValue V = foldBitcastedFPLogic(
N, DAG, TLI))
17819 AddToWorklist(NewConv.
getNode());
17822 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17829 AddToWorklist(FlipBit.
getNode());
17836 AddToWorklist(
Hi.getNode());
17838 AddToWorklist(FlipBit.
getNode());
17842 AddToWorklist(FlipBits.
getNode());
17872 AddToWorklist(
X.getNode());
17876 if (OrigXWidth < VTWidth) {
17878 AddToWorklist(
X.getNode());
17879 }
else if (OrigXWidth > VTWidth) {
17884 X.getValueType(),
X,
17886 X.getValueType()));
17887 AddToWorklist(
X.getNode());
17889 AddToWorklist(
X.getNode());
17892 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17895 AddToWorklist(Cst.
getNode());
17897 AddToWorklist(
X.getNode());
17899 AddToWorklist(XorResult.
getNode());
17903 SDLoc(XorResult)));
17904 AddToWorklist(XorResult64.
getNode());
17907 DAG.
getConstant(SignBit, SDLoc(XorResult64), MVT::i64));
17908 AddToWorklist(FlipBit.
getNode());
17911 AddToWorklist(FlipBits.
getNode());
17917 AddToWorklist(
X.getNode());
17922 AddToWorklist(Cst.
getNode());
17930 if (
SDValue CombineLD = CombineConsecutiveLoads(N0.
getNode(), VT))
17953 auto PeekThroughBitcast = [&](
SDValue Op) {
17955 Op.getOperand(0).getValueType() == VT)
17972 SmallVector<int, 8> NewMask;
17974 for (
int i = 0; i != MaskScale; ++i)
17975 NewMask.
push_back(M < 0 ? -1 : M * MaskScale + i);
17980 return LegalShuffle;
17986SDValue DAGCombiner::visitBUILD_PAIR(SDNode *
N) {
17987 EVT VT =
N->getValueType(0);
17988 return CombineConsecutiveLoads(
N, VT);
17991SDValue DAGCombiner::visitFREEZE(SDNode *
N) {
18002 while (!
N->use_empty())
18007 assert(
N->getOperand(0) == FrozenN0 &&
"Expected cycle in DAG");
18037 bool AllowMultipleMaybePoisonOperands =
18065 SmallSet<SDValue, 8> MaybePoisonOperands;
18066 SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
18071 bool HadMaybePoisonOperands = !MaybePoisonOperands.
empty();
18072 bool IsNewMaybePoisonOperand = MaybePoisonOperands.
insert(
Op).second;
18073 if (IsNewMaybePoisonOperand)
18074 MaybePoisonOperandNumbers.
push_back(OpNo);
18075 if (!HadMaybePoisonOperands)
18077 if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
18086 for (
unsigned OpNo : MaybePoisonOperandNumbers) {
18097 SDValue MaybePoisonOperand =
N->getOperand(0).getOperand(OpNo);
18099 if (MaybePoisonOperand.
isUndef())
18106 FrozenMaybePoisonOperand.
getOperand(0) == FrozenMaybePoisonOperand) {
18110 MaybePoisonOperand);
18146 SDNodeFlags SrcFlags = N0->
getFlags();
18147 SDNodeFlags SafeFlags;
18161 N->getFlags().hasAllowContract();
18165SDValue DAGCombiner::visitFADDForFMACombine(SDNode *
N) {
18168 EVT VT =
N->getValueType(0);
18173 bool HasFMAD = (LegalOperations && TLI.
isFMADLegal(DAG,
N));
18181 if (!HasFMAD && !HasFMA)
18184 bool AllowFusionGlobally =
18187 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
18205 unsigned Opcode =
N.getOpcode();
18214 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
18244 bool CanReassociate =
N->getFlags().hasAllowReassociation();
18245 if (CanReassociate) {
18250 }
else if (isFusedOp(N1) && N1.
hasOneUse()) {
18256 while (
E && isFusedOp(TmpFMA) && TmpFMA.
hasOneUse()) {
18280 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18294 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18307 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X,
Y,
18308 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18313 if (isFusedOp(N0)) {
18337 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18343 if (isFusedOp(N00)) {
18357 if (isFusedOp(N1)) {
18378 if (isFusedOp(N10)) {
18395SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *
N) {
18398 EVT VT =
N->getValueType(0);
18403 bool HasFMAD = (LegalOperations && TLI.
isFMADLegal(DAG,
N));
18411 if (!HasFMAD && !HasFMA)
18414 const SDNodeFlags
Flags =
N->getFlags();
18415 bool AllowFusionGlobally =
18419 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
18428 bool NoSignedZero =
Flags.hasNoSignedZeros();
18435 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
18451 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18463 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
18466 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
18470 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
18473 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
18482 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18496 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18512 PreferredFusedOpcode, SL, VT,
18534 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18557 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18570 unsigned Opcode =
N.getOpcode();
18575 if (
Aggressive &&
N->getFlags().hasAllowReassociation()) {
18576 bool CanFuse =
N->getFlags().hasAllowContract();
18579 if (CanFuse && isFusedOp(N0) &&
18580 isContractableAndReassociableFMUL(N0.
getOperand(2)) &&
18584 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18592 if (CanFuse && isFusedOp(N1) &&
18593 isContractableAndReassociableFMUL(N1.
getOperand(2)) &&
18598 PreferredFusedOpcode, SL, VT,
18600 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18606 if (isFusedOp(N0) && N0->
hasOneUse()) {
18610 if (isContractableAndReassociableFMUL(N020) &&
18616 PreferredFusedOpcode, SL, VT,
18632 if (isFusedOp(N00)) {
18634 if (isContractableAndReassociableFMUL(N002) &&
18638 PreferredFusedOpcode, SL, VT,
18642 PreferredFusedOpcode, SL, VT,
18655 if (isContractableAndReassociableFMUL(N120) &&
18661 PreferredFusedOpcode, SL, VT,
18663 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18681 if (isContractableAndReassociableFMUL(N102) &&
18687 PreferredFusedOpcode, SL, VT,
18691 DAG.
getNode(PreferredFusedOpcode, SL, VT,
18705SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *
N) {
18708 EVT VT =
N->getValueType(0);
18718 if (!
FAdd->getFlags().hasNoInfs())
18729 bool HasFMAD = LegalOperations && TLI.
isFMADLegal(DAG,
N);
18732 if (!HasFMAD && !HasFMA)
18744 if (
C->isExactlyValue(+1.0))
18745 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18747 if (
C->isExactlyValue(-1.0))
18748 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18755 if (
SDValue FMA = FuseFADD(N0, N1))
18757 if (
SDValue FMA = FuseFADD(N1, N0))
18767 if (C0->isExactlyValue(+1.0))
18768 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18771 if (C0->isExactlyValue(-1.0))
18772 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18777 if (C1->isExactlyValue(+1.0))
18778 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18780 if (C1->isExactlyValue(-1.0))
18781 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18788 if (
SDValue FMA = FuseFSUB(N0, N1))
18790 if (
SDValue FMA = FuseFSUB(N1, N0))
18796SDValue DAGCombiner::visitFADD(SDNode *
N) {
18801 EVT VT =
N->getValueType(0);
18803 SDNodeFlags
Flags =
N->getFlags();
18804 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18814 if (N0CFP && !N1CFP)
18819 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18824 if (N1C && N1C->
isZero())
18828 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18834 N1, DAG, LegalOperations, ForCodeSize))
18840 N0, DAG, LegalOperations, ForCodeSize))
18847 return C &&
C->isExactlyValue(-2.0);
18851 if (isFMulNegTwo(N0)) {
18857 if (isFMulNegTwo(N1)) {
18868 if (
Flags.hasNoNaNs() && AllowNewConst) {
18881 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18899 if (CFP01 && !CFP00 && N0.
getOperand(0) == N1) {
18920 if (CFP11 && !CFP10 && N1.
getOperand(0) == N0) {
18967 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros()) {
18970 VT, N0, N1, Flags))
18975 if (
SDValue Fused = visitFADDForFMACombine(
N)) {
18977 AddToWorklist(Fused.getNode());
18983SDValue DAGCombiner::visitSTRICT_FADD(SDNode *
N) {
18987 EVT VT =
N->getValueType(0);
18988 EVT ChainVT =
N->getValueType(1);
18990 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18995 N1, DAG, LegalOperations, ForCodeSize)) {
18997 {Chain, N0, NegN1});
19003 N0, DAG, LegalOperations, ForCodeSize)) {
19005 {Chain, N1, NegN0});
19010SDValue DAGCombiner::visitFSUB(SDNode *
N) {
19015 EVT VT =
N->getValueType(0);
19017 const SDNodeFlags
Flags =
N->getFlags();
19018 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19029 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
19032 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19036 if (N1CFP && N1CFP->
isZero()) {
19044 if (
Flags.hasNoNaNs())
19049 if (N0CFP && N0CFP->
isZero()) {
19066 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
19082 if (
SDValue Fused = visitFSUBForFMACombine(
N)) {
19083 AddToWorklist(Fused.getNode());
19105SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *
N) {
19106 EVT VT =
N->getValueType(0);
19112 std::optional<int> Mantissa;
19113 auto GetConstAndPow2Ops = [&](
unsigned ConstOpIdx) {
19114 if (ConstOpIdx == 1 &&
N->getOpcode() ==
ISD::FDIV)
19131 auto IsFPConstValid = [
N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
19132 if (CFP ==
nullptr)
19135 const APFloat &APF = CFP->getValueAPF();
19143 int CurExp =
ilogb(APF);
19146 N->getOpcode() ==
ISD::FMUL ? CurExp : (CurExp - MaxExpChange);
19149 N->getOpcode() ==
ISD::FDIV ? CurExp : (CurExp + MaxExpChange);
19157 Mantissa = ThisMantissa;
19159 return *Mantissa == ThisMantissa && ThisMantissa > 0;
19166 if (!GetConstAndPow2Ops(0) && !GetConstAndPow2Ops(1))
19194 NewIntVT, DAG.
getBitcast(NewIntVT, ConstOp), Shift);
19199SDValue DAGCombiner::visitFMUL(SDNode *
N) {
19203 EVT VT =
N->getValueType(0);
19205 const SDNodeFlags
Flags =
N->getFlags();
19206 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19222 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
19225 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19228 if (
Flags.hasAllowReassociation()) {
19254 VT, N0, N1, Flags))
19278 HandleSDNode NegN0Handle(NegN0);
19288 if (
Flags.hasNoNaNs() &&
Flags.hasNoSignedZeros() &&
19319 if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
19323 if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
19332 if (
SDValue Fused = visitFMULForFMADistributiveCombine(
N)) {
19333 AddToWorklist(Fused.getNode());
19339 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
19345SDValue DAGCombiner::visitFMA(SDNode *
N) {
19352 EVT VT =
N->getValueType(0);
19355 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19370 HandleSDNode NegN0Handle(NegN0);
19378 if (
N->getFlags().hasNoNaNs() &&
N->getFlags().hasNoInfs()) {
19379 if (
N->getFlags().hasNoSignedZeros() || (N2CFP && !N2CFP->
isNegZero())) {
19380 if (N0CFP && N0CFP->
isZero())
19382 if (N1CFP && N1CFP->
isZero())
19397 bool CanReassociate =
N->getFlags().hasAllowReassociation();
19398 if (CanReassociate) {
19425 AddToWorklist(RHSNeg.
getNode());
19439 if (CanReassociate) {
19441 if (N1CFP && N0 == N2) {
19459 SDValue(
N, 0), DAG, LegalOperations, ForCodeSize))
19464SDValue DAGCombiner::visitFMAD(SDNode *
N) {
19468 EVT VT =
N->getValueType(0);
19478SDValue DAGCombiner::visitFMULADD(SDNode *
N) {
19482 EVT VT =
N->getValueType(0);
19500SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *
N) {
19504 const SDNodeFlags
Flags =
N->getFlags();
19505 if (LegalDAG || !
Flags.hasAllowReciprocal())
19520 unsigned NumElts = 1;
19521 EVT VT =
N->getValueType(0);
19525 if (!MinUses || (N1->
use_size() * NumElts) < MinUses)
19530 SetVector<SDNode *>
Users;
19531 for (
auto *U : N1->
users()) {
19532 if (
U->getOpcode() ==
ISD::FDIV &&
U->getOperand(1) == N1) {
19534 if (
U->getOperand(1).getOpcode() ==
ISD::FSQRT &&
19535 U->getOperand(0) ==
U->getOperand(1).getOperand(0) &&
19536 U->getFlags().hasAllowReassociation() &&
19537 U->getFlags().hasNoSignedZeros())
19542 if (
U->getFlags().hasAllowReciprocal())
19549 if ((
Users.size() * NumElts) < MinUses)
19557 for (
auto *U :
Users) {
19558 SDValue Dividend =
U->getOperand(0);
19559 if (Dividend != FPOne) {
19561 Reciprocal, Flags);
19562 CombineTo(U, NewNode);
19563 }
else if (U != Reciprocal.
getNode()) {
19566 CombineTo(U, Reciprocal);
19572SDValue DAGCombiner::visitFDIV(SDNode *
N) {
19575 EVT VT =
N->getValueType(0);
19577 SDNodeFlags
Flags =
N->getFlags();
19578 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19589 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
19592 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19609 (!LegalOperations ||
19619 if (
Flags.hasAllowReciprocal()) {
19628 N1AllowReciprocal) {
19661 A =
Y.getOperand(0);
19674 recursivelyDeleteUnusedNodes(AAZ.
getNode());
19683 AddToWorklist(Div.
getNode());
19690 if (
Flags.hasNoInfs())
19691 if (
SDValue RV = BuildDivEstimate(N0, N1, Flags))
19697 Flags.hasAllowReassociation())
19709 HandleSDNode NegN0Handle(NegN0);
19717 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
19723SDValue DAGCombiner::visitFREM(SDNode *
N) {
19726 EVT VT =
N->getValueType(0);
19727 SDNodeFlags
Flags =
N->getFlags();
19728 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19738 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19766SDValue DAGCombiner::visitFSQRT(SDNode *
N) {
19767 SDNodeFlags
Flags =
N->getFlags();
19771 if (!
Flags.hasApproximateFuncs() || !
Flags.hasNoInfs())
19779 SelectionDAG::FlagInserter FlagInserter(DAG, Flags);
19784 return buildSqrtEstimate(N0, Flags);
19799 if (YTy == MVT::f128)
19816SDValue DAGCombiner::visitFCOPYSIGN(SDNode *
N) {
19819 EVT VT =
N->getValueType(0);
19857SDValue DAGCombiner::visitFPOW(SDNode *
N) {
19861 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19867 EVT VT =
N->getValueType(0);
19869 if ((ScalarVT == MVT::f32 &&
19871 (ScalarVT == MVT::f64 &&
19879 SDNodeFlags
Flags =
N->getFlags();
19880 if (!
Flags.hasNoSignedZeros() || !
Flags.hasNoInfs() || !
Flags.hasNoNaNs() ||
19881 !
Flags.hasApproximateFuncs())
19903 if (ExponentIs025 || ExponentIs075) {
19911 SDNodeFlags
Flags =
N->getFlags();
19914 if ((!
Flags.hasNoSignedZeros() && ExponentIs025) || !
Flags.hasNoInfs() ||
19915 !
Flags.hasApproximateFuncs())
19952 EVT VT =
N->getValueType(0);