86#define DEBUG_TYPE "dagcombine"
88STATISTIC(NodesCombined ,
"Number of dag nodes combined");
89STATISTIC(PreIndexedNodes ,
"Number of pre-indexed nodes created");
90STATISTIC(PostIndexedNodes,
"Number of post-indexed nodes created");
91STATISTIC(OpsNarrowed ,
"Number of load/op/store narrowed");
92STATISTIC(LdStFP2Int ,
"Number of fp load/store pairs transformed to int");
94STATISTIC(NumFPLogicOpsConv,
"Number of logic ops converted to fp ops");
97 "Controls whether a DAG combine is performed for a node");
101 cl::desc(
"Enable DAG combiner's use of IR alias analysis"));
105 cl::desc(
"Enable DAG combiner's use of TBAA"));
110 cl::desc(
"Only use DAG-combiner alias analysis in this"
118 cl::desc(
"Bypass the profitability model of load slicing"),
123 cl::desc(
"DAG combiner may split indexing from loads"));
127 cl::desc(
"DAG combiner enable merging multiple stores "
128 "into a wider store"));
132 cl::desc(
"Limit the number of operands to inline for Token Factors"));
136 cl::desc(
"Limit the number of times for the same StoreNode and RootNode "
137 "to bail out in store merging dependence check"));
141 cl::desc(
"DAG combiner enable reducing the width of load/op/store "
144 "combiner-reduce-load-op-store-width-force-narrowing-profitable",
146 cl::desc(
"DAG combiner force override the narrowing profitable check when "
147 "reducing the width of load/op/store sequences"));
151 cl::desc(
"DAG combiner enable load/<replace bytes>/store with "
152 "a narrower store"));
156 cl::desc(
"Disable the DAG combiner"));
166 bool LegalDAG =
false;
167 bool LegalOperations =
false;
168 bool LegalTypes =
false;
170 bool DisableGenericCombines;
206 void AddUsersToWorklist(
SDNode *
N) {
212 void AddToWorklistWithUsers(SDNode *
N) {
213 AddUsersToWorklist(
N);
220 void clearAddedDanglingWorklistEntries() {
222 while (!PruningList.empty()) {
223 auto *
N = PruningList.pop_back_val();
225 recursivelyDeleteUnusedNodes(
N);
229 SDNode *getNextWorklistEntry() {
231 clearAddedDanglingWorklistEntries();
235 while (!
N && !Worklist.empty()) {
236 N = Worklist.pop_back_val();
240 assert(
N->getCombinerWorklistIndex() >= 0 &&
241 "Found a worklist entry without a corresponding map entry!");
243 N->setCombinerWorklistIndex(-2);
253 : DAG(
D), TLI(
D.getTargetLoweringInfo()),
254 STI(
D.getSubtarget().getSelectionDAGInfo()), OptLevel(OL),
256 ForCodeSize = DAG.shouldOptForSize();
257 DisableGenericCombines =
260 MaximumLegalStoreInBits = 0;
264 if (EVT(VT).
isSimple() && VT != MVT::Other &&
265 TLI.isTypeLegal(EVT(VT)) &&
266 VT.getSizeInBits().getKnownMinValue() >= MaximumLegalStoreInBits)
267 MaximumLegalStoreInBits = VT.getSizeInBits().getKnownMinValue();
270 void ConsiderForPruning(SDNode *
N) {
272 PruningList.insert(
N);
277 void AddToWorklist(SDNode *
N,
bool IsCandidateForPruning =
true,
278 bool SkipIfCombinedBefore =
false) {
280 "Deleted Node added to Worklist");
287 if (SkipIfCombinedBefore &&
N->getCombinerWorklistIndex() == -2)
290 if (IsCandidateForPruning)
291 ConsiderForPruning(
N);
293 if (
N->getCombinerWorklistIndex() < 0) {
294 N->setCombinerWorklistIndex(Worklist.size());
295 Worklist.push_back(
N);
300 void removeFromWorklist(SDNode *
N) {
301 PruningList.remove(
N);
302 StoreRootCountMap.erase(
N);
304 int WorklistIndex =
N->getCombinerWorklistIndex();
308 if (WorklistIndex < 0)
312 Worklist[WorklistIndex] =
nullptr;
313 N->setCombinerWorklistIndex(-1);
316 void deleteAndRecombine(SDNode *
N);
317 bool recursivelyDeleteUnusedNodes(SDNode *
N);
325 return CombineTo(
N, &Res, 1, AddTo);
332 return CombineTo(
N, To, 2, AddTo);
335 SDValue CombineTo(SDNode *
N, SmallVectorImpl<SDValue> *To,
337 return CombineTo(
N, To->
data(), To->
size(), AddTo);
340 void CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO);
343 unsigned MaximumLegalStoreInBits;
349 unsigned BitWidth =
Op.getScalarValueSizeInBits();
351 return SimplifyDemandedBits(
Op, DemandedBits);
354 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits) {
355 EVT VT =
Op.getValueType();
359 return SimplifyDemandedBits(
Op, DemandedBits, DemandedElts,
false);
365 bool SimplifyDemandedVectorElts(
SDValue Op) {
367 if (
Op.getValueType().isScalableVector())
370 unsigned NumElts =
Op.getValueType().getVectorNumElements();
372 return SimplifyDemandedVectorElts(
Op, DemandedElts);
375 bool SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
376 const APInt &DemandedElts,
377 bool AssumeSingleUse =
false);
378 bool SimplifyDemandedVectorElts(
SDValue Op,
const APInt &DemandedElts,
379 bool AssumeSingleUse =
false);
381 bool CombineToPreIndexedLoadStore(SDNode *
N);
382 bool CombineToPostIndexedLoadStore(SDNode *
N);
383 SDValue SplitIndexingFromLoad(LoadSDNode *LD);
384 bool SliceUpLoad(SDNode *
N);
390 StoreSDNode *getUniqueStoreFeeding(LoadSDNode *LD, int64_t &
Offset);
392 SDValue ForwardStoreValueToDirectLoad(LoadSDNode *LD);
393 bool getTruncatedStoreValue(StoreSDNode *ST,
SDValue &Val);
394 bool extendLoadedValueToExtension(LoadSDNode *LD,
SDValue &Val);
396 void ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad);
405 SDValue foldShiftToAvg(SDNode *
N,
const SDLoc &
DL);
407 SDValue foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT);
425 SDValue visitTokenFactor(SDNode *
N);
426 SDValue visitMERGE_VALUES(SDNode *
N);
430 SDNode *LocReference);
441 SDValue visitUADDO_CARRY(SDNode *
N);
442 SDValue visitSADDO_CARRY(SDNode *
N);
448 SDValue visitUSUBO_CARRY(SDNode *
N);
449 SDValue visitSSUBO_CARRY(SDNode *
N);
450 template <
class MatchContextClass>
SDValue visitMUL(SDNode *
N);
471 SDValue SimplifyVCastOp(SDNode *
N,
const SDLoc &
DL);
472 SDValue SimplifyVBinOp(SDNode *
N,
const SDLoc &
DL);
476 SDValue visitFunnelShift(SDNode *
N);
483 SDValue visitCTLZ_ZERO_UNDEF(SDNode *
N);
485 SDValue visitCTTZ_ZERO_UNDEF(SDNode *
N);
493 SDValue visitSIGN_EXTEND(SDNode *
N);
494 SDValue visitZERO_EXTEND(SDNode *
N);
497 SDValue visitAssertAlign(SDNode *
N);
498 SDValue visitSIGN_EXTEND_INREG(SDNode *
N);
499 SDValue visitEXTEND_VECTOR_INREG(SDNode *
N);
501 SDValue visitTRUNCATE_USAT_U(SDNode *
N);
508 SDValue visitSTRICT_FADD(SDNode *
N);
511 template <
class MatchContextClass>
SDValue visitFMA(SDNode *
N);
519 SDValue visitFCANONICALIZE(SDNode *
N);
539 SDValue replaceStoreOfFPConstant(StoreSDNode *ST);
540 SDValue replaceStoreOfInsertLoad(StoreSDNode *ST);
542 bool refineExtractVectorEltIntoMultipleNarrowExtractVectorElts(SDNode *
N);
545 SDValue visitATOMIC_STORE(SDNode *
N);
546 SDValue visitLIFETIME_END(SDNode *
N);
547 SDValue visitINSERT_VECTOR_ELT(SDNode *
N);
548 SDValue visitEXTRACT_VECTOR_ELT(SDNode *
N);
549 SDValue visitBUILD_VECTOR(SDNode *
N);
550 SDValue visitCONCAT_VECTORS(SDNode *
N);
551 SDValue visitVECTOR_INTERLEAVE(SDNode *
N);
552 SDValue visitEXTRACT_SUBVECTOR(SDNode *
N);
553 SDValue visitVECTOR_SHUFFLE(SDNode *
N);
554 SDValue visitSCALAR_TO_VECTOR(SDNode *
N);
555 SDValue visitINSERT_SUBVECTOR(SDNode *
N);
556 SDValue visitVECTOR_COMPRESS(SDNode *
N);
562 SDValue visitPARTIAL_REDUCE_MLA(SDNode *
N);
565 SDValue visitVP_STRIDED_LOAD(SDNode *
N);
566 SDValue visitVP_STRIDED_STORE(SDNode *
N);
573 SDValue visitGET_FPENV_MEM(SDNode *
N);
574 SDValue visitSET_FPENV_MEM(SDNode *
N);
576 template <
class MatchContextClass>
577 SDValue visitFADDForFMACombine(SDNode *
N);
578 template <
class MatchContextClass>
579 SDValue visitFSUBForFMACombine(SDNode *
N);
580 SDValue visitFMULForFMADistributiveCombine(SDNode *
N);
582 SDValue XformToShuffleWithZero(SDNode *
N);
583 bool reassociationCanBreakAddressingModePattern(
unsigned Opc,
589 SDValue N1, SDNodeFlags Flags);
591 SDValue N1, SDNodeFlags Flags);
592 SDValue reassociateReduction(
unsigned RedOpc,
unsigned Opc,
const SDLoc &
DL,
594 SDNodeFlags Flags = SDNodeFlags());
596 SDValue visitShiftByConstant(SDNode *
N);
598 SDValue foldSelectOfConstants(SDNode *
N);
599 SDValue foldVSelectOfConstants(SDNode *
N);
600 SDValue foldBinOpIntoSelect(SDNode *BO);
602 SDValue hoistLogicOpWithSameOpcodeHands(SDNode *
N);
606 bool NotExtCompare =
false);
607 SDValue convertSelectOfFPConstantsToLoadOffset(
610 SDValue foldSignChangeInBitcast(SDNode *
N);
613 SDValue foldSelectOfBinops(SDNode *
N);
617 SDValue foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL);
618 SDValue foldABSToABD(SDNode *
N,
const SDLoc &
DL);
623 SDValue unfoldMaskedMerge(SDNode *
N);
624 SDValue unfoldExtremeBitClearingToShifts(SDNode *
N);
626 const SDLoc &
DL,
bool foldBooleans);
630 SDValue &CC,
bool MatchStrict =
false)
const;
631 bool isOneUseSetCC(
SDValue N)
const;
633 SDValue foldAddToAvg(SDNode *
N,
const SDLoc &
DL);
634 SDValue foldSubToAvg(SDNode *
N,
const SDLoc &
DL);
638 SDValue SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
640 SDValue CombineConsecutiveLoads(SDNode *
N, EVT VT);
641 SDValue foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
642 const TargetLowering &TLI);
643 SDValue foldPartialReduceMLAMulOp(SDNode *
N);
644 SDValue foldPartialReduceAdd(SDNode *
N);
647 SDValue CombineZExtLogicopShiftLoad(SDNode *
N);
648 SDValue combineRepeatedFPDivisors(SDNode *
N);
649 SDValue combineFMulOrFDivWithIntPow2(SDNode *
N);
650 SDValue replaceShuffleOfInsert(ShuffleVectorSDNode *Shuf);
651 SDValue mergeInsertEltWithShuffle(SDNode *
N,
unsigned InsIndex);
652 SDValue combineInsertEltToShuffle(SDNode *
N,
unsigned InsIndex);
653 SDValue combineInsertEltToLoad(SDNode *
N,
unsigned InsIndex);
660 bool KnownNeverZero =
false,
661 bool InexpensiveOnly =
false,
662 std::optional<EVT> OutVT = std::nullopt);
672 bool DemandHighBits =
true);
676 bool HasPos,
unsigned PosOpcode,
677 unsigned NegOpcode,
const SDLoc &
DL);
680 bool HasPos,
unsigned PosOpcode,
681 unsigned NegOpcode,
const SDLoc &
DL);
684 SDValue MatchLoadCombine(SDNode *
N);
685 SDValue mergeTruncStores(StoreSDNode *
N);
687 SDValue ReduceLoadOpStoreWidth(SDNode *
N);
689 SDValue TransformFPLoadStorePair(SDNode *
N);
690 SDValue convertBuildVecZextToZext(SDNode *
N);
691 SDValue convertBuildVecZextToBuildVecWithZeros(SDNode *
N);
692 SDValue reduceBuildVecExtToExtBuildVec(SDNode *
N);
693 SDValue reduceBuildVecTruncToBitCast(SDNode *
N);
694 SDValue reduceBuildVecToShuffle(SDNode *
N);
695 SDValue createBuildVecShuffle(
const SDLoc &
DL, SDNode *
N,
696 ArrayRef<int> VectorMask,
SDValue VecIn1,
697 SDValue VecIn2,
unsigned LeftIdx,
699 SDValue matchVSelectOpSizesWithSetCC(SDNode *Cast);
703 void GatherAllAliases(SDNode *
N,
SDValue OriginalChain,
704 SmallVectorImpl<SDValue> &Aliases);
707 bool mayAlias(SDNode *Op0, SDNode *Op1)
const;
719 bool findBetterNeighborChains(StoreSDNode *St);
723 bool parallelizeChainedStores(StoreSDNode *St);
729 LSBaseSDNode *MemNode;
732 int64_t OffsetFromBase;
734 MemOpLink(LSBaseSDNode *
N, int64_t
Offset)
735 : MemNode(
N), OffsetFromBase(
Offset) {}
740 StoreSource getStoreSource(
SDValue StoreVal) {
744 return StoreSource::Constant;
748 return StoreSource::Constant;
749 return StoreSource::Unknown;
752 return StoreSource::Extract;
754 return StoreSource::Load;
756 return StoreSource::Unknown;
764 bool isMulAddWithConstProfitable(SDNode *MulNode,
SDValue AddNode,
770 bool isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
771 EVT LoadResultTy, EVT &ExtVT);
776 EVT &MemVT,
unsigned ShAmt = 0);
779 bool SearchForAndLoads(SDNode *
N, SmallVectorImpl<LoadSDNode*> &Loads,
780 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
781 ConstantSDNode *Mask, SDNode *&NodeToMask);
784 bool BackwardsPropagateMask(SDNode *
N);
788 SDValue getMergeStoreChains(SmallVectorImpl<MemOpLink> &StoreNodes,
800 bool mergeStoresOfConstantsOrVecElts(SmallVectorImpl<MemOpLink> &StoreNodes,
801 EVT MemVT,
unsigned NumStores,
802 bool IsConstantSrc,
bool UseVector,
808 SDNode *getStoreMergeCandidates(StoreSDNode *St,
809 SmallVectorImpl<MemOpLink> &StoreNodes);
815 bool checkMergeStoreCandidatesForDependencies(
816 SmallVectorImpl<MemOpLink> &StoreNodes,
unsigned NumStores,
821 bool hasCallInLdStChain(StoreSDNode *St, LoadSDNode *Ld);
826 unsigned getConsecutiveStores(SmallVectorImpl<MemOpLink> &StoreNodes,
827 int64_t ElementSizeBytes)
const;
831 bool tryStoreMergeOfConstants(SmallVectorImpl<MemOpLink> &StoreNodes,
832 unsigned NumConsecutiveStores,
833 EVT MemVT, SDNode *Root,
bool AllowVectors);
839 bool tryStoreMergeOfExtracts(SmallVectorImpl<MemOpLink> &StoreNodes,
840 unsigned NumConsecutiveStores, EVT MemVT,
845 bool tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
846 unsigned NumConsecutiveStores, EVT MemVT,
847 SDNode *Root,
bool AllowVectors,
848 bool IsNonTemporalStore,
bool IsNonTemporalLoad);
853 bool mergeConsecutiveStores(StoreSDNode *St);
861 SDValue distributeTruncateThroughAnd(SDNode *
N);
867 bool hasOperation(
unsigned Opcode, EVT VT) {
868 return TLI.isOperationLegalOrCustom(Opcode, VT, LegalOperations);
871 bool hasUMin(EVT VT)
const {
872 auto LK = TLI.getTypeConversion(*DAG.getContext(), VT);
875 TLI.isOperationLegalOrCustom(
ISD::UMIN, LK.second);
882 SelectionDAG &getDAG()
const {
return DAG; }
885 EVT getShiftAmountTy(EVT LHSTy) {
886 return TLI.getShiftAmountTy(LHSTy, DAG.getDataLayout());
891 bool isTypeLegal(
const EVT &VT) {
892 if (!LegalTypes)
return true;
893 return TLI.isTypeLegal(VT);
897 EVT getSetCCResultType(EVT VT)
const {
898 return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
901 void ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
912 explicit WorklistRemover(DAGCombiner &dc)
913 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
915 void NodeDeleted(SDNode *
N, SDNode *
E)
override {
916 DC.removeFromWorklist(
N);
924 explicit WorklistInserter(DAGCombiner &dc)
925 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
929 void NodeInserted(SDNode *
N)
override { DC.ConsiderForPruning(
N); }
939 ((DAGCombiner*)
DC)->AddToWorklist(
N);
944 return ((DAGCombiner*)
DC)->CombineTo(
N, &To[0], To.
size(), AddTo);
949 return ((DAGCombiner*)
DC)->CombineTo(
N, Res, AddTo);
954 return ((DAGCombiner*)
DC)->CombineTo(
N, Res0, Res1, AddTo);
959 return ((DAGCombiner*)
DC)->recursivelyDeleteUnusedNodes(
N);
964 return ((DAGCombiner*)
DC)->CommitTargetLoweringOpt(TLO);
971void DAGCombiner::deleteAndRecombine(
SDNode *
N) {
972 removeFromWorklist(
N);
980 if (
Op->hasOneUse() ||
Op->getNumValues() > 1)
981 AddToWorklist(
Op.getNode());
990 unsigned Bits =
Offset + std::max(
LHS.getBitWidth(),
RHS.getBitWidth());
1001 SDValue &CC,
bool MatchStrict)
const {
1003 LHS =
N.getOperand(0);
1004 RHS =
N.getOperand(1);
1012 LHS =
N.getOperand(1);
1013 RHS =
N.getOperand(2);
1026 LHS =
N.getOperand(0);
1027 RHS =
N.getOperand(1);
1035bool DAGCombiner::isOneUseSetCC(
SDValue N)
const {
1037 if (isSetCCEquivalent(
N, N0, N1, N2) &&
N->hasOneUse())
1049 MaskForTy = 0xFFULL;
1052 MaskForTy = 0xFFFFULL;
1055 MaskForTy = 0xFFFFFFFFULL;
1073 bool AllowTruncation =
false) {
1075 return !(Const->isOpaque() && NoOpaques);
1078 unsigned BitWidth =
N.getScalarValueSizeInBits();
1083 if (!Const || (Const->isOpaque() && NoOpaques))
1087 if ((AllowTruncation &&
1088 Const->getAPIntValue().getActiveBits() >
BitWidth) ||
1089 (!AllowTruncation && Const->getAPIntValue().getBitWidth() !=
BitWidth))
1111bool DAGCombiner::reassociationCanBreakAddressingModePattern(
unsigned Opc,
1139 : (N1.
getOperand(0).getConstantOperandVal(0) *
1144 ScalableOffset = -ScalableOffset;
1145 if (
all_of(
N->users(), [&](SDNode *Node) {
1146 if (auto *LoadStore = dyn_cast<MemSDNode>(Node);
1147 LoadStore && LoadStore->getBasePtr().getNode() == N) {
1148 TargetLoweringBase::AddrMode AM;
1149 AM.HasBaseReg = true;
1150 AM.ScalableOffset = ScalableOffset;
1151 EVT VT = LoadStore->getMemoryVT();
1152 unsigned AS = LoadStore->getAddressSpace();
1153 Type *AccessTy = VT.getTypeForEVT(*DAG.getContext());
1154 return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM, AccessTy,
1169 const APInt &C2APIntVal = C2->getAPIntValue();
1177 const APInt &C1APIntVal = C1->getAPIntValue();
1178 const APInt CombinedValueIntVal = C1APIntVal + C2APIntVal;
1181 const int64_t CombinedValue = CombinedValueIntVal.
getSExtValue();
1183 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()) {
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();
1546 bool Replace =
false;
1547 SDValue NewOp = PromoteOperand(
Op, PVT, Replace);
1550 AddToWorklist(NewOp.
getNode());
1553 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1559 EVT OldVT =
Op.getValueType();
1561 bool Replace =
false;
1562 SDValue NewOp = PromoteOperand(
Op, PVT, Replace);
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;
1666 bool Replace =
false;
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());
1819 WorklistInserter AddNodes(*
this);
1827 for (SDNode &Node : DAG.
allnodes())
1828 AddToWorklist(&Node,
Node.use_empty());
1833 HandleSDNode Dummy(DAG.
getRoot());
1836 while (SDNode *
N = getNextWorklistEntry()) {
1840 if (recursivelyDeleteUnusedNodes(
N))
1843 WorklistRemover DeadNodes(*
this);
1848 SmallSetVector<SDNode *, 16> UpdatedNodes;
1851 for (SDNode *LN : UpdatedNodes)
1852 AddToWorklistWithUsers(LN);
1864 for (
const SDValue &ChildN :
N->op_values())
1865 AddToWorklist(ChildN.getNode(),
true,
1876 ChainsWithoutMergeableStores.
clear();
1887 "Node was deleted but visit returned new node!");
1895 N->getNumValues() == 1 &&
"Type mismatch");
1905 AddToWorklistWithUsers(RV.
getNode());
1911 recursivelyDeleteUnusedNodes(
N);
1915 DAG.
setRoot(Dummy.getValue());
1919SDValue DAGCombiner::visit(SDNode *
N) {
1921 switch (
N->getOpcode()) {
1948 case ISD::MUL:
return visitMUL<EmptyMatchContext>(
N);
2012 case ISD::FMA:
return visitFMA<EmptyMatchContext>(
N);
2065 return visitPARTIAL_REDUCE_MLA(
N);
2091#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) case ISD::SDOPC:
2092#include "llvm/IR/VPIntrinsics.def"
2093 return visitVPOp(
N);
2099SDValue DAGCombiner::combine(SDNode *
N) {
2104 if (!DisableGenericCombines)
2110 "Node was deleted but visit returned NULL!");
2116 TargetLowering::DAGCombinerInfo
2117 DagCombineInfo(DAG, Level,
false,
this);
2125 switch (
N->getOpcode()) {
2133 RV = PromoteIntBinOp(
SDValue(
N, 0));
2138 RV = PromoteIntShiftOp(
SDValue(
N, 0));
2174 if (
unsigned NumOps =
N->getNumOperands()) {
2175 if (
N->getOperand(0).getValueType() == MVT::Other)
2176 return N->getOperand(0);
2177 if (
N->getOperand(
NumOps-1).getValueType() == MVT::Other)
2178 return N->getOperand(
NumOps-1);
2179 for (
unsigned i = 1; i <
NumOps-1; ++i)
2180 if (
N->getOperand(i).getValueType() == MVT::Other)
2181 return N->getOperand(i);
2186SDValue DAGCombiner::visitFCANONICALIZE(SDNode *
N) {
2187 SDValue Operand =
N->getOperand(0);
2199SDValue DAGCombiner::visitTokenFactor(SDNode *
N) {
2202 if (
N->getNumOperands() == 2) {
2204 return N->getOperand(0);
2206 return N->getOperand(1);
2221 AddToWorklist(*(
N->user_begin()));
2225 SmallPtrSet<SDNode*, 16> SeenOps;
2233 for (
unsigned i = 0; i < TFs.
size(); ++i) {
2238 for (
unsigned j = i;
j < TFs.
size();
j++)
2239 Ops.emplace_back(TFs[j], 0);
2246 SDNode *TF = TFs[i];
2249 switch (
Op.getOpcode()) {
2267 if (SeenOps.
insert(
Op.getNode()).second)
2278 for (
unsigned i = 1, e = TFs.
size(); i < e; i++)
2279 AddToWorklist(TFs[i]);
2289 SmallVector<unsigned, 8> OpWorkCount;
2290 SmallPtrSet<SDNode *, 16> SeenChains;
2291 bool DidPruneOps =
false;
2293 unsigned NumLeftToConsider = 0;
2295 Worklist.
push_back(std::make_pair(
Op.getNode(), NumLeftToConsider++));
2299 auto AddToWorklist = [&](
unsigned CurIdx, SDNode *
Op,
unsigned OpNumber) {
2305 unsigned OrigOpNumber = 0;
2306 while (OrigOpNumber <
Ops.size() &&
Ops[OrigOpNumber].getNode() !=
Op)
2309 "expected to find TokenFactor Operand");
2311 for (
unsigned i = CurIdx + 1; i < Worklist.
size(); ++i) {
2312 if (Worklist[i].second == OrigOpNumber) {
2313 Worklist[i].second = OpNumber;
2316 OpWorkCount[OpNumber] += OpWorkCount[OrigOpNumber];
2317 OpWorkCount[OrigOpNumber] = 0;
2318 NumLeftToConsider--;
2321 if (SeenChains.
insert(
Op).second) {
2322 OpWorkCount[OpNumber]++;
2327 for (
unsigned i = 0; i < Worklist.
size() && i < 1024; ++i) {
2329 if (NumLeftToConsider <= 1)
2331 auto CurNode = Worklist[i].first;
2332 auto CurOpNumber = Worklist[i].second;
2333 assert((OpWorkCount[CurOpNumber] > 0) &&
2334 "Node should not appear in worklist");
2335 switch (CurNode->getOpcode()) {
2341 NumLeftToConsider++;
2344 for (
const SDValue &
Op : CurNode->op_values())
2345 AddToWorklist(i,
Op.getNode(), CurOpNumber);
2351 AddToWorklist(i, CurNode->getOperand(0).getNode(), CurOpNumber);
2355 AddToWorklist(i, MemNode->getChain().getNode(), CurOpNumber);
2358 OpWorkCount[CurOpNumber]--;
2359 if (OpWorkCount[CurOpNumber] == 0)
2360 NumLeftToConsider--;
2374 if (SeenChains.
count(
Op.getNode()) == 0)
2388SDValue DAGCombiner::visitMERGE_VALUES(SDNode *
N) {
2389 WorklistRemover DeadNodes(*
this);
2395 AddUsersToWorklist(
N);
2400 }
while (!
N->use_empty());
2401 deleteAndRecombine(
N);
2409 return Const !=
nullptr && !Const->isOpaque() ? Const :
nullptr;
2419 Op =
N->getOperand(0);
2421 if (
N->getFlags().hasNoUnsignedWrap())
2426 if (
N.getValueType().getScalarType() != MVT::i1 ||
2443 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2445 VT = LD->getMemoryVT();
2446 AS = LD->getAddressSpace();
2448 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2450 VT = ST->getMemoryVT();
2451 AS = ST->getAddressSpace();
2453 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2455 VT = LD->getMemoryVT();
2456 AS = LD->getAddressSpace();
2458 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2460 VT = ST->getMemoryVT();
2461 AS = ST->getAddressSpace();
2467 if (
N->isAnyAdd()) {
2476 }
else if (
N->getOpcode() ==
ISD::SUB) {
2498 bool ShouldCommuteOperands) {
2504 if (ShouldCommuteOperands)
2518 unsigned Opcode =
N->getOpcode();
2519 EVT VT =
N->getValueType(0);
2524 unsigned OpNo = ShouldCommuteOperands ? 0 : 1;
2544SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
2547 "Unexpected binary operator");
2559 unsigned SelOpNo = 0;
2596 bool CanFoldNonConst =
2602 if (!CanFoldNonConst &&
2611 if (CanFoldNonConst) {
2630 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CT, CBO});
2635 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CF, CBO});
2646 "Expecting add or sub");
2651 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2652 SDValue C = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2653 SDValue Z = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2659 if (Z.getOperand(0).getValueType() != MVT::i1)
2671 EVT VT =
C.getValueType();
2679SDValue DAGCombiner::foldSubToAvg(SDNode *
N,
const SDLoc &
DL) {
2684 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
2689 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
2700SDValue DAGCombiner::visitPTRADD(SDNode *
N) {
2710 "PTRADD with different operand types is not supported");
2721 !reassociationCanBreakAddressingModePattern(
ISD::PTRADD,
DL,
N, N0, N1)) {
2732 if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
2737 AddToWorklist(
Add.getNode());
2761 if (
const GlobalAddressSDNode *GA =
2776 AddToWorklist(Inner.
getNode());
2798 SDNodeFlags CommonFlags =
N->getFlags() & N1->
getFlags();
2806 if (ZIsConstant != YIsConstant) {
2810 AddToWorklist(Inner.
getNode());
2820 bool TransformCannotBreakAddrMode =
none_of(
N->users(), [&](SDNode *User) {
2821 return canFoldInAddressingMode(N, User, DAG, TLI);
2824 if (TransformCannotBreakAddrMode)
2836 "Expecting add or sub");
2840 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2841 SDValue ConstantOp = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2842 SDValue ShiftOp = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2864 {ConstantOp, DAG.getConstant(1, DL, VT)})) {
2866 Not.getOperand(0), ShAmt);
2882SDValue DAGCombiner::visitADDLike(SDNode *
N) {
2908 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
2940 if ((!LegalOperations ||
2943 X.getScalarValueSizeInBits() == 1) {
2959 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
2963 if (!reassociationCanBreakAddressingModePattern(
ISD::ADD,
DL,
N, N0, N1)) {
3050 auto MatchUSUBSAT = [](ConstantSDNode *
Max, ConstantSDNode *
Op) {
3051 return (!Max && !
Op) ||
3052 (
Max &&
Op &&
Max->getAPIntValue() == (-
Op->getAPIntValue()));
3093 !
N->getFlags().hasNoSignedWrap()))) {
3114 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3118 if (
N->getFlags().hasNoUnsignedWrap() &&
3122 if (
N->getFlags().hasNoSignedWrap() &&
3131 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3139 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3145 if (
N->getFlags().hasNoUnsignedWrap() &&
3150 if (
N->getFlags().hasNoSignedWrap() &&
3161 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3166 if (
SDValue Combined = visitADDLikeCommutative(N0, N1,
N))
3169 if (
SDValue Combined = visitADDLikeCommutative(N1, N0,
N))
3177SDValue DAGCombiner::foldAddToAvg(SDNode *
N,
const SDLoc &
DL) {
3206SDValue DAGCombiner::visitADD(SDNode *
N) {
3212 if (
SDValue Combined = visitADDLike(
N))
3221 if (
SDValue V = MatchRotate(N0, N1, SDLoc(
N),
true))
3255 APInt NewStep = C0 + C1;
3265 APInt NewStep = SV0 + SV1;
3273SDValue DAGCombiner::visitADDSAT(SDNode *
N) {
3274 unsigned Opcode =
N->getOpcode();
3292 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
3296 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
3316 bool ForceCarryReconstruction =
false) {
3321 if (ForceCarryReconstruction && V.getValueType() == MVT::i1)
3325 V = V.getOperand(0);
3330 if (ForceCarryReconstruction)
3334 V = V.getOperand(0);
3342 if (V.getResNo() != 1)
3349 EVT VT = V->getValueType(0);
3393 SDNode *LocReference) {
3395 SDLoc
DL(LocReference);
3457 if (TN->
getVT() == MVT::i1) {
3474 DAG.
getVTList(VT, Carry.getValueType()), N0,
3480SDValue DAGCombiner::visitADDC(SDNode *
N) {
3487 if (!
N->hasAnyUseOfValue(1))
3527 return V.getOperand(0);
3533SDValue DAGCombiner::visitADDO(SDNode *
N) {
3539 EVT CarryVT =
N->getValueType(1);
3543 if (!
N->hasAnyUseOfValue(1))
3550 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
3575 if (
SDValue Combined = visitUADDOLike(N0, N1,
N))
3578 if (
SDValue Combined = visitUADDOLike(N1, N0,
N))
3609SDValue DAGCombiner::visitADDE(SDNode *
N) {
3628SDValue DAGCombiner::visitUADDO_CARRY(SDNode *
N) {
3642 if (!LegalOperations ||
3652 AddToWorklist(CarryExt.
getNode());
3658 if (
SDValue Combined = visitUADDO_CARRYLike(N0, N1, CarryIn,
N))
3661 if (
SDValue Combined = visitUADDO_CARRYLike(N1, N0, CarryIn,
N))
3808 EVT CarryOutType =
N->getValueType(0);
3824 unsigned CarryInOperandNum =
3826 if (Opcode ==
ISD::USUBO && CarryInOperandNum != 1)
3917SDValue DAGCombiner::visitSADDO_CARRY(SDNode *
N) {
3931 if (!LegalOperations ||
3936 if (
SDValue Combined = visitSADDO_CARRYLike(N0, N1, CarryIn,
N))
3939 if (
SDValue Combined = visitSADDO_CARRYLike(N1, N0, CarryIn,
N))
3951 "Illegal truncation");
3975SDValue DAGCombiner::foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL) {
3977 !(!LegalOperations || hasOperation(
ISD::USUBSAT, DstVT)))
3980 EVT SubVT =
N->getValueType(0);
4048template <
class MatchContextClass>
4071 if ((
BitWidth - Src.getValueType().getScalarSizeInBits()) != BitWidthDiff)
4083 if (!(AndMask.
isMask(AndMaskWidth) && XorMask.
countr_one() >= AndMaskWidth))
4118 if (
SDValue Res = CheckAndFoldMulCase(Mul0, Mul1))
4121 if (
SDValue Res = CheckAndFoldMulCase(Mul1, Mul0))
4159SDValue DAGCombiner::visitSUB(SDNode *
N) {
4179 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4206 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4229 if (
N->getFlags().hasNoUnsignedWrap())
4235 if (
N->getFlags().hasNoSignedWrap())
4261 if (hasOperation(NewOpc, VT))
4403 if (!reassociationCanBreakAddressingModePattern(
ISD::SUB,
DL,
N, N0, N1) &&
4441 if ((!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4451 if (GA->getGlobal() == GB->getGlobal())
4452 return DAG.
getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
4459 if (TN->
getVT() == MVT::i1) {
4512 DAG.
getVTList(VT, Carry.getValueType()), NegX, Zero,
4520 if (!C0->isOpaque()) {
4521 const APInt &C0Val = C0->getAPIntValue();
4522 const APInt &MaybeOnes = ~DAG.computeKnownBits(N1).Zero;
4523 if ((C0Val - MaybeOnes) == (C0Val ^ MaybeOnes))
4529 if ((!LegalOperations || hasOperation(
ISD::ABDS, VT)) &&
4541 if ((!LegalOperations || hasOperation(
ISD::ABDU, VT)) &&
4555SDValue DAGCombiner::visitSUBSAT(SDNode *
N) {
4556 unsigned Opcode =
N->getOpcode();
4577 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4596SDValue DAGCombiner::visitSUBC(SDNode *
N) {
4603 if (!
N->hasAnyUseOfValue(1))
4624SDValue DAGCombiner::visitSUBO(SDNode *
N) {
4630 EVT CarryVT =
N->getValueType(1);
4634 if (!
N->hasAnyUseOfValue(1))
4666SDValue DAGCombiner::visitSUBE(SDNode *
N) {
4678SDValue DAGCombiner::visitUSUBO_CARRY(SDNode *
N) {
4685 if (!LegalOperations ||
4693SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *
N) {
4700 if (!LegalOperations ||
4710SDValue DAGCombiner::visitMULFIX(SDNode *
N) {
4723 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0, Scale);
4732template <
class MatchContextClass>
SDValue DAGCombiner::visitMUL(SDNode *
N) {
4738 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
4739 MatchContextClass Matcher(DAG, TLI,
N);
4754 bool N1IsConst =
false;
4755 bool N1IsOpaqueConst =
false;
4762 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4767 "Splat APInt should be element width");
4777 if (N1IsConst && ConstValue1.
isZero())
4781 if (N1IsConst && ConstValue1.
isOne())
4785 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4789 if (N1IsConst && ConstValue1.
isAllOnes())
4795 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
4799 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap());
4801 return Matcher.getNode(
ISD::SHL,
DL, VT, N0, Trunc, Flags);
4807 unsigned Log2Val = (-ConstValue1).logBase2();
4811 return Matcher.getNode(
4822 SDVTList LoHiVT = DAG.
getVTList(VT, VT);
4825 if (LoHi->hasAnyUseOfValue(1))
4828 if (LoHi->hasAnyUseOfValue(1))
4849 if (!UseVP && N1IsConst &&
4855 APInt MulC = ConstValue1.
abs();
4857 unsigned TZeros = MulC == 2 ? 0 : MulC.
countr_zero();
4859 if ((MulC - 1).isPowerOf2())
4861 else if ((MulC + 1).isPowerOf2())
4866 MathOp ==
ISD::ADD ? (MulC - 1).logBase2() : (MulC + 1).logBase2();
4869 "multiply-by-constant generated out of bounds shift");
4873 TZeros ? DAG.
getNode(MathOp,
DL, VT, Shl,
4915 return Matcher.getNode(
4933 APInt NewStep = C0 * MulVal;
4939 if (!UseVP && (!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4953 SmallBitVector ClearMask;
4955 auto IsClearMask = [&ClearMask](ConstantSDNode *
V) {
4956 if (!V ||
V->isZero()) {
4970 for (
unsigned I = 0;
I != NumElts; ++
I)
5001 EVT NodeType =
Node->getValueType(0);
5002 if (!NodeType.isSimple())
5004 switch (NodeType.getSimpleVT().SimpleTy) {
5005 default:
return false;
5006 case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
5007 case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
5008 case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
5009 case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
5010 case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
5017SDValue DAGCombiner::useDivRem(SDNode *Node) {
5018 if (
Node->use_empty())
5021 unsigned Opcode =
Node->getOpcode();
5026 EVT VT =
Node->getValueType(0);
5040 unsigned OtherOpcode = 0;
5054 for (SDNode *User : Op0->
users()) {
5061 unsigned UserOpc =
User->getOpcode();
5062 if ((UserOpc == Opcode || UserOpc == OtherOpcode || UserOpc == DivRemOpc) &&
5063 User->getOperand(0) == Op0 &&
5064 User->getOperand(1) == Op1) {
5066 if (UserOpc == OtherOpcode) {
5068 combined = DAG.
getNode(DivRemOpc, SDLoc(Node), VTs, Op0, Op1);
5069 }
else if (UserOpc == DivRemOpc) {
5072 assert(UserOpc == Opcode);
5077 CombineTo(User, combined);
5079 CombineTo(User, combined.
getValue(1));
5088 EVT VT =
N->getValueType(0);
5091 unsigned Opc =
N->getOpcode();
5110 if (N0C && N0C->
isZero())
5130SDValue DAGCombiner::visitSDIV(SDNode *
N) {
5133 EVT VT =
N->getValueType(0);
5143 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5160 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5168 if (
SDValue V = visitSDIVLike(N0, N1,
N)) {
5175 if (!
N->getFlags().hasExact()) {
5178 AddToWorklist(
Mul.getNode());
5179 AddToWorklist(
Sub.getNode());
5180 CombineTo(RemNode,
Sub);
5201 if (
C->isZero() ||
C->isOpaque())
5203 if (
C->getAPIntValue().isPowerOf2())
5205 if (
C->getAPIntValue().isNegatedPowerOf2())
5216 EVT VT =
N->getValueType(0);
5241 AddToWorklist(Sign.
getNode());
5247 AddToWorklist(
Add.getNode());
5258 Sra = DAG.
getSelect(
DL, VT, IsOneOrAllOnes, N0, Sra);
5284SDValue DAGCombiner::visitUDIV(SDNode *
N) {
5287 EVT VT =
N->getValueType(0);
5297 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5311 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5314 if (
SDValue V = visitUDIVLike(N0, N1,
N)) {
5321 if (!
N->getFlags().hasExact()) {
5324 AddToWorklist(
Mul.getNode());
5325 AddToWorklist(
Sub.getNode());
5326 CombineTo(RemNode,
Sub);
5351 EVT VT =
N->getValueType(0);
5356 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5357 AddToWorklist(LogBase2.getNode());
5361 AddToWorklist(Trunc.
getNode());
5371 if (
SDValue LogBase2 = BuildLogBase2(N10,
DL)) {
5372 AddToWorklist(LogBase2.getNode());
5376 AddToWorklist(Trunc.
getNode());
5378 AddToWorklist(
Add.getNode());
5406SDValue DAGCombiner::visitREM(SDNode *
N) {
5407 unsigned Opcode =
N->getOpcode();
5410 EVT VT =
N->getValueType(0);
5432 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5445 AddToWorklist(
Add.getNode());
5456 AddToWorklist(
Add.getNode());
5473 if (
SDValue OptimizedRem = buildOptimizedSREM(N0, N1,
N))
5474 return OptimizedRem;
5478 isSigned ? visitSDIVLike(N0, N1,
N) : visitUDIVLike(N0, N1,
N);
5481 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
5482 if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
5484 CombineTo(DivNode, OptimizedDiv);
5487 AddToWorklist(OptimizedDiv.
getNode());
5488 AddToWorklist(
Mul.getNode());
5495 return DivRem.getValue(1);
5518SDValue DAGCombiner::visitMULHS(SDNode *
N) {
5521 EVT VT =
N->getValueType(0);
5534 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5577SDValue DAGCombiner::visitMULHU(SDNode *
N) {
5580 EVT VT =
N->getValueType(0);
5593 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5618 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5633 unsigned SimpleSize =
Simple.getSizeInBits();
5654SDValue DAGCombiner::visitAVG(SDNode *
N) {
5655 unsigned Opcode =
N->getOpcode();
5658 EVT VT =
N->getValueType(0);
5669 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5672 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5698 X.getValueType() ==
Y.getValueType() &&
5699 hasOperation(Opcode,
X.getValueType())) {
5705 X.getValueType() ==
Y.getValueType() &&
5706 hasOperation(Opcode,
X.getValueType())) {
5739 if (IsSigned &&
Add->getFlags().hasNoSignedWrap())
5742 if (!IsSigned &&
Add->getFlags().hasNoUnsignedWrap())
5756SDValue DAGCombiner::visitABD(SDNode *
N) {
5757 unsigned Opcode =
N->getOpcode();
5760 EVT VT =
N->getValueType(0);
5770 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5773 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5788 (!LegalOperations || hasOperation(
ISD::ABS, VT)))
5803 EVT SmallVT =
X.getScalarValueSizeInBits() >
Y.getScalarValueSizeInBits()
5806 if (!LegalOperations || hasOperation(Opcode, SmallVT)) {
5821SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
5824 bool HiExists =
N->hasAnyUseOfValue(1);
5825 if (!HiExists && (!LegalOperations ||
5828 return CombineTo(
N, Res, Res);
5832 bool LoExists =
N->hasAnyUseOfValue(0);
5833 if (!LoExists && (!LegalOperations ||
5836 return CombineTo(
N, Res, Res);
5840 if (LoExists && HiExists)
5846 AddToWorklist(
Lo.getNode());
5849 (!LegalOperations ||
5851 return CombineTo(
N, LoOpt, LoOpt);
5856 AddToWorklist(
Hi.getNode());
5859 (!LegalOperations ||
5861 return CombineTo(
N, HiOpt, HiOpt);
5867SDValue DAGCombiner::visitSMUL_LOHI(SDNode *
N) {
5873 EVT VT =
N->getValueType(0);
5889 unsigned SimpleSize =
Simple.getSizeInBits();
5901 return CombineTo(
N,
Lo,
Hi);
5908SDValue DAGCombiner::visitUMUL_LOHI(SDNode *
N) {
5914 EVT VT =
N->getValueType(0);
5929 return CombineTo(
N, Zero, Zero);
5935 return CombineTo(
N, N0, Zero);
5942 unsigned SimpleSize =
Simple.getSizeInBits();
5954 return CombineTo(
N,
Lo,
Hi);
5961SDValue DAGCombiner::visitMULO(SDNode *
N) {
5967 EVT CarryVT =
N->getValueType(1);
5988 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
6000 N->getVTList(), N0, N0);
6007 return CombineTo(
N,
And, Cmp);
6045 unsigned Opcode0 = isSignedMinMax(N0, N1, N2, N3, CC);
6099 unsigned Opcode1 = isSignedMinMax(N00, N01, N02, N03, N0CC);
6100 if (!Opcode1 || Opcode0 == Opcode1)
6110 APInt MinCPlus1 = MinC + 1;
6111 if (-MaxC == MinCPlus1 && MinCPlus1.
isPowerOf2()) {
6117 if (MaxC == 0 && MinC != 0 && MinCPlus1.
isPowerOf2()) {
6166 unsigned BW = (C1 + 1).exactLogBase2();
6180SDValue DAGCombiner::visitIMINMAX(SDNode *
N) {
6184 unsigned Opcode =
N->getOpcode();
6200 return C0 > C1 ? N0 : N1;
6202 return C0 > C1 ? N1 : N0;
6208 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
6212 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
6216 if (
SDValue RMINMAX = reassociateOps(Opcode,
DL, N0, N1,
N->getFlags()))
6236 return DAG.
getNode(AltOpcode,
DL, VT, N0, N1);
6248 auto ReductionOpcode = [](
unsigned Opcode) {
6262 if (
SDValue SD = reassociateReduction(ReductionOpcode(Opcode), Opcode,
6263 SDLoc(
N), VT, N0, N1))
6275SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *
N) {
6278 unsigned LogicOpcode =
N->getOpcode();
6303 if (XVT !=
Y.getValueType())
6307 if ((VT.
isVector() || LegalOperations) &&
6317 SDNodeFlags LogicFlags;
6323 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6333 if (XVT !=
Y.getValueType())
6345 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6366 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6381 return DAG.
getNode(HandOpcode,
DL, VT, Logic0, Logic1, S);
6394 if (XVT.
isInteger() && XVT ==
Y.getValueType() &&
6398 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6417 assert(
X.getValueType() ==
Y.getValueType() &&
6418 "Inputs to shuffles are not the same type");
6424 if (!SVN0->hasOneUse() || !SVN1->hasOneUse() ||
6425 !SVN0->getMask().equals(SVN1->getMask()))
6461 SDValue LL, LR, RL, RR, N0CC, N1CC;
6462 if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
6463 !isSetCCEquivalent(N1, RL, RR, N1CC))
6467 "Unexpected operand types for bitwise logic op");
6470 "Unexpected operand types for setcc");
6486 if (LR == RR && CC0 == CC1 && IsInteger) {
6491 bool AndEqZero = IsAnd && CC1 ==
ISD::SETEQ && IsZero;
6493 bool AndGtNeg1 = IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6495 bool OrNeZero = !IsAnd && CC1 ==
ISD::SETNE && IsZero;
6497 bool OrLtZero = !IsAnd && CC1 ==
ISD::SETLT && IsZero;
6503 if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
6505 AddToWorklist(
Or.getNode());
6510 bool AndEqNeg1 = IsAnd && CC1 ==
ISD::SETEQ && IsNeg1;
6512 bool AndLtZero = IsAnd && CC1 ==
ISD::SETLT && IsZero;
6514 bool OrNeNeg1 = !IsAnd && CC1 ==
ISD::SETNE && IsNeg1;
6516 bool OrGtNeg1 = !IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6522 if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
6524 AddToWorklist(
And.getNode());
6538 AddToWorklist(
Add.getNode());
6559 auto MatchDiffPow2 = [&](ConstantSDNode *C0, ConstantSDNode *C1) {
6565 return !C0->
isOpaque() && !C1->isOpaque() && (CMax - CMin).isPowerOf2();
6583 if (LL == RR && LR == RL) {
6590 if (LL == RL && LR == RR) {
6594 (!LegalOperations ||
6631 SelectionDAG &DAG,
bool isFMAXNUMFMINNUM_IEEE,
bool isFMAXNUMFMINNUM) {
6642 isFMAXNUMFMINNUM_IEEE
6650 isFMAXNUMFMINNUM_IEEE
6668 isFMAXNUMFMINNUM_IEEE
6677 isFMAXNUMFMINNUM_IEEE
6688 (LogicOp->getOpcode() ==
ISD::AND || LogicOp->getOpcode() ==
ISD::OR) &&
6689 "Invalid Op to combine SETCC with");
6695 !
LHS->hasOneUse() || !
RHS->hasOneUse())
6700 LogicOp,
LHS.getNode(),
RHS.getNode());
6712 EVT VT = LogicOp->getValueType(0);
6735 (isFMAXNUMFMINNUM_IEEE || isFMAXNUMFMINNUM))) &&
6741 SDValue CommonValue, Operand1, Operand2;
6749 }
else if (LHS1 == RHS1) {
6762 }
else if (RHS0 == LHS1) {
6779 bool IsSigned = isSignedIntSetCC(CC);
6783 bool IsOr = (LogicOp->getOpcode() ==
ISD::OR);
6790 Operand1, Operand2, CC, LogicOp->
getOpcode(), DAG,
6791 isFMAXNUMFMINNUM_IEEE, isFMAXNUMFMINNUM);
6795 DAG.
getNode(NewOpcode,
DL, OpVT, Operand1, Operand2);
6796 return DAG.
getSetCC(
DL, VT, MinMaxValue, CommonValue, CC);
6801 if (LHS0 == LHS1 && RHS0 == RHS1 && CCL == CCR &&
6805 return DAG.
getSetCC(
DL, VT, LHS0, RHS0, CCL);
6812 LHS0 == RHS0 && LHS1C && RHS1C && OpVT.
isInteger()) {
6813 const APInt &APLhs = LHS1C->getAPIntValue();
6814 const APInt &APRhs = RHS1C->getAPIntValue();
6818 if (APLhs == (-APRhs) &&
6829 }
else if (TargetPreference &
6850 APInt Dif = MaxC - MinC;
6884 EVT CondVT =
Cond.getValueType();
6895 EVT OpVT =
T.getValueType();
6914 if (
SDValue V = foldLogicOfSetCCs(
true, N0, N1,
DL))
6931 APInt
ADDC = ADDI->getAPIntValue();
6932 APInt SRLC = SRLI->getAPIntValue();
6944 CombineTo(N0.
getNode(), NewAdd);
6957bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
6958 EVT LoadResultTy, EVT &ExtVT) {
6967 if (ExtVT == LoadedVT &&
6968 (!LegalOperations ||
6984 if (LegalOperations &&
6994bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
7003 const unsigned ByteShAmt = ShAmt / 8;
7022 if (LdStMemVT.
bitsLT(MemVT))
7037 if (PtrType == MVT::Untyped || PtrType.
isExtended())
7044 if (!
SDValue(Load, 0).hasOneUse())
7047 if (LegalOperations &&
7056 if (
Load->getNumValues() > 2)
7075 if (LegalOperations &&
7082bool DAGCombiner::SearchForAndLoads(SDNode *
N,
7083 SmallVectorImpl<LoadSDNode*> &Loads,
7084 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
7085 ConstantSDNode *Mask,
7086 SDNode *&NodeToMask) {
7090 if (
Op.getValueType().isVector())
7096 "Expected bitwise logic operation");
7097 if (!
C->getAPIntValue().isSubsetOf(
Mask->getAPIntValue()))
7102 if (!
Op.hasOneUse())
7105 switch(
Op.getOpcode()) {
7109 if (isAndLoadExtLoad(Mask, Load,
Load->getValueType(0), ExtVT) &&
7127 unsigned ActiveBits =
Mask->getAPIntValue().countr_one();
7131 Op.getOperand(0).getValueType();
7142 if (!SearchForAndLoads(
Op.getNode(), Loads, NodesWithConsts, Mask,
7153 NodeToMask =
Op.getNode();
7156 for (
unsigned i = 0, e = NodeToMask->
getNumValues(); i < e; ++i) {
7157 MVT VT =
SDValue(NodeToMask, i).getSimpleValueType();
7158 if (VT != MVT::Glue && VT != MVT::Other) {
7160 NodeToMask =
nullptr;
7172bool DAGCombiner::BackwardsPropagateMask(SDNode *
N) {
7177 if (!
Mask->getAPIntValue().isMask())
7185 SmallPtrSet<SDNode*, 2> NodesWithConsts;
7186 SDNode *FixupNode =
nullptr;
7187 if (SearchForAndLoads(
N, Loads, NodesWithConsts, Mask, FixupNode)) {
7200 SDValue(FixupNode, 0), MaskOp);
7202 if (
And.getOpcode() == ISD ::AND)
7207 for (
auto *LogicN : NodesWithConsts) {
7213 if (LogicN->getOpcode() ==
ISD::AND &&
7232 for (
auto *Load : Loads) {
7237 if (
And.getOpcode() == ISD ::AND)
7240 SDValue NewLoad = reduceLoadWidth(
And.getNode());
7242 "Shouldn't be masking the load if it can't be narrowed");
7243 CombineTo(Load, NewLoad, NewLoad.
getValue(1));
7256SDValue DAGCombiner::unfoldExtremeBitClearingToShifts(SDNode *
N) {
7267 unsigned OuterShift;
7268 unsigned InnerShift;
7270 auto matchMask = [&OuterShift, &InnerShift, &
Y](
SDValue M) ->
bool {
7273 OuterShift =
M->getOpcode();
7282 Y =
M->getOperand(1);
7289 else if (matchMask(N0))
7295 EVT VT =
N->getValueType(0);
7312 SDValue And0 =
And->getOperand(0), And1 =
And->getOperand(1);
7322 bool FoundNot =
false;
7325 Src = Src.getOperand(0);
7331 Src = Src.getOperand(0);
7335 if (Src.getOpcode() !=
ISD::SRL || !Src.hasOneUse())
7339 EVT SrcVT = Src.getValueType();
7348 if (!ShiftAmtC || !ShiftAmtC->getAPIntValue().ult(
BitWidth))
7352 Src = Src.getOperand(0);
7359 Src = Src.getOperand(0);
7383 EVT VT =
N->getValueType(0);
7409 unsigned LogicOpcode =
N->getOpcode();
7411 "Expected bitwise logic operation");
7413 if (!LogicOp.hasOneUse() || !ShiftOp.
hasOneUse())
7417 unsigned ShiftOpcode = ShiftOp.
getOpcode();
7418 if (LogicOp.getOpcode() != LogicOpcode ||
7430 if (LogicOp.getOperand(0).getOpcode() == ShiftOpcode &&
7431 LogicOp.getOperand(0).getOperand(1) ==
Y) {
7433 Z = LogicOp.getOperand(1);
7434 }
else if (LogicOp.getOperand(1).getOpcode() == ShiftOpcode &&
7435 LogicOp.getOperand(1).getOperand(1) ==
Y) {
7437 Z = LogicOp.getOperand(0);
7442 EVT VT =
N->getValueType(0);
7446 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift, Z);
7457 unsigned LogicOpcode =
N->getOpcode();
7459 "Expected bitwise logic operation");
7460 if (LeftHand.
getOpcode() != LogicOpcode ||
7481 EVT VT =
N->getValueType(0);
7483 return DAG.
getNode(LogicOpcode,
DL, VT, CombinedShifts, W);
7495 "Must be called with ISD::OR or ISD::AND node");
7509 EVT VT = M.getValueType();
7517SDValue DAGCombiner::visitAND(SDNode *
N) {
7541 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
7559 EVT MemVT =
MLoad->getMemoryVT();
7569 MLoad->isExpandingLoad());
7570 CombineTo(
N, Frozen ? N0 : NewLoad);
7571 CombineTo(MLoad, NewLoad, NewLoad.
getValue(1));
7591 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
7604 auto MatchSubset = [](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
7605 return RHS->getAPIntValue().isSubsetOf(
LHS->getAPIntValue());
7615 APInt
Mask = ~N1C->getAPIntValue();
7640 {N0Op0.getOperand(1)})) {
7673 unsigned EltBitWidth =
Vector->getValueType(0).getScalarSizeInBits();
7674 APInt SplatValue, SplatUndef;
7675 unsigned SplatBitSize;
7682 const bool IsBigEndian =
false;
7684 Vector->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
7685 HasAnyUndefs, EltBitWidth, IsBigEndian);
7689 if (IsSplat && (SplatBitSize % EltBitWidth) == 0) {
7692 SplatValue |= SplatUndef;
7699 for (
unsigned i = 0, n = (SplatBitSize / EltBitWidth); i < n; ++i)
7700 Constant &= SplatValue.
extractBits(EltBitWidth, i * EltBitWidth);
7708 Load->getValueType(0),
7709 Load->getMemoryVT());
7717 switch (
Load->getExtensionType()) {
7718 default:
B =
false;
break;
7730 CombineTo(
N, (N0.
getNode() == Load) ? NewLoad : N0);
7734 Load->getValueType(0), SDLoc(Load),
7735 Load->getChain(),
Load->getBasePtr(),
7736 Load->getOffset(),
Load->getMemoryVT(),
7737 Load->getMemOperand());
7739 if (
Load->getNumValues() == 3) {
7741 SDValue To[] = { NewLoad.getValue(0), NewLoad.getValue(1),
7742 NewLoad.getValue(2) };
7743 CombineTo(Load, To, 3,
true);
7745 CombineTo(Load, NewLoad.getValue(0), NewLoad.getValue(1));
7755 if (
SDValue Shuffle = XformToShuffleWithZero(
N))
7782 EVT MemVT = GN0->getMemoryVT();
7785 if (
SDValue(GN0, 0).hasOneUse() &&
7788 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
7789 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
7792 DAG.
getVTList(VT, MVT::Other), MemVT,
DL,
Ops, GN0->getMemOperand(),
7795 CombineTo(
N, ZExtLoad);
7796 AddToWorklist(ZExtLoad.
getNode());
7805 if (
SDValue Res = reduceLoadWidth(
N))
7813 if (BackwardsPropagateMask(
N))
7817 if (
SDValue Combined = visitANDLike(N0, N1,
N))
7822 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
7853 if (
SDValue Folded = foldBitwiseOpWithNeg(
N,
DL, VT))
7875 X.getOperand(0).getScalarValueSizeInBits() == 1)
7878 X.getOperand(0).getScalarValueSizeInBits() == 1)
7893 EVT MemVT = LN0->getMemoryVT();
7900 ((!LegalOperations && LN0->isSimple()) ||
7904 LN0->getBasePtr(), MemVT, LN0->getMemOperand());
7918 if (
SDValue Shifts = unfoldExtremeBitClearingToShifts(
N))
7938 if (!
C->getAPIntValue().isMask(
7939 LHS.getOperand(0).getValueType().getFixedSizeInBits()))
7946 if (IsAndZeroExtMask(N0, N1))
7955 if (LegalOperations || VT.
isVector())
7968 bool DemandHighBits) {
7969 if (!LegalOperations)
7972 EVT VT =
N->getValueType(0);
7973 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16)
7979 bool LookPassAnd0 =
false;
7980 bool LookPassAnd1 =
false;
7995 LookPassAnd0 =
true;
8005 LookPassAnd1 =
true;
8031 LookPassAnd0 =
true;
8045 LookPassAnd1 =
true;
8054 if (OpSizeInBits > 16) {
8058 if (DemandHighBits && !LookPassAnd0)
8065 if (!LookPassAnd1) {
8066 unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
8074 if (OpSizeInBits > 16) {
8089 if (!
N->hasOneUse())
8092 unsigned Opc =
N.getOpcode();
8110 unsigned MaskByteOffset;
8114 case 0xFF: MaskByteOffset = 0;
break;
8115 case 0xFF00: MaskByteOffset = 1;
break;
8124 case 0xFF0000: MaskByteOffset = 2;
break;
8125 case 0xFF000000: MaskByteOffset = 3;
break;
8130 if (MaskByteOffset == 0 || MaskByteOffset == 2) {
8136 if (!
C ||
C->getZExtValue() != 8)
8144 if (!
C ||
C->getZExtValue() != 8)
8150 if (MaskByteOffset != 0 && MaskByteOffset != 2)
8153 if (!
C ||
C->getZExtValue() != 8)
8158 if (MaskByteOffset != 1 && MaskByteOffset != 3)
8161 if (!
C ||
C->getZExtValue() != 8)
8165 if (Parts[MaskByteOffset])
8180 if (!
C ||
C->getAPIntValue() != 16)
8182 Parts[0] = Parts[1] =
N.getOperand(0).getOperand(0).getNode();
8197 "MatchBSwapHWordOrAndAnd: expecting i32");
8207 if (!Mask0 || !Mask1)
8218 if (!ShiftAmt0 || !ShiftAmt1)
8238 if (!LegalOperations)
8241 EVT VT =
N->getValueType(0);
8259 SDNode *Parts[4] = {};
8279 if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
8307 if (
SDValue V = foldLogicOfSetCCs(
false, N0, N1,
DL))
8316 if (
const ConstantSDNode *N0O1C =
8318 if (
const ConstantSDNode *N1O1C =
8322 const APInt &LHSMask = N0O1C->getAPIntValue();
8323 const APInt &RHSMask = N1O1C->getAPIntValue();
8357 auto peekThroughResize = [](
SDValue V) {
8359 return V->getOperand(0);
8363 SDValue N0Resized = peekThroughResize(N0);
8365 SDValue N1Resized = peekThroughResize(N1);
8370 if (N00 == N1Resized || N01 == N1Resized)
8377 if (peekThroughResize(NotOperand) == N1Resized)
8385 if (peekThroughResize(NotOperand) == N1Resized)
8406 auto peekThroughZext = [](
SDValue V) {
8408 return V->getOperand(0);
8430 Lo.getScalarValueSizeInBits() == (BW / 2) &&
8431 Lo.getValueType() ==
Hi.getValueType()) {
8447SDValue DAGCombiner::visitOR(SDNode *
N) {
8468 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
8490 if ((ZeroN00 != ZeroN01) && (ZeroN10 != ZeroN11)) {
8491 assert((!ZeroN00 || !ZeroN01) &&
"Both inputs zero!");
8492 assert((!ZeroN10 || !ZeroN11) &&
"Both inputs zero!");
8493 bool CanFold =
true;
8495 SmallVector<int, 4>
Mask(NumElts, -1);
8497 for (
int i = 0; i != NumElts; ++i) {
8498 int M0 = SV0->getMaskElt(i);
8499 int M1 = SV1->getMaskElt(i);
8502 bool M0Zero =
M0 < 0 || (ZeroN00 == (
M0 < NumElts));
8503 bool M1Zero =
M1 < 0 || (ZeroN10 == (
M1 < NumElts));
8507 if ((M0Zero &&
M1 < 0) || (M1Zero &&
M0 < 0))
8511 if (M0Zero == M1Zero) {
8516 assert((
M0 >= 0 ||
M1 >= 0) &&
"Undef index!");
8522 Mask[i] = M1Zero ?
M0 % NumElts : (
M1 % NumElts) + NumElts;
8531 return LegalShuffle;
8545 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
8556 if (
SDValue Combined = visitORLike(N0, N1,
DL))
8563 if (
SDValue BSwap = MatchBSwapHWord(
N, N0, N1))
8565 if (
SDValue BSwap = MatchBSwapHWordLow(
N, N0, N1))
8579 auto MatchIntersect = [](ConstantSDNode *C1, ConstantSDNode *C2) {
8599 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
8603 if (
SDValue Rot = MatchRotate(N0, N1,
DL,
false))
8606 if (
SDValue Load = MatchLoadCombine(
N))
8616 if (
SDValue Combined = visitADDLike(
N))
8621 if (LegalOperations || VT.
isVector())
8636 Mask =
Op.getOperand(1);
8637 return Op.getOperand(0);
8680 assert(OppShift && ExtractFrom &&
"Empty SDValue");
8708 bool IsMulOrDiv =
false;
8711 auto SelectOpcode = [&](
unsigned NeededShift,
unsigned MulOrDivVariant) {
8712 IsMulOrDiv = ExtractFrom.
getOpcode() == MulOrDivVariant;
8713 if (!IsMulOrDiv && ExtractFrom.
getOpcode() != NeededShift)
8715 Opcode = NeededShift;
8765 if (Rem != 0 || ResultAmt != OppLHSAmt)
8771 if (OppLHSAmt != ExtractFromAmt - NeededShiftAmt.
zextOrTrunc(
8780 return DAG.
getNode(Opcode,
DL, ResVT, OppShiftLHS, NewShiftNode);
8834 unsigned MaskLoBits = 0;
8836 unsigned Bits =
Log2_64(EltSize);
8838 if (NegBits >= Bits) {
8861 if (PosBits >= MaskLoBits) {
8883 if ((Pos == NegOp1) ||
8907 return Width.
getLoBits(MaskLoBits) == 0;
8908 return Width == EltSize;
8918 SDValue InnerNeg,
bool FromAdd,
8919 bool HasPos,
unsigned PosOpcode,
8920 unsigned NegOpcode,
const SDLoc &
DL) {
8931 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, Shifted,
8932 HasPos ? Pos : Neg);
8945 SDValue InnerNeg,
bool FromAdd,
8946 bool HasPos,
unsigned PosOpcode,
8947 unsigned NegOpcode,
const SDLoc &
DL) {
8960 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, N0, N1,
8961 HasPos ? Pos : Neg);
9006 EVT VT =
LHS.getValueType();
9011 bool HasROTL = hasOperation(
ISD::ROTL, VT);
9012 bool HasROTR = hasOperation(
ISD::ROTR, VT);
9013 bool HasFSHL = hasOperation(
ISD::FSHL, VT);
9014 bool HasFSHR = hasOperation(
ISD::FSHR, VT);
9025 if (LegalOperations && !HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9030 LHS.getOperand(0).getValueType() ==
RHS.getOperand(0).getValueType()) {
9033 MatchRotate(
LHS.getOperand(0),
RHS.getOperand(0),
DL, FromAdd))
9047 if (!LHSShift && !RHSShift)
9062 RHSShift = NewRHSShift;
9067 LHSShift = NewLHSShift;
9070 if (!RHSShift || !LHSShift)
9095 auto MatchRotateSum = [EltSizeInBits](ConstantSDNode *
LHS,
9096 ConstantSDNode *
RHS) {
9097 return (
LHS->getAPIntValue() +
RHS->getAPIntValue()) == EltSizeInBits;
9100 auto ApplyMasks = [&](
SDValue Res) {
9124 bool IsRotate = LHSShiftArg == RHSShiftArg;
9125 if (!IsRotate && !(HasFSHL || HasFSHR)) {
9134 if (CommonOp ==
Or.getOperand(0)) {
9136 Y =
Or.getOperand(1);
9139 if (CommonOp ==
Or.getOperand(1)) {
9141 Y =
Or.getOperand(0);
9148 if (matchOr(LHSShiftArg, RHSShiftArg)) {
9153 }
else if (matchOr(RHSShiftArg, LHSShiftArg)) {
9162 return ApplyMasks(Res);
9175 if (IsRotate && (HasROTL || HasROTR || !(HasFSHL || HasFSHR))) {
9176 bool UseROTL = !LegalOperations || HasROTL;
9178 UseROTL ? LHSShiftAmt : RHSShiftAmt);
9180 bool UseFSHL = !LegalOperations || HasFSHL;
9182 RHSShiftArg, UseFSHL ? LHSShiftAmt : RHSShiftAmt);
9185 return ApplyMasks(Res);
9190 if (!HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9199 SDValue LExtOp0 = LHSShiftAmt;
9200 SDValue RExtOp0 = RHSShiftAmt;
9213 if (IsRotate && (HasROTL || HasROTR)) {
9214 if (
SDValue TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
9215 LExtOp0, RExtOp0, FromAdd, HasROTL,
9219 if (
SDValue TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
9220 RExtOp0, LExtOp0, FromAdd, HasROTR,
9225 if (
SDValue TryL = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt,
9226 RHSShiftAmt, LExtOp0, RExtOp0, FromAdd,
9230 if (
SDValue TryR = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt,
9231 LHSShiftAmt, RExtOp0, LExtOp0, FromAdd,
9281static std::optional<SDByteProvider>
9283 std::optional<uint64_t> VectorIndex,
9284 unsigned StartingIndex = 0) {
9288 return std::nullopt;
9292 if (
Depth && !
Op.hasOneUse() &&
9293 (
Op.getOpcode() !=
ISD::LOAD || !
Op.getValueType().isVector()))
9294 return std::nullopt;
9298 if (
Op.getOpcode() !=
ISD::LOAD && VectorIndex.has_value())
9299 return std::nullopt;
9301 unsigned BitWidth =
Op.getScalarValueSizeInBits();
9303 return std::nullopt;
9305 assert(Index < ByteWidth &&
"invalid index requested");
9308 switch (
Op.getOpcode()) {
9313 return std::nullopt;
9317 return std::nullopt;
9319 if (
LHS->isConstantZero())
9321 if (
RHS->isConstantZero())
9323 return std::nullopt;
9328 return std::nullopt;
9330 uint64_t BitShift = ShiftOp->getZExtValue();
9332 if (BitShift % 8 != 0)
9333 return std::nullopt;
9339 return Index < ByteShift
9342 Depth + 1, VectorIndex, Index);
9349 if (NarrowBitWidth % 8 != 0)
9350 return std::nullopt;
9351 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9353 if (Index >= NarrowByteWidth)
9355 ? std::optional<SDByteProvider>(
9363 Depth + 1, VectorIndex, StartingIndex);
9367 return std::nullopt;
9369 VectorIndex =
OffsetOp->getZExtValue();
9373 if (NarrowBitWidth % 8 != 0)
9374 return std::nullopt;
9375 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9378 if (Index >= NarrowByteWidth)
9379 return std::nullopt;
9387 if (*VectorIndex * NarrowByteWidth > StartingIndex)
9388 return std::nullopt;
9389 if ((*VectorIndex + 1) * NarrowByteWidth <= StartingIndex)
9390 return std::nullopt;
9393 VectorIndex, StartingIndex);
9397 if (!L->isSimple() || L->isIndexed())
9398 return std::nullopt;
9400 unsigned NarrowBitWidth = L->getMemoryVT().getScalarSizeInBits();
9401 if (NarrowBitWidth % 8 != 0)
9402 return std::nullopt;
9403 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9408 if (Index >= NarrowByteWidth)
9410 ? std::optional<SDByteProvider>(
9414 unsigned BPVectorIndex = VectorIndex.value_or(0U);
9419 return std::nullopt;
9434 int64_t FirstOffset) {
9436 unsigned Width = ByteOffsets.
size();
9438 return std::nullopt;
9440 bool BigEndian =
true, LittleEndian =
true;
9441 for (
unsigned i = 0; i < Width; i++) {
9442 int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
9445 if (!BigEndian && !LittleEndian)
9446 return std::nullopt;
9449 assert((BigEndian != LittleEndian) &&
"It should be either big endian or"
9456 switch (
Value.getOpcode()) {
9461 return Value.getOperand(0);
9488SDValue DAGCombiner::mergeTruncStores(StoreSDNode *
N) {
9499 EVT MemVT =
N->getMemoryVT();
9500 if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
9501 !
N->isSimple() ||
N->isIndexed())
9508 unsigned MaxWideNumBits = 64;
9509 unsigned MaxStores = MaxWideNumBits / NarrowNumBits;
9518 if (
Store->getMemoryVT() != MemVT || !
Store->isSimple() ||
9522 Chain =
Store->getChain();
9523 if (MaxStores < Stores.
size())
9527 if (Stores.
size() < 2)
9532 unsigned NumStores = Stores.
size();
9533 unsigned WideNumBits = NumStores * NarrowNumBits;
9534 if (WideNumBits != 16 && WideNumBits != 32 && WideNumBits != 64)
9542 StoreSDNode *FirstStore =
nullptr;
9543 std::optional<BaseIndexOffset>
Base;
9544 for (
auto *Store : Stores) {
9563 if (ShiftAmtC % NarrowNumBits != 0)
9570 Offset = ShiftAmtC / NarrowNumBits;
9576 SourceValue = WideVal;
9577 else if (SourceValue != WideVal) {
9585 SourceValue = WideVal;
9594 int64_t ByteOffsetFromBase = 0;
9597 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9601 if (ByteOffsetFromBase < FirstOffset) {
9603 FirstOffset = ByteOffsetFromBase;
9609 OffsetMap[
Offset] = ByteOffsetFromBase;
9615 assert(FirstStore &&
"First store must be set");
9622 if (!Allowed || !
Fast)
9627 auto checkOffsets = [&](
bool MatchLittleEndian) {
9628 if (MatchLittleEndian) {
9629 for (
unsigned i = 0; i != NumStores; ++i)
9630 if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
9633 for (
unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --
j)
9634 if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
9641 bool NeedBswap =
false;
9642 bool NeedRotate =
false;
9645 if (NarrowNumBits == 8 && checkOffsets(Layout.
isBigEndian()))
9647 else if (NumStores == 2 && checkOffsets(Layout.
isBigEndian()))
9656 "Unexpected store value to merge");
9665 }
else if (NeedRotate) {
9666 assert(WideNumBits % 2 == 0 &&
"Unexpected type for rotate");
9710SDValue DAGCombiner::MatchLoadCombine(SDNode *
N) {
9712 "Can only match load combining against OR nodes");
9715 EVT VT =
N->getValueType(0);
9716 if (VT != MVT::i16 && VT != MVT::i32 && VT != MVT::i64)
9722 assert(
P.hasSrc() &&
"Must be a memory byte provider");
9725 unsigned LoadBitWidth =
Load->getMemoryVT().getScalarSizeInBits();
9727 assert(LoadBitWidth % 8 == 0 &&
9728 "can only analyze providers for individual bytes not bit");
9729 unsigned LoadByteWidth = LoadBitWidth / 8;
9734 std::optional<BaseIndexOffset>
Base;
9737 SmallPtrSet<LoadSDNode *, 8> Loads;
9738 std::optional<SDByteProvider> FirstByteProvider;
9744 unsigned ZeroExtendedBytes = 0;
9745 for (
int i = ByteWidth - 1; i >= 0; --i) {
9752 if (
P->isConstantZero()) {
9755 if (++ZeroExtendedBytes != (ByteWidth -
static_cast<unsigned>(i)))
9759 assert(
P->hasSrc() &&
"provenance should either be memory or zero");
9766 else if (Chain != LChain)
9771 int64_t ByteOffsetFromBase = 0;
9780 if (
L->getMemoryVT().isVector()) {
9781 unsigned LoadWidthInBit =
L->getMemoryVT().getScalarSizeInBits();
9782 if (LoadWidthInBit % 8 != 0)
9784 unsigned ByteOffsetFromVector =
P->SrcOffset * LoadWidthInBit / 8;
9785 Ptr.addToOffset(ByteOffsetFromVector);
9791 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9795 ByteOffsetFromBase += MemoryByteOffset(*
P);
9796 ByteOffsets[i] = ByteOffsetFromBase;
9799 if (ByteOffsetFromBase < FirstOffset) {
9800 FirstByteProvider =
P;
9801 FirstOffset = ByteOffsetFromBase;
9807 assert(!Loads.
empty() &&
"All the bytes of the value must be loaded from "
9808 "memory, so there must be at least one load which produces the value");
9809 assert(
Base &&
"Base address of the accessed memory location must be set");
9812 bool NeedsZext = ZeroExtendedBytes > 0;
9823 if (LegalOperations &&
9831 ArrayRef(ByteOffsets).drop_back(ZeroExtendedBytes), FirstOffset);
9835 assert(FirstByteProvider &&
"must be set");
9839 if (MemoryByteOffset(*FirstByteProvider) != 0)
9848 bool NeedsBswap = IsBigEndianTarget != *IsBigEndian;
9855 if (NeedsBswap && (LegalOperations || NeedsZext) &&
9861 if (NeedsBswap && NeedsZext && LegalOperations &&
9869 *FirstLoad->getMemOperand(), &
Fast);
9870 if (!Allowed || !
Fast)
9875 Chain, FirstLoad->getBasePtr(),
9876 FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
9879 for (LoadSDNode *L : Loads)
9909SDValue DAGCombiner::unfoldMaskedMerge(SDNode *
N) {
9916 EVT VT =
N->getValueType(0);
9938 M =
And.getOperand(XorIdx ? 0 : 1);
9944 if (!matchAndXor(N0, 0, N1) && !matchAndXor(N0, 1, N1) &&
9945 !matchAndXor(N1, 0, N0) && !matchAndXor(N1, 1, N0))
9992SDValue DAGCombiner::visitXOR(SDNode *
N) {
10019 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10031 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10052 if (
SDValue Combined = visitADDLike(
N))
10060 isSetCCEquivalent(N0,
LHS,
RHS, CC,
true) &&
10062 N->use_begin()->getUser()->getOpcode() ==
ISD::AND)) {
10064 LHS.getValueType());
10065 if (!LegalOperations ||
10067 switch (N0Opcode) {
10083 CombineTo(
N, SetCC);
10085 recursivelyDeleteUnusedNodes(N0.
getNode());
10101 AddToWorklist(
V.getNode());
10110 if (isOneUseSetCC(N01) || isOneUseSetCC(N00)) {
10115 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10128 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10138 APInt NotYValue = ~YConst->getAPIntValue();
10154 AddToWorklist(NotX.
getNode());
10159 if (!LegalOperations || hasOperation(
ISD::ABS, VT)) {
10163 SDValue A0 =
A.getOperand(0), A1 =
A.getOperand(1);
10165 if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
10202 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
10213 if (
SDValue MM = unfoldMaskedMerge(
N))
10282 if (!LogicOp.hasOneUse())
10285 unsigned LogicOpcode = LogicOp.getOpcode();
10291 unsigned ShiftOpcode = Shift->
getOpcode();
10294 assert(C1Node &&
"Expected a shift with constant operand");
10297 const APInt *&ShiftAmtVal) {
10298 if (V.getOpcode() != ShiftOpcode || !V.hasOneUse())
10306 ShiftOp = V.getOperand(0);
10311 if (ShiftAmtVal->getBitWidth() != C1Val.
getBitWidth())
10316 bool Overflow =
false;
10317 APInt NewShiftAmt = C1Val.
uadd_ov(*ShiftAmtVal, Overflow);
10322 if (NewShiftAmt.
uge(V.getScalarValueSizeInBits()))
10330 const APInt *C0Val;
10331 if (matchFirstShift(LogicOp.getOperand(0),
X, C0Val))
10332 Y = LogicOp.getOperand(1);
10333 else if (matchFirstShift(LogicOp.getOperand(1),
X, C0Val))
10334 Y = LogicOp.getOperand(0);
10345 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift1, NewShift2,
10355SDValue DAGCombiner::visitShiftByConstant(SDNode *
N) {
10375 switch (
LHS.getOpcode()) {
10399 if (!IsShiftByConstant && !IsCopyOrSelect)
10402 if (IsCopyOrSelect &&
N->hasOneUse())
10407 EVT VT =
N->getValueType(0);
10409 N->getOpcode(),
DL, VT, {LHS.getOperand(1), N->getOperand(1)})) {
10412 return DAG.
getNode(
LHS.getOpcode(),
DL, VT, NewShift, NewRHS);
10418SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *
N) {
10423 EVT TruncVT =
N->getValueType(0);
10424 if (
N->hasOneUse() &&
N->getOperand(0).hasOneUse() &&
10432 AddToWorklist(Trunc00.
getNode());
10433 AddToWorklist(Trunc01.
getNode());
10441SDValue DAGCombiner::visitRotate(SDNode *
N) {
10445 EVT VT =
N->getValueType(0);
10460 bool OutOfRange =
false;
10461 auto MatchOutOfRange = [Bitsize, &OutOfRange](ConstantSDNode *
C) {
10462 OutOfRange |=
C->getAPIntValue().uge(Bitsize);
10470 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, Amt);
10475 if (RotAmtC && RotAmtC->getAPIntValue() == 8 &&
10486 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10487 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, NewOp1);
10499 bool SameSide = (
N->getOpcode() == NextOp);
10506 if (Norm1 && Norm2)
10508 CombineOp, dl, ShiftVT, {Norm1, Norm2})) {
10510 {CombinedShift, BitsizeC});
10512 ISD::UREM, dl, ShiftVT, {CombinedShift, BitsizeC});
10514 CombinedShiftNorm);
10521SDValue DAGCombiner::visitSHL(SDNode *
N) {
10538 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10561 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10571 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10577 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
10578 ConstantSDNode *
RHS) {
10579 APInt c1 =
LHS->getAPIntValue();
10580 APInt c2 =
RHS->getAPIntValue();
10582 return (c1 + c2).uge(OpSizeInBits);
10587 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
10588 ConstantSDNode *
RHS) {
10589 APInt c1 =
LHS->getAPIntValue();
10590 APInt c2 =
RHS->getAPIntValue();
10592 return (c1 + c2).ult(OpSizeInBits);
10614 auto MatchOutOfRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10615 ConstantSDNode *
RHS) {
10616 APInt c1 =
LHS->getAPIntValue();
10617 APInt c2 =
RHS->getAPIntValue();
10619 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10620 (c1 + c2).uge(OpSizeInBits);
10627 auto MatchInRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10628 ConstantSDNode *
RHS) {
10629 APInt c1 =
LHS->getAPIntValue();
10630 APInt c2 =
RHS->getAPIntValue();
10632 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10633 (c1 + c2).ult(OpSizeInBits);
10653 auto MatchEqual = [VT](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
10654 APInt c1 =
LHS->getAPIntValue();
10655 APInt c2 =
RHS->getAPIntValue();
10665 AddToWorklist(NewSHL.
getNode());
10671 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
10672 ConstantSDNode *
RHS) {
10673 const APInt &LHSC =
LHS->getAPIntValue();
10674 const APInt &RHSC =
RHS->getAPIntValue();
10675 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
10747 AddToWorklist(Shl0.
getNode());
10766 {Add.getOperand(1)})) {
10786 if (
SDValue NewSHL = visitShiftByConstant(
N))
10820 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap() &&
10833 APInt NewStep = C0 << ShlVal;
10848 "SRL or SRA node is required here!");
10857 SDValue ShiftOperand =
N->getOperand(0);
10868 if (!IsSignExt && !IsZeroExt)
10875 auto UserOfLowerBits = [NarrowVTSize](
SDNode *U) {
10880 if (!UShiftAmtSrc) {
10884 return UShiftAmt < NarrowVTSize;
10898 unsigned ActiveBits = IsSignExt
10899 ?
Constant->getAPIntValue().getSignificantBits()
10900 :
Constant->getAPIntValue().getActiveBits();
10901 if (ActiveBits > NarrowVTSize)
10918 "Cannot have a multiply node with two different operand types.");
10929 if (ShiftAmt != NarrowVTSize)
10939 EVT TransformVT = NarrowVT;
10950 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
10957 unsigned Opcode =
N->getOpcode();
10962 EVT VT =
N->getValueType(0);
10981SDValue DAGCombiner::visitSRA(SDNode *
N) {
11003 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11006 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11018 auto SumOfShifts = [&](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
11019 APInt c1 =
LHS->getAPIntValue();
11020 APInt c2 =
RHS->getAPIntValue();
11022 APInt Sum = c1 + c2;
11023 unsigned ShiftSum =
11024 Sum.
uge(OpSizeInBits) ? (OpSizeInBits - 1) : Sum.getZExtValue();
11034 "Expected matchBinaryPredicate to return one element for "
11038 ShiftValue = ShiftValues[0];
11052 APInt Sum = C1 + C2;
11056 return DAG.
getNOT(
DL, NewShift, VT);
11080 if ((ShiftAmt > 0) &&
11090 N->getValueType(0), Trunc);
11107 if (ConstantSDNode *AddC =
11124 DAG.
getConstant(AddC->getAPIntValue().lshr(ShiftAmt).trunc(
11141 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11158 if (LargeShift->getAPIntValue() == TruncBits) {
11179 if (
SDValue NewSRA = visitShiftByConstant(
N))
11188 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11197SDValue DAGCombiner::visitSRL(SDNode *
N) {
11214 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11217 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11228 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
11229 ConstantSDNode *
RHS) {
11230 APInt c1 =
LHS->getAPIntValue();
11231 APInt c2 =
RHS->getAPIntValue();
11233 return (c1 + c2).uge(OpSizeInBits);
11238 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
11239 ConstantSDNode *
RHS) {
11240 APInt c1 =
LHS->getAPIntValue();
11241 APInt c2 =
RHS->getAPIntValue();
11243 return (c1 + c2).ult(OpSizeInBits);
11263 if (c1 + OpSizeInBits == InnerShiftSize) {
11264 if (c1 + c2 >= InnerShiftSize)
11274 c1 + c2 < InnerShiftSize) {
11279 OpSizeInBits - c2),
11296 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
11297 ConstantSDNode *
RHS) {
11298 const APInt &LHSC =
LHS->getAPIntValue();
11299 const APInt &RHSC =
RHS->getAPIntValue();
11300 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
11342 AddToWorklist(SmallShift.
getNode());
11370 APInt UnknownBits = ~Known.Zero;
11371 if (UnknownBits == 0)
return DAG.
getConstant(1, SDLoc(N0), VT);
11386 AddToWorklist(
Op.getNode());
11395 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11421 if (
SDValue NewSRL = visitShiftByConstant(
N))
11425 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11452 if (
N->hasOneUse()) {
11453 SDNode *
User = *
N->user_begin();
11461 AddToWorklist(User);
11477 X.getScalarValueSizeInBits() == HalfBW &&
11478 Y.getScalarValueSizeInBits() == HalfBW) {
11500SDValue DAGCombiner::visitFunnelShift(SDNode *
N) {
11501 EVT VT =
N->getValueType(0);
11519 return IsFSHL ? N0 : N1;
11521 auto IsUndefOrZero = [](
SDValue V) {
11530 if (Cst->getAPIntValue().uge(
BitWidth)) {
11531 uint64_t RotAmt = Cst->getAPIntValue().urem(
BitWidth);
11532 return DAG.
getNode(
N->getOpcode(),
DL, VT, N0, N1,
11536 unsigned ShAmt = Cst->getZExtValue();
11538 return IsFSHL ? N0 : N1;
11544 if (IsUndefOrZero(N0))
11548 if (IsUndefOrZero(N1))
11562 if (
LHS &&
RHS &&
LHS->isSimple() &&
RHS->isSimple() &&
11563 LHS->getAddressSpace() ==
RHS->getAddressSpace() &&
11564 (
LHS->hasNUsesOfValue(1, 0) ||
RHS->hasNUsesOfValue(1, 0)) &&
11573 RHS->getAddressSpace(), NewAlign,
11574 RHS->getMemOperand()->getFlags(), &
Fast) &&
11578 AddToWorklist(NewPtr.
getNode());
11580 VT,
DL,
RHS->getChain(), NewPtr,
11581 RHS->getPointerInfo().getWithOffset(PtrOff), NewAlign,
11582 RHS->getMemOperand()->getFlags(),
RHS->getAAInfo());
11610 if (N0 == N1 && hasOperation(RotOpc, VT))
11611 return DAG.
getNode(RotOpc,
DL, VT, N0, N2);
11620SDValue DAGCombiner::visitSHLSAT(SDNode *
N) {
11655SDValue DAGCombiner::foldABSToABD(SDNode *
N,
const SDLoc &
DL) {
11656 EVT SrcVT =
N->getValueType(0);
11659 N =
N->getOperand(0).getNode();
11661 EVT VT =
N->getValueType(0);
11667 SDValue AbsOp0 =
N->getOperand(0);
11704 EVT MaxVT = VT0.
bitsGT(VT1) ? VT0 : VT1;
11705 if ((VT0 == MaxVT || Op0->
hasOneUse()) &&
11707 (!LegalTypes || hasOperation(ABDOpcode, MaxVT))) {
11717 if (!LegalOperations || hasOperation(ABDOpcode, VT)) {
11725SDValue DAGCombiner::visitABS(SDNode *
N) {
11727 EVT VT =
N->getValueType(0);
11760SDValue DAGCombiner::visitBSWAP(SDNode *
N) {
11762 EVT VT =
N->getValueType(0);
11787 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
11788 ShAmt->getZExtValue() >= (BW / 2) &&
11789 (ShAmt->getZExtValue() % 16) == 0 && TLI.
isTypeLegal(HalfVT) &&
11791 (!LegalOperations || hasOperation(
ISD::BSWAP, HalfVT))) {
11793 if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2)))
11809 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
11810 ShAmt->getZExtValue() % 8 == 0) {
11823SDValue DAGCombiner::visitBITREVERSE(SDNode *
N) {
11825 EVT VT =
N->getValueType(0);
11858 EVT VT = Src.getValueType();
11868 bool NeedAdd =
true;
11890SDValue DAGCombiner::visitCTLZ(SDNode *
N) {
11892 EVT VT =
N->getValueType(0);
11904 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
11910SDValue DAGCombiner::visitCTLZ_ZERO_UNDEF(SDNode *
N) {
11912 EVT VT =
N->getValueType(0);
11920 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
11926SDValue DAGCombiner::visitCTTZ(SDNode *
N) {
11928 EVT VT =
N->getValueType(0);
11943SDValue DAGCombiner::visitCTTZ_ZERO_UNDEF(SDNode *
N) {
11945 EVT VT =
N->getValueType(0);
11955SDValue DAGCombiner::visitCTPOP(SDNode *
N) {
11957 EVT VT =
N->getValueType(0);
11969 const APInt &Amt = AmtC->getAPIntValue();
11970 if (Amt.
ult(NumBits)) {
12004 EVT VT =
LHS.getValueType();
12008 return Flags.hasNoSignedZeros() &&
12010 (Flags.hasNoNaNs() ||
12060SDValue DAGCombiner::foldShiftToAvg(SDNode *
N,
const SDLoc &
DL) {
12061 const unsigned Opcode =
N->getOpcode();
12065 EVT VT =
N->getValueType(0);
12066 bool IsUnsigned = Opcode ==
ISD::SRL;
12077 if (!hasOperation(FloorISD, VT))
12081 if ((IsUnsigned && !
Add->getFlags().hasNoUnsignedWrap()) ||
12082 (!IsUnsigned && !
Add->getFlags().hasNoSignedWrap()))
12085 return DAG.
getNode(FloorISD,
DL,
N->getValueType(0), {A, B});
12091SDValue DAGCombiner::foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT) {
12092 unsigned Opc =
N->getOpcode();
12111 if ((
LHS == True &&
RHS == False) || (
LHS == False &&
RHS == True))
12117 True, DAG, LegalOperations, ForCodeSize);
12121 HandleSDNode NegTrueHandle(NegTrue);
12129 if (
LHS == NegTrue) {
12133 RHS, DAG, LegalOperations, ForCodeSize);
12135 HandleSDNode NegRHSHandle(NegRHS);
12136 if (NegRHS == False) {
12138 False, CC, TLI, DAG);
12158 EVT VT =
N->getValueType(0);
12160 VT !=
Cond.getOperand(0).getValueType())
12203SDValue DAGCombiner::foldSelectOfConstants(SDNode *
N) {
12207 EVT VT =
N->getValueType(0);
12208 EVT CondVT =
Cond.getValueType();
12219 if (CondVT != MVT::i1 || LegalOperations) {
12234 C1->
isZero() && C2->isOne()) {
12249 assert(CondVT == MVT::i1 && !LegalOperations);
12252 if (C1->
isOne() && C2->isZero())
12260 if (C1->
isZero() && C2->isOne()) {
12267 if (C1->
isZero() && C2->isAllOnes()) {
12280 const APInt &C1Val = C1->getAPIntValue();
12281 const APInt &C2Val = C2->getAPIntValue();
12284 if (C1Val - 1 == C2Val) {
12290 if (C1Val + 1 == C2Val) {
12310 if (C2->isAllOnes()) {
12322template <
class MatchContextClass>
12326 N->getOpcode() == ISD::VP_SELECT) &&
12327 "Expected a (v)(vp.)select");
12329 SDValue T =
N->getOperand(1),
F =
N->getOperand(2);
12330 EVT VT =
N->getValueType(0);
12332 MatchContextClass matcher(DAG, TLI,
N);
12368 EVT VT =
N->getValueType(0);
12432 EVT VT =
LHS.getValueType();
12434 if (LegalOperations && !hasOperation(ABDOpc, VT))
12451 hasOperation(ABDOpc, VT))
12467 hasOperation(ABDOpc, VT))
12501SDValue DAGCombiner::visitSELECT(SDNode *
N) {
12505 EVT VT =
N->getValueType(0);
12508 SDNodeFlags
Flags =
N->getFlags();
12520 if (
SDValue V = foldSelectOfConstants(
N))
12524 if (SimplifySelectOps(
N, N1, N2))
12527 if (VT0 == MVT::i1) {
12536 bool normalizeToSequence =
12545 if (normalizeToSequence || !InnerSelect.
use_empty())
12547 InnerSelect, N2, Flags);
12550 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12557 Cond1, N1, N2, Flags);
12558 if (normalizeToSequence || !InnerSelect.
use_empty())
12560 InnerSelect, Flags);
12563 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12573 if (!normalizeToSequence) {
12579 if (
SDValue Combined = visitANDLike(N0, N1_0,
N)) {
12592 if (!normalizeToSequence) {
12598 if (
SDValue Combined = visitORLike(N0, N2_0,
DL))
12634 combineMinNumMaxNum(
DL, VT, Cond0, Cond1, N1, N2, CC))
12647 if (
C && NotC &&
C->getAPIntValue() == ~NotC->getAPIntValue()) {
12667 (!LegalOperations &&
12675 if (
SDValue ABD = foldSelectToABD(Cond0, Cond1, N1, N2, CC,
DL))
12678 if (
SDValue NewSel = SimplifySelect(
DL, N0, N1, N2))
12683 if (
SDValue UMin = foldSelectToUMin(Cond0, Cond1, N1, N2, CC,
DL))
12688 if (
SDValue BinOp = foldSelectOfBinops(
N))
12704 EVT VT =
N->getValueType(0);
12712 if (
LHS->getNumOperands() != 2 ||
RHS->getNumOperands() != 2)
12721 for (
int i = 0; i < NumElems / 2; ++i) {
12722 if (
Cond->getOperand(i)->isUndef())
12725 if (BottomHalf ==
nullptr)
12727 else if (
Cond->getOperand(i).getNode() != BottomHalf)
12733 for (
int i = NumElems / 2; i < NumElems; ++i) {
12734 if (
Cond->getOperand(i)->isUndef())
12737 if (TopHalf ==
nullptr)
12739 else if (
Cond->getOperand(i).getNode() != TopHalf)
12743 assert(TopHalf && BottomHalf &&
12744 "One half of the selector was all UNDEFs and the other was all the "
12745 "same value. This should have been addressed before this function.");
12748 BottomHalf->
isZero() ?
RHS->getOperand(0) :
LHS->getOperand(0),
12749 TopHalf->
isZero() ?
RHS->getOperand(1) :
LHS->getOperand(1));
12762 EVT VT = BasePtr.getValueType();
12766 SplatVal.getValueType() == VT) {
12772 if (Index.getOpcode() !=
ISD::ADD)
12799 Index = Index.getOperand(0);
12812 Index = Index.getOperand(0);
12819SDValue DAGCombiner::visitVPSCATTER(SDNode *
N) {
12850SDValue DAGCombiner::visitMSCATTER(SDNode *
N) {
12882SDValue DAGCombiner::visitMSTORE(SDNode *
N) {
12896 MST1->isSimple() && MST1->getBasePtr() == Ptr &&
12899 MST1->getMemoryVT().getStoreSize()) ||
12903 CombineTo(MST1, MST1->getChain());
12920 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
12924 Value.getValueType().isInteger() &&
12927 APInt TruncDemandedBits =
12953 Value.getOperand(0).getValueType());
12963SDValue DAGCombiner::visitVP_STRIDED_STORE(SDNode *
N) {
12965 EVT EltVT = SST->getValue().getValueType().getVectorElementType();
12968 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
12969 return DAG.
getStoreVP(SST->getChain(), SDLoc(
N), SST->getValue(),
12970 SST->getBasePtr(), SST->getOffset(), SST->getMask(),
12971 SST->getVectorLength(), SST->getMemoryVT(),
12972 SST->getMemOperand(), SST->getAddressingMode(),
12973 SST->isTruncatingStore(), SST->isCompressingStore());
12978SDValue DAGCombiner::visitVECTOR_COMPRESS(SDNode *
N) {
12982 SDValue Passthru =
N->getOperand(2);
12985 bool HasPassthru = !Passthru.
isUndef();
12998 unsigned NumSelected = 0;
13000 for (
unsigned I = 0;
I < NumElmts; ++
I) {
13009 Ops.push_back(VecI);
13013 for (
unsigned Rest = NumSelected; Rest < NumElmts; ++Rest) {
13019 Ops.push_back(Val);
13027SDValue DAGCombiner::visitVPGATHER(SDNode *
N) {
13055SDValue DAGCombiner::visitMGATHER(SDNode *
N) {
13068 return CombineTo(
N, PassThru, MGT->
getChain());
13087SDValue DAGCombiner::visitMLOAD(SDNode *
N) {
13103 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13107 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13113SDValue DAGCombiner::visitMHISTOGRAM(SDNode *
N) {
13123 EVT DataVT =
Index.getValueType();
13141SDValue DAGCombiner::visitPARTIAL_REDUCE_MLA(SDNode *
N) {
13142 if (
SDValue Res = foldPartialReduceMLAMulOp(
N))
13144 if (
SDValue Res = foldPartialReduceAdd(
N))
13160SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *
N) {
13192 RHS.getValueType().getScalarType()));
13200 auto IsIntOrFPExtOpcode = [](
unsigned int Opcode) {
13204 unsigned LHSOpcode =
LHS->getOpcode();
13205 if (!IsIntOrFPExtOpcode(LHSOpcode))
13216 EVT OpVT =
Op.getValueType();
13230 unsigned LHSBits =
LHS.getValueType().getScalarSizeInBits();
13247 ApplyPredicate(
C, LHSExtOp);
13248 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, LHSExtOp,
C);
13251 unsigned RHSOpcode =
RHS->getOpcode();
13252 if (!IsIntOrFPExtOpcode(RHSOpcode))
13279 NewOpc !=
N->getOpcode())
13289 ApplyPredicate(RHSExtOp, LHSExtOp);
13290 return DAG.
getNode(NewOpc,
DL,
N->getValueType(0), Acc, LHSExtOp, RHSExtOp);
13300SDValue DAGCombiner::foldPartialReduceAdd(SDNode *
N) {
13325 if (Op1IsSigned != NodeIsSigned &&
13352 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, UnextOp1,
13356SDValue DAGCombiner::visitVP_STRIDED_LOAD(SDNode *
N) {
13361 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13363 SLD->getAddressingMode(), SLD->getExtensionType(), SLD->getValueType(0),
13364 SDLoc(
N), SLD->getChain(), SLD->getBasePtr(), SLD->getOffset(),
13365 SLD->getMask(), SLD->getVectorLength(), SLD->getMemoryVT(),
13366 SLD->getMemOperand(), SLD->isExpandingLoad());
13367 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13374SDValue DAGCombiner::foldVSelectOfConstants(SDNode *
N) {
13378 EVT VT =
N->getValueType(0);
13379 if (!
Cond.hasOneUse() ||
Cond.getScalarValueSizeInBits() != 1 ||
13388 bool AllAddOne =
true;
13389 bool AllSubOne =
true;
13391 for (
unsigned i = 0; i != Elts; ++i) {
13414 if (AllAddOne || AllSubOne) {
13441SDValue DAGCombiner::visitVP_SELECT(SDNode *
N) {
13465 EVT CondVT =
Cond.getValueType();
13466 assert(CondVT.
isVector() &&
"Vector select expects a vector selector!");
13474 if (!IsTAllZero && !IsTAllOne && !IsFAllZero && !IsFAllOne)
13478 if (IsTAllZero && IsFAllZero) {
13487 Cond.getOperand(0).getValueType() == VT && VT.
isSimple() &&
13489 TValAPInt.
isOne() &&
13508 if (!IsTAllOne && !IsFAllZero &&
Cond.hasOneUse() &&
13512 if (IsTAllZero || IsFAllOne) {
13525 "Select condition no longer all-sign bits");
13528 if (IsTAllOne && IsFAllZero)
13557SDValue DAGCombiner::visitVSELECT(SDNode *
N) {
13561 EVT VT =
N->getValueType(0);
13594 bool isAbs =
false;
13613 AddToWorklist(Shift.
getNode());
13614 AddToWorklist(
Add.getNode());
13626 if (
SDValue FMinMax = combineMinNumMaxNum(
DL, VT,
LHS,
RHS, N1, N2, CC))
13641 EVT NarrowVT =
LHS.getValueType();
13649 SetCCWidth != 1 && SetCCWidth < WideWidth &&
13695 (OpLHS == CondLHS || OpRHS == CondLHS))
13698 if (OpRHS.getOpcode() == CondRHS.getOpcode() &&
13701 CondLHS == OpLHS) {
13705 auto MatchUADDSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13706 return Cond->getAPIntValue() == ~Op->getAPIntValue();
13747 if (OpLHS ==
LHS) {
13762 auto MatchUSUBSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13763 return (!
Op && !
Cond) ||
13765 Cond->getAPIntValue() == (-
Op->getAPIntValue() - 1));
13801 if (SimplifySelectOps(
N, N1, N2))
13821 if (
SDValue V = foldVSelectOfConstants(
N))
13837SDValue DAGCombiner::visitSELECT_CC(SDNode *
N) {
13858 AddToWorklist(
SCC.getNode());
13863 return SCCC->isZero() ? N3 : N2;
13867 if (
SCC->isUndef())
13873 SCC.getOperand(0),
SCC.getOperand(1), N2, N3,
13874 SCC.getOperand(2),
SCC->getFlags());
13879 if (SimplifySelectOps(
N, N2, N3))
13883 return SimplifySelectCC(
DL, N0, N1, N2, N3, CC);
13886SDValue DAGCombiner::visitSETCC(SDNode *
N) {
13891 N->hasOneUse() &&
N->user_begin()->getOpcode() ==
ISD::BRCOND;
13894 EVT VT =
N->getValueType(0);
13901 if (PreferSetCC && Combined.getOpcode() !=
ISD::SETCC) {
13902 SDValue NewSetCC = rebuildSetCC(Combined);
13930 A.getOperand(0) ==
B.getOperand(0);
13934 B.getOperand(0) ==
A;
13937 bool IsRotate =
false;
13940 if (IsAndWithShift(N0, N1)) {
13942 ShiftOrRotate = N1;
13943 }
else if (IsAndWithShift(N1, N0)) {
13945 ShiftOrRotate = N0;
13946 }
else if (IsRotateWithOp(N0, N1)) {
13949 ShiftOrRotate = N1;
13950 }
else if (IsRotateWithOp(N1, N0)) {
13953 ShiftOrRotate = N0;
13956 if (AndOrOp && ShiftOrRotate && ShiftOrRotate.hasOneUse() &&
13961 auto GetAPIntValue = [](
SDValue Op) -> std::optional<APInt> {
13964 if (CNode ==
nullptr)
13965 return std::nullopt;
13968 std::optional<APInt> AndCMask =
13969 IsRotate ? std::nullopt : GetAPIntValue(AndOrOp.
getOperand(1));
13970 std::optional<APInt> ShiftCAmt =
13971 GetAPIntValue(ShiftOrRotate.getOperand(1));
13975 if (ShiftCAmt && (IsRotate || AndCMask) && ShiftCAmt->ult(NumBits)) {
13976 unsigned ShiftOpc = ShiftOrRotate.getOpcode();
13978 bool CanTransform = IsRotate;
13979 if (!CanTransform) {
13981 CanTransform = *ShiftCAmt == (~*AndCMask).
popcount();
13983 CanTransform &= (*ShiftCAmt + AndCMask->popcount()) == NumBits;
13991 OpVT, ShiftOpc, ShiftCAmt->isPowerOf2(), *ShiftCAmt, AndCMask);
13993 if (CanTransform && NewShiftOpc != ShiftOpc) {
13995 DAG.
getNode(NewShiftOpc,
DL, OpVT, ShiftOrRotate.getOperand(0),
13996 ShiftOrRotate.getOperand(1));
14003 NumBits - ShiftCAmt->getZExtValue())
14004 : APInt::getLowBitsSet(NumBits,
14005 NumBits - ShiftCAmt->getZExtValue());
14013 return DAG.
getSetCC(
DL, VT, NewAndOrOp, NewShiftOrRotate,
Cond);
14021SDValue DAGCombiner::visitSETCCCARRY(SDNode *
N) {
14042 if (!
N.hasOneUse())
14071 unsigned Opcode =
N->getOpcode();
14073 EVT VT =
N->getValueType(0);
14076 "Expected EXTEND dag node in input!");
14116 unsigned Opcode =
N->getOpcode();
14118 EVT VT =
N->getValueType(0);
14121 "Expected EXTEND dag node in input!");
14127 return DAG.
getNode(Opcode,
DL, VT, N0);
14146 unsigned FoldOpc = Opcode;
14169 for (
unsigned i = 0; i != NumElts; ++i) {
14171 if (
Op.isUndef()) {
14182 APInt C =
Op->getAsAPIntVal().zextOrTrunc(EVTBits);
14200 bool HasCopyToRegUses =
false;
14215 for (
unsigned i = 0; i != 2; ++i) {
14233 HasCopyToRegUses =
true;
14236 if (HasCopyToRegUses) {
14237 bool BothLiveOut =
false;
14240 BothLiveOut =
true;
14247 return !ExtendNodes.
empty();
14252void DAGCombiner::ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
14257 for (SDNode *SetCC : SetCCs) {
14260 for (
unsigned j = 0;
j != 2; ++
j) {
14261 SDValue SOp = SetCC->getOperand(j);
14262 if (SOp == OrigLoad)
14263 Ops.push_back(ExtLoad);
14268 Ops.push_back(SetCC->getOperand(2));
14274SDValue DAGCombiner::CombineExtLoad(SDNode *
N) {
14276 EVT DstVT =
N->getValueType(0);
14281 "Unexpected node type (not an extend)!");
14319 EVT SplitSrcVT = SrcVT;
14320 EVT SplitDstVT = DstVT;
14333 const unsigned NumSplits =
14340 for (
unsigned Idx = 0; Idx < NumSplits; Idx++) {
14341 const unsigned Offset = Idx * Stride;
14359 AddToWorklist(NewChain.
getNode());
14361 CombineTo(
N, NewValue);
14367 ExtendSetCCUses(SetCCs, N0, NewValue, (
ISD::NodeType)
N->getOpcode());
14368 CombineTo(N0.
getNode(), Trunc, NewChain);
14374SDValue DAGCombiner::CombineZExtLogicopShiftLoad(SDNode *
N) {
14376 EVT VT =
N->getValueType(0);
14377 EVT OrigVT =
N->getOperand(0).getValueType();
14399 EVT MemVT =
Load->getMemoryVT();
14420 Load->getChain(),
Load->getBasePtr(),
14421 Load->getMemoryVT(),
Load->getMemOperand());
14434 if (
SDValue(Load, 0).hasOneUse()) {
14438 Load->getValueType(0), ExtLoad);
14439 CombineTo(Load, Trunc, ExtLoad.
getValue(1));
14443 recursivelyDeleteUnusedNodes(N0.
getNode());
14452SDValue DAGCombiner::matchVSelectOpSizesWithSetCC(SDNode *Cast) {
14453 unsigned CastOpcode = Cast->
getOpcode();
14457 "Unexpected opcode for vector select narrowing/widening");
14497 bool LegalOperations,
SDNode *
N,
14508 if ((LegalOperations || !LN0->
isSimple() ||
14519 Combiner.recursivelyDeleteUnusedNodes(LN0);
14532 bool NonNegZExt =
false) {
14539 "Unexpected load type or opcode");
14560 bool DoXform =
true;
14573 Combiner.ExtendSetCCUses(SetCCs, N0, ExtLoad, ExtOpc);
14575 bool NoReplaceTrunc =
SDValue(LN0, 0).hasOneUse();
14577 if (NoReplaceTrunc) {
14579 Combiner.recursivelyDeleteUnusedNodes(LN0);
14624 EVT MemoryVT = ALoad->getMemoryVT();
14633 EVT OrigVT = ALoad->getValueType(0);
14636 ExtLoadType,
SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
14637 ALoad->getBasePtr(), ALoad->getMemOperand()));
14647 bool LegalOperations) {
14659 EVT VT =
N->getValueType(0);
14660 EVT XVT =
X.getValueType();
14676 return DAG.
getNode(ShiftOpcode,
DL, VT, NotX, ShiftAmount);
14682SDValue DAGCombiner::foldSextSetcc(SDNode *
N) {
14690 EVT VT =
N->getValueType(0);
14695 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
14700 if (VT.
isVector() && !LegalOperations &&
14719 if (SVT == MatchingVecType) {
14735 auto IsFreeToExtend = [&](
SDValue V) {
14749 for (SDUse &Use :
V->uses()) {
14751 SDNode *
User =
Use.getUser();
14752 if (
Use.getResNo() != 0 || User == N0.
getNode())
14757 if (
User->getOpcode() != ExtOpcode ||
User->getValueType(0) != VT)
14763 if (IsFreeToExtend(N00) && IsFreeToExtend(N01)) {
14766 return DAG.
getSetCC(
DL, VT, Ext0, Ext1, CC);
14783 SDValue ExtTrueVal = (SetCCWidth == 1)
14787 if (
SDValue SCC = SimplifySelectCC(
DL, N00, N01, ExtTrueVal, Zero, CC,
true))
14799 return DAG.
getSelect(
DL, VT, SetCC, ExtTrueVal, Zero);
14806SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *
N) {
14808 EVT VT =
N->getValueType(0);
14812 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
14858 if (NarrowLoad.getNode() != N0.
getNode()) {
14859 CombineTo(N0.
getNode(), NarrowLoad);
14861 AddToWorklist(oye);
14869 unsigned OpBits =
Op.getScalarValueSizeInBits();
14875 if (OpBits == DestBits) {
14881 if (OpBits < DestBits) {
14890 Flags.setNoSignedWrap(
true);
14898 if (OpBits < DestBits)
14900 else if (OpBits > DestBits)
14920 if (
SDValue ExtLoad = CombineExtLoad(
N))
14955 bool NoReplaceTruncAnd = !N0.
hasOneUse();
14956 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
14959 if (NoReplaceTruncAnd) {
14962 CombineTo(N0.
getNode(), TruncAnd);
14964 if (NoReplaceTrunc) {
14969 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
14988 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15019 if (NewXor.getNode() == N0.
getNode()) {
15045 "Expected extend op");
15089SDValue DAGCombiner::visitZERO_EXTEND(SDNode *
N) {
15091 EVT VT =
N->getValueType(0);
15095 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15126 APInt TruncatedBits =
15128 APInt(
Op.getScalarValueSizeInBits(), 0) :
15129 APInt::getBitsSet(
Op.getScalarValueSizeInBits(),
15130 N0.getScalarValueSizeInBits(),
15131 std::min(
Op.getScalarValueSizeInBits(),
15134 SDValue ZExtOrTrunc = DAG.getZExtOrTrunc(Op, DL, VT);
15135 DAG.salvageDebugInfo(*N0.getNode());
15137 return ZExtOrTrunc;
15147 if (NarrowLoad.getNode() != N0.
getNode()) {
15148 CombineTo(N0.
getNode(), NarrowLoad);
15150 AddToWorklist(oye);
15158 if (
N->getFlags().hasNonNeg()) {
15166 if (OpBits == DestBits) {
15172 if (OpBits < DestBits) {
15182 Flags.setNoSignedWrap(
true);
15183 Flags.setNoUnsignedWrap(
true);
15195 AddToWorklist(
Op.getNode());
15199 return ZExtOrTrunc;
15205 AddToWorklist(
Op.getNode());
15241 if (
SDValue ExtLoad = CombineExtLoad(
N))
15261 bool DoXform =
true;
15268 if (isAndLoadExtLoad(AndC, LN00, LoadResultTy, ExtVT))
15284 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15285 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15288 if (NoReplaceTruncAnd) {
15291 CombineTo(N0.
getNode(), TruncAnd);
15293 if (NoReplaceTrunc) {
15298 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
15307 if (
SDValue ZExtLoad = CombineZExtLogicopShiftLoad(
N))
15320 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
15323 if (!LegalOperations && VT.
isVector() &&
15355 if (
SDValue SCC = SimplifySelectCC(
15375 if (ShAmtC->getAPIntValue().ugt(KnownZeroBits)) {
15396 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15418SDValue DAGCombiner::visitANY_EXTEND(SDNode *
N) {
15420 EVT VT =
N->getValueType(0);
15454 if (NarrowLoad.getNode() != N0.
getNode()) {
15455 CombineTo(N0.
getNode(), NarrowLoad);
15457 AddToWorklist(oye);
15491 bool DoXform =
true;
15504 CombineTo(
N, ExtLoad);
15505 if (NoReplaceTrunc) {
15507 recursivelyDeleteUnusedNodes(LN0);
15511 CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
15525 if (!LegalOperations || TLI.
isLoadExtLegal(ExtType, VT, MemVT)) {
15529 CombineTo(
N, ExtLoad);
15531 recursivelyDeleteUnusedNodes(LN0);
15538 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
15545 if (VT.
isVector() && !LegalOperations) {
15570 if (
SDValue SCC = SimplifySelectCC(
15586SDValue DAGCombiner::visitAssertExt(SDNode *
N) {
15587 unsigned Opcode =
N->getOpcode();
15607 EVT MinAssertVT = AssertVT.
bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
15622 if (AssertVT.
bitsLT(BigA_AssertVT)) {
15640 if (AssertVT.
bitsLT(BigA_AssertVT) &&
15660SDValue DAGCombiner::visitAssertAlign(SDNode *
N) {
15670 std::max(AL, AAN->getAlign()));
15681 unsigned AlignShift =
Log2(AL);
15686 if (LHSAlignShift >= AlignShift || RHSAlignShift >= AlignShift) {
15687 if (LHSAlignShift < AlignShift)
15689 if (RHSAlignShift < AlignShift)
15703SDValue DAGCombiner::reduceLoadWidth(SDNode *
N) {
15704 unsigned Opc =
N->getOpcode();
15708 EVT VT =
N->getValueType(0);
15718 unsigned ShAmt = 0;
15723 unsigned ShiftedOffset = 0;
15743 uint64_t MemoryWidth = LN->getMemoryVT().getScalarSizeInBits();
15744 if (MemoryWidth <= ShAmt)
15755 LN->getExtensionType() != ExtType)
15764 unsigned ActiveBits = 0;
15765 if (
Mask.isMask()) {
15766 ActiveBits =
Mask.countr_one();
15767 }
else if (
Mask.isShiftedMask(ShAmt, ActiveBits)) {
15768 ShiftedOffset = ShAmt;
15789 if (!
SRL.hasOneUse())
15802 ShAmt = SRL1C->getZExtValue();
15803 uint64_t MemoryWidth = LN->getMemoryVT().getSizeInBits();
15804 if (ShAmt >= MemoryWidth)
15829 SDNode *
Mask = *(
SRL->user_begin());
15832 unsigned Offset, ActiveBits;
15833 const APInt& ShiftMask =
Mask->getConstantOperandAPInt(1);
15834 if (ShiftMask.
isMask()) {
15856 N0 =
SRL.getOperand(0);
15864 unsigned ShLeftAmt = 0;
15868 ShLeftAmt = N01->getZExtValue();
15881 !isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
15884 auto AdjustBigEndianShift = [&](
unsigned ShAmt) {
15885 unsigned LVTStoreBits =
15888 return LVTStoreBits - EVTStoreBits - ShAmt;
15893 unsigned PtrAdjustmentInBits =
15896 uint64_t PtrOff = PtrAdjustmentInBits / 8;
15902 AddToWorklist(NewPtr.
getNode());
15906 const MDNode *OldRanges = LN0->
getRanges();
15907 const MDNode *NewRanges =
nullptr;
15911 if (ShAmt == 0 && OldRanges) {
15919 ConstantRange TruncatedCR = CR.
truncate(BitSize);
15929 NewRanges = OldRanges;
15942 WorklistRemover DeadNodes(*
this);
15947 if (ShLeftAmt != 0) {
15959 if (ShiftedOffset != 0) {
15973SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *
N) {
15976 EVT VT =
N->getValueType(0);
16007 if ((N00Bits <= ExtVTBits ||
16020 if ((N00Bits == ExtVTBits ||
16021 (!IsZext && (N00Bits < ExtVTBits ||
16023 (!LegalOperations ||
16048 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
16056 if (ShAmt->getAPIntValue().ule(VTBits - ExtVTBits)) {
16060 if (((VTBits - ExtVTBits) - ShAmt->getZExtValue()) < InSignBits)
16079 CombineTo(
N, ExtLoad);
16081 AddToWorklist(ExtLoad.
getNode());
16094 CombineTo(
N, ExtLoad);
16103 if (ExtVT == Ld->getMemoryVT() && Ld->hasNUsesOfValue(1, 0) &&
16107 VT,
DL, Ld->getChain(), Ld->getBasePtr(), Ld->getOffset(),
16108 Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->getMemOperand(),
16109 Ld->getAddressingMode(),
ISD::SEXTLOAD, Ld->isExpandingLoad());
16110 CombineTo(
N, Frozen ? N0 : ExtMaskedLoad);
16111 CombineTo(Ld, ExtMaskedLoad, ExtMaskedLoad.
getValue(1));
16118 if (
SDValue(GN0, 0).hasOneUse() && ExtVT == GN0->getMemoryVT() &&
16120 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
16121 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
16124 DAG.
getVTList(VT, MVT::Other), ExtVT,
DL,
Ops, GN0->getMemOperand(),
16127 CombineTo(
N, ExtLoad);
16129 AddToWorklist(ExtLoad.
getNode());
16152 (!LegalOperations ||
16166 bool LegalOperations) {
16167 unsigned InregOpcode =
N->getOpcode();
16171 EVT VT =
N->getValueType(0);
16173 *DAG.
getContext(), Src.getValueType().getVectorElementType());
16176 "Expected EXTEND_VECTOR_INREG dag node in input!");
16185 Src = Src.getOperand(0);
16186 if (Src.getValueType() != SrcVT)
16192 return DAG.
getNode(Opcode,
DL, VT, Src);
16195SDValue DAGCombiner::visitEXTEND_VECTOR_INREG(SDNode *
N) {
16197 EVT VT =
N->getValueType(0);
16221SDValue DAGCombiner::visitTRUNCATE_USAT_U(SDNode *
N) {
16222 EVT VT =
N->getValueType(0);
16243 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16245 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16266 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16268 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16289 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16291 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16314 auto AllowedTruncateSat = [&](
unsigned Opc,
EVT SrcVT,
EVT VT) ->
bool {
16326 }
else if (Src.getOpcode() ==
ISD::UMIN) {
16338SDValue DAGCombiner::visitTRUNCATE(SDNode *
N) {
16340 EVT VT =
N->getValueType(0);
16355 return SaturatedTR;
16407 if (LegalTypes && !LegalOperations && VT.
isScalarInteger() && VT != MVT::i1 &&
16409 EVT TrTy =
N->getValueType(0);
16414 if (Src.getOpcode() ==
ISD::SRL && Src.getOperand(0)->hasOneUse()) {
16417 Src = Src.getOperand(0);
16424 EVT VecTy = Src.getOperand(0).getValueType();
16425 EVT ExTy = Src.getValueType();
16429 auto NewEltCnt = EltCnt * SizeRatio;
16434 SDValue EltNo = Src->getOperand(1);
16437 int Index = isLE ? (Elt * SizeRatio + EltOffset)
16438 : (Elt * SizeRatio + (SizeRatio - 1) - EltOffset);
16449 if (!LegalOperations ||
16472 AddToWorklist(Amt.
getNode());
16521 if (BuildVectEltTy == TruncVecEltTy) {
16525 unsigned TruncEltOffset = BuildVecNumElts / TruncVecNumElts;
16526 unsigned FirstElt = isLE ? 0 : (TruncEltOffset - 1);
16528 assert((BuildVecNumElts % TruncVecNumElts) == 0 &&
16529 "Invalid number of elements");
16532 for (
unsigned i = FirstElt, e = BuildVecNumElts; i <
e;
16533 i += TruncEltOffset)
16543 if (
SDValue Reduced = reduceLoadWidth(
N))
16566 unsigned NumDefs = 0;
16570 if (!
X.isUndef()) {
16587 if (NumDefs == 1) {
16588 assert(
V.getNode() &&
"The single defined operand is empty!");
16590 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
16596 AddToWorklist(
NV.getNode());
16611 (!LegalOperations ||
16639 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
16653 if (!LegalOperations && N0.
hasOneUse() &&
16670 Flags.setNoUnsignedWrap(
true);
16695 if (!LegalOperations && N0.
hasOneUse() &&
16736 if (!LegalOperations && N0.
hasOneUse() &&
16744 bool CanFold =
false;
16752 unsigned NeededBits = SrcBits - TruncBits;
16778SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *
N, EVT VT) {
16791 !LD1->hasOneUse() || !LD2->hasOneUse() ||
16792 LD1->getAddressSpace() != LD2->getAddressSpace())
16795 unsigned LD1Fast = 0;
16796 EVT LD1VT = LD1->getValueType(0);
16801 *LD1->getMemOperand(), &LD1Fast) && LD1Fast)
16802 return DAG.
getLoad(VT, SDLoc(
N), LD1->getChain(), LD1->getBasePtr(),
16803 LD1->getPointerInfo(), LD1->getAlign());
16814SDValue DAGCombiner::foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
16818 EVT VT =
N->getValueType(0);
16855 auto IsBitCastOrFree = [&TLI, FPOpcode](
SDValue Op, EVT VT) {
16869 IsBitCastOrFree(LogicOp0, VT)) {
16872 NumFPLogicOpsConv++;
16881SDValue DAGCombiner::visitBITCAST(SDNode *
N) {
16883 EVT VT =
N->getValueType(0);
16908 if (!LegalOperations ||
16914 if (
C.getNode() !=
N)
16927 auto IsFreeBitcast = [VT](
SDValue V) {
16929 V.getOperand(0).getValueType() == VT) ||
16942 auto CastLoad = [
this, &VT](
SDValue N0,
const SDLoc &
DL) {
16957 if ((LegalOperations || !LN0->
isSimple()) &&
16967 if (
const MDNode *MD = LN0->
getRanges()) {
16979 if (
SDValue NewLd = CastLoad(N0, SDLoc(
N)))
16986 if (
SDValue V = foldBitcastedFPLogic(
N, DAG, TLI))
17006 AddToWorklist(NewConv.
getNode());
17009 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17016 AddToWorklist(FlipBit.
getNode());
17023 AddToWorklist(
Hi.getNode());
17025 AddToWorklist(FlipBit.
getNode());
17029 AddToWorklist(FlipBits.
getNode());
17059 AddToWorklist(
X.getNode());
17063 if (OrigXWidth < VTWidth) {
17065 AddToWorklist(
X.getNode());
17066 }
else if (OrigXWidth > VTWidth) {
17071 X.getValueType(),
X,
17073 X.getValueType()));
17074 AddToWorklist(
X.getNode());
17076 AddToWorklist(
X.getNode());
17079 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17082 AddToWorklist(Cst.
getNode());
17084 AddToWorklist(
X.getNode());
17086 AddToWorklist(XorResult.
getNode());
17090 SDLoc(XorResult)));
17091 AddToWorklist(XorResult64.
getNode());
17094 DAG.
getConstant(SignBit, SDLoc(XorResult64), MVT::i64));
17095 AddToWorklist(FlipBit.
getNode());
17098 AddToWorklist(FlipBits.
getNode());
17104 AddToWorklist(
X.getNode());
17109 AddToWorklist(Cst.
getNode());
17117 if (
SDValue CombineLD = CombineConsecutiveLoads(N0.
getNode(), VT))
17140 auto PeekThroughBitcast = [&](
SDValue Op) {
17142 Op.getOperand(0).getValueType() == VT)
17159 SmallVector<int, 8> NewMask;
17161 for (
int i = 0; i != MaskScale; ++i)
17162 NewMask.
push_back(M < 0 ? -1 : M * MaskScale + i);
17167 return LegalShuffle;
17173SDValue DAGCombiner::visitBUILD_PAIR(SDNode *
N) {
17174 EVT VT =
N->getValueType(0);
17175 return CombineConsecutiveLoads(
N, VT);
17178SDValue DAGCombiner::visitFREEZE(SDNode *
N) {
17192 assert(
N->getOperand(0) == FrozenN0 &&
"Expected cycle in DAG");
17220 bool AllowMultipleMaybePoisonOperands =
17248 SmallSet<SDValue, 8> MaybePoisonOperands;
17249 SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
17253 bool HadMaybePoisonOperands = !MaybePoisonOperands.
empty();
17254 bool IsNewMaybePoisonOperand = MaybePoisonOperands.
insert(
Op).second;
17255 if (IsNewMaybePoisonOperand)
17256 MaybePoisonOperandNumbers.
push_back(OpNo);
17257 if (!HadMaybePoisonOperands)
17259 if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
17268 for (
unsigned OpNo : MaybePoisonOperandNumbers) {
17279 SDValue MaybePoisonOperand =
N->getOperand(0).getOperand(OpNo);
17281 if (MaybePoisonOperand.
isUndef())
17288 FrozenMaybePoisonOperand.
getOperand(0) == FrozenMaybePoisonOperand) {
17292 MaybePoisonOperand);
17328 SDNodeFlags SrcFlags = N0->
getFlags();
17329 SDNodeFlags SafeFlags;
17343 N->getFlags().hasAllowContract();
17347template <
class MatchContextClass>
17348SDValue DAGCombiner::visitFADDForFMACombine(SDNode *
N) {
17351 EVT VT =
N->getValueType(0);
17353 MatchContextClass matcher(DAG, TLI,
N);
17356 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17361 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17365 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17369 if (!HasFMAD && !HasFMA)
17372 bool AllowFusionGlobally =
17375 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17401 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17412 return matcher.getNode(PreferredFusedOpcode, SL, VT, N0.
getOperand(0),
17419 return matcher.getNode(PreferredFusedOpcode, SL, VT, N1.
getOperand(0),
17431 bool CanReassociate =
N->getFlags().hasAllowReassociation();
17432 if (CanReassociate) {
17437 }
else if (isFusedOp(N1) && N1.
hasOneUse()) {
17443 while (
E && isFusedOp(TmpFMA) && TmpFMA.
hasOneUse()) {
17448 SDValue CDE = matcher.getNode(PreferredFusedOpcode, SL, VT,
C,
D,
E);
17467 return matcher.getNode(
17468 PreferredFusedOpcode, SL, VT,
17481 return matcher.getNode(
17482 PreferredFusedOpcode, SL, VT,
17494 return matcher.getNode(
17495 PreferredFusedOpcode, SL, VT,
X,
Y,
17496 matcher.getNode(PreferredFusedOpcode, SL, VT,
17500 if (isFusedOp(N0)) {
17521 return matcher.getNode(
17522 PreferredFusedOpcode, SL, VT,
17525 matcher.getNode(PreferredFusedOpcode, SL, VT,
17531 if (isFusedOp(N00)) {
17545 if (isFusedOp(N1)) {
17566 if (isFusedOp(N10)) {
17583template <
class MatchContextClass>
17584SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *
N) {
17587 EVT VT =
N->getValueType(0);
17589 MatchContextClass matcher(DAG, TLI,
N);
17592 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17597 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17601 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17605 if (!HasFMAD && !HasFMA)
17608 const SDNodeFlags
Flags =
N->getFlags();
17609 bool AllowFusionGlobally =
17613 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17622 bool NoSignedZero =
Flags.hasNoSignedZeros();
17629 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17635 return matcher.getNode(PreferredFusedOpcode, SL, VT, XY.
getOperand(0),
17646 return matcher.getNode(
17647 PreferredFusedOpcode, SL, VT,
17648 matcher.getNode(
ISD::FNEG, SL, VT, YZ.getOperand(0)),
17649 YZ.getOperand(1),
X);
17659 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17662 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17666 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17669 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17678 return matcher.
getNode(PreferredFusedOpcode, SL, VT,
17679 matcher.getNode(
ISD::FNEG, SL, VT, N00), N01,
17680 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17692 return matcher.getNode(
17693 PreferredFusedOpcode, SL, VT,
17696 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17708 return matcher.getNode(
17709 PreferredFusedOpcode, SL, VT,
17730 return matcher.getNode(
17733 PreferredFusedOpcode, SL, VT,
17754 return matcher.getNode(
17757 PreferredFusedOpcode, SL, VT,
17774 if (
Aggressive &&
N->getFlags().hasAllowReassociation()) {
17775 bool CanFuse =
N->getFlags().hasAllowContract();
17778 if (CanFuse && isFusedOp(N0) &&
17779 isContractableAndReassociableFMUL(N0.
getOperand(2)) &&
17781 return matcher.getNode(
17783 matcher.
getNode(PreferredFusedOpcode, SL, VT,
17791 if (CanFuse && isFusedOp(N1) &&
17792 isContractableAndReassociableFMUL(N1.
getOperand(2)) &&
17797 PreferredFusedOpcode, SL, VT,
17800 matcher.
getNode(PreferredFusedOpcode, SL, VT,
17801 matcher.getNode(
ISD::FNEG, SL, VT, N20), N21, N0));
17806 if (isFusedOp(N0) && N0->
hasOneUse()) {
17810 if (isContractableAndReassociableFMUL(N020) &&
17813 return matcher.getNode(
17816 PreferredFusedOpcode, SL, VT,
17819 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
17832 if (isFusedOp(N00)) {
17834 if (isContractableAndReassociableFMUL(N002) &&
17837 return matcher.getNode(
17838 PreferredFusedOpcode, SL, VT,
17842 PreferredFusedOpcode, SL, VT,
17845 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
17855 if (isContractableAndReassociableFMUL(N120) &&
17861 PreferredFusedOpcode, SL, VT,
17865 PreferredFusedOpcode, SL, VT,
17883 if (isContractableAndReassociableFMUL(N102) &&
17889 PreferredFusedOpcode, SL, VT,
17894 PreferredFusedOpcode, SL, VT,
17908SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *
N) {
17911 EVT VT =
N->getValueType(0);
17921 if (!
FAdd->getFlags().hasNoInfs())
17932 bool HasFMAD = LegalOperations && TLI.
isFMADLegal(DAG,
N);
17935 if (!HasFMAD && !HasFMA)
17947 if (
C->isExactlyValue(+1.0))
17948 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17950 if (
C->isExactlyValue(-1.0))
17951 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17958 if (
SDValue FMA = FuseFADD(N0, N1))
17960 if (
SDValue FMA = FuseFADD(N1, N0))
17970 if (C0->isExactlyValue(+1.0))
17971 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
17974 if (C0->isExactlyValue(-1.0))
17975 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
17980 if (C1->isExactlyValue(+1.0))
17981 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17983 if (C1->isExactlyValue(-1.0))
17984 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
17991 if (
SDValue FMA = FuseFSUB(N0, N1))
17993 if (
SDValue FMA = FuseFSUB(N1, N0))
17999SDValue DAGCombiner::visitVP_FADD(SDNode *
N) {
18000 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18003 if (
SDValue Fused = visitFADDForFMACombine<VPMatchContext>(
N)) {
18005 AddToWorklist(Fused.getNode());
18011SDValue DAGCombiner::visitFADD(SDNode *
N) {
18016 EVT VT =
N->getValueType(0);
18018 SDNodeFlags
Flags =
N->getFlags();
18019 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18029 if (N0CFP && !N1CFP)
18034 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18039 if (N1C && N1C->
isZero())
18044 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18050 N1, DAG, LegalOperations, ForCodeSize))
18056 N0, DAG, LegalOperations, ForCodeSize))
18063 return C &&
C->isExactlyValue(-2.0);
18067 if (isFMulNegTwo(N0)) {
18073 if (isFMulNegTwo(N1)) {
18084 if (
Flags.hasNoNaNs() && AllowNewConst) {
18097 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18115 if (CFP01 && !CFP00 && N0.
getOperand(0) == N1) {
18136 if (CFP11 && !CFP10 && N1.
getOperand(0) == N0) {
18183 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros()) {
18186 VT, N0, N1, Flags))
18191 if (
SDValue Fused = visitFADDForFMACombine<EmptyMatchContext>(
N)) {
18193 AddToWorklist(Fused.getNode());
18199SDValue DAGCombiner::visitSTRICT_FADD(SDNode *
N) {
18203 EVT VT =
N->getValueType(0);
18204 EVT ChainVT =
N->getValueType(1);
18206 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18211 N1, DAG, LegalOperations, ForCodeSize)) {
18213 {Chain, N0, NegN1});
18219 N0, DAG, LegalOperations, ForCodeSize)) {
18221 {Chain, N1, NegN0});
18226SDValue DAGCombiner::visitFSUB(SDNode *
N) {
18231 EVT VT =
N->getValueType(0);
18233 const SDNodeFlags
Flags =
N->getFlags();
18234 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18245 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18248 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18252 if (N1CFP && N1CFP->
isZero()) {
18261 if (
Flags.hasNoNaNs())
18266 if (N0CFP && N0CFP->
isZero()) {
18284 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18300 if (
SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(
N)) {
18301 AddToWorklist(Fused.getNode());
18323SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *
N) {
18324 EVT VT =
N->getValueType(0);
18330 std::optional<int> Mantissa;
18331 auto GetConstAndPow2Ops = [&](
unsigned ConstOpIdx) {
18332 if (ConstOpIdx == 1 &&
N->getOpcode() ==
ISD::FDIV)
18348 auto IsFPConstValid = [
N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
18349 if (CFP ==
nullptr)
18352 const APFloat &APF = CFP->getValueAPF();
18360 int CurExp =
ilogb(APF);
18363 N->getOpcode() ==
ISD::FMUL ? CurExp : (CurExp - MaxExpChange);
18366 N->getOpcode() ==
ISD::FDIV ? CurExp : (CurExp + MaxExpChange);
18374 Mantissa = ThisMantissa;
18376 return *Mantissa == ThisMantissa && ThisMantissa > 0;
18383 if (!GetConstAndPow2Ops(0) && !GetConstAndPow2Ops(1))
18411 NewIntVT, DAG.
getBitcast(NewIntVT, ConstOp), Shift);
18416SDValue DAGCombiner::visitFMUL(SDNode *
N) {
18420 EVT VT =
N->getValueType(0);
18422 const SDNodeFlags
Flags =
N->getFlags();
18423 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18439 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18442 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18445 if (
Flags.hasAllowReassociation()) {
18471 VT, N0, N1, Flags))
18495 HandleSDNode NegN0Handle(NegN0);
18505 if (
Flags.hasNoNaNs() &&
Flags.hasNoSignedZeros() &&
18516 if (TrueOpnd && FalseOpnd &&
18537 if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
18541 if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
18550 if (
SDValue Fused = visitFMULForFMADistributiveCombine(
N)) {
18551 AddToWorklist(Fused.getNode());
18557 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
18563template <
class MatchContextClass>
SDValue DAGCombiner::visitFMA(SDNode *
N) {
18570 EVT VT =
N->getValueType(0);
18573 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18574 MatchContextClass matcher(DAG, TLI,
N);
18589 HandleSDNode NegN0Handle(NegN0);
18597 if (
N->getFlags().hasNoNaNs() &&
N->getFlags().hasNoInfs()) {
18598 if (
N->getFlags().hasNoSignedZeros() ||
18600 if (N0CFP && N0CFP->
isZero())
18602 if (N1CFP && N1CFP->
isZero())
18611 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18616 return matcher.getNode(
ISD::FMA,
DL, VT, N1, N0, N2);
18618 bool CanReassociate =
N->getFlags().hasAllowReassociation();
18619 if (CanReassociate) {
18624 return matcher.getNode(
18633 return matcher.getNode(
18643 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18648 AddToWorklist(RHSNeg.
getNode());
18649 return matcher.getNode(
ISD::FADD,
DL, VT, N2, RHSNeg);
18663 if (CanReassociate) {
18665 if (N1CFP && N0 == N2) {
18683 SDValue(
N, 0), DAG, LegalOperations, ForCodeSize))
18688SDValue DAGCombiner::visitFMAD(SDNode *
N) {
18692 EVT VT =
N->getValueType(0);
18702SDValue DAGCombiner::visitFMULADD(SDNode *
N) {
18706 EVT VT =
N->getValueType(0);
18724SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *
N) {
18728 const SDNodeFlags
Flags =
N->getFlags();
18729 if (LegalDAG || !
Flags.hasAllowReciprocal())
18744 unsigned NumElts = 1;
18745 EVT VT =
N->getValueType(0);
18749 if (!MinUses || (N1->
use_size() * NumElts) < MinUses)
18754 SetVector<SDNode *>
Users;
18755 for (
auto *U : N1->
users()) {
18756 if (
U->getOpcode() ==
ISD::FDIV &&
U->getOperand(1) == N1) {
18758 if (
U->getOperand(1).getOpcode() ==
ISD::FSQRT &&
18759 U->getOperand(0) ==
U->getOperand(1).getOperand(0) &&
18760 U->getFlags().hasAllowReassociation() &&
18761 U->getFlags().hasNoSignedZeros())
18766 if (
U->getFlags().hasAllowReciprocal())
18773 if ((
Users.size() * NumElts) < MinUses)
18781 for (
auto *U :
Users) {
18782 SDValue Dividend =
U->getOperand(0);
18783 if (Dividend != FPOne) {
18785 Reciprocal, Flags);
18786 CombineTo(U, NewNode);
18787 }
else if (U != Reciprocal.
getNode()) {
18790 CombineTo(U, Reciprocal);
18796SDValue DAGCombiner::visitFDIV(SDNode *
N) {
18799 EVT VT =
N->getValueType(0);
18801 SDNodeFlags
Flags =
N->getFlags();
18802 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18813 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18816 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18833 (!LegalOperations ||
18843 if (
Flags.hasAllowReciprocal()) {
18852 N1AllowReciprocal) {
18883 A =
Y.getOperand(0);
18892 if (
SDValue Rsqrt = buildRsqrtEstimate(AAZ))
18896 recursivelyDeleteUnusedNodes(AAZ.
getNode());
18904 AddToWorklist(Div.
getNode());
18911 if (
Flags.hasNoInfs())
18912 if (
SDValue RV = BuildDivEstimate(N0, N1, Flags))
18918 Flags.hasAllowReassociation())
18930 HandleSDNode NegN0Handle(NegN0);
18938 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
18944SDValue DAGCombiner::visitFREM(SDNode *
N) {
18947 EVT VT =
N->getValueType(0);
18948 SDNodeFlags
Flags =
N->getFlags();
18949 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18959 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18969 bool NeedsCopySign = !
Flags.hasNoSignedZeros() &&
18988SDValue DAGCombiner::visitFSQRT(SDNode *
N) {
18989 SDNodeFlags
Flags =
N->getFlags();
18993 if (!
Flags.hasApproximateFuncs() || !
Flags.hasNoInfs())
19001 SelectionDAG::FlagInserter FlagInserter(DAG, Flags);
19006 return buildSqrtEstimate(N0);
19021 if (YTy == MVT::f128)
19038SDValue DAGCombiner::visitFCOPYSIGN(SDNode *
N) {
19041 EVT VT =
N->getValueType(0);
19079SDValue DAGCombiner::visitFPOW(SDNode *
N) {
19083 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19089 EVT VT =
N->getValueType(0);
19098 SDNodeFlags
Flags =
N->getFlags();
19099 if (!
Flags.hasNoSignedZeros() || !
Flags.hasNoInfs() || !
Flags.hasNoNaNs() ||
19100 !
Flags.hasApproximateFuncs())
19119 if (ExponentIs025 || ExponentIs075) {
19127 SDNodeFlags
Flags =
N->getFlags();
19130 if ((!
Flags.hasNoSignedZeros() && ExponentIs025) || !
Flags.hasNoInfs() ||
19131 !
Flags.hasApproximateFuncs())
19168 EVT VT =
N->getValueType(0);
19174 assert(IsSigned || IsUnsigned);
19179 if (IsSigned && !IsSignedZeroSafe)
19183 if (IsUnsigned && !IsSignedZeroSafe && !TLI.
isFAbsFree(VT))
19191 constexpr unsigned MaxClamps = 2;
19195 SDValue IntVal =
N->getOperand(0);
19196 for (
unsigned Level = 0; Level < MaxClamps; ++Level) {
19197 if (!IntVal.hasOneUse() ||
19198 (IntVal.getOpcode() != MinOp && IntVal.getOpcode() != MaxOp))
19203 IntConst = IntConstNode->getAPIntValue();
19213 !IsExact ||
static_cast<const APInt &
>(RoundTrip) != IntConst)
19215 bool IsMin = IntVal.getOpcode() == MinOp;
19217 IntVal = IntVal.getOperand(0);
19222 if (IntVal.getOpcode() != FPToIntOp ||
19223 IntVal.getOperand(0).getValueType() != VT)
19226 SDValue Result = IntVal.getOperand(0);
19227 if (IsUnsigned && !IsSignedZeroSafe && TLI.
isFAbsFree(VT))
19231 for (
const ClampInfo &Clamp :
reverse(Clamps)) {
19232 unsigned FPClampOp =
19236 Result = DAG.
getNode(FPClampOp,
DL, VT, Result, Clamp.Constant);
19241SDValue DAGCombiner::visitSINT_TO_FP(SDNode *
N) {
19243 EVT VT =
N->getValueType(0);
19295SDValue DAGCombiner::visitUINT_TO_FP(SDNode *
N) {
19297 EVT VT =
N->getValueType(0);
19341 EVT VT =
N->getValueType(0);
19347 EVT SrcVT = Src.getValueType();
19362 unsigned ActualSize = std::min(InputSize, OutputSize);
19371 return DAG.
getNode(ExtOp,
DL, VT, Src);
19380SDValue DAGCombiner::visitFP_TO_SINT(SDNode *
N) {
19382 EVT VT =
N->getValueType(0);
19396SDValue DAGCombiner::visitFP_TO_UINT(SDNode *
N) {
19398 EVT VT =
N->getValueType(0);
19412SDValue DAGCombiner::visitXROUND(SDNode *
N) {
19414 EVT VT =
N->getValueType(0);
19430SDValue DAGCombiner::visitFP_ROUND(SDNode *
N) {
19433 EVT VT =
N->getValueType(0);
19446 const bool NIsTrunc =
N->getConstantOperandVal(1) == 1;
19468 if ((
N->getFlags().hasAllowContract() &&
19486 AddToWorklist(Tmp.
getNode());
19490 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19500 EVT VT =
N->getValueType(0);
19502 unsigned NarrowingOp;
19503 switch (
N->getOpcode()) {
19533SDValue DAGCombiner::visitFP_EXTEND(SDNode *
N) {
19534 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19536 EVT VT =
N->getValueType(0);
19540 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
19560 if (
In.getValueType() == VT)
return In;
19574 CombineTo(
N, ExtLoad);
19583 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19587 return CastEliminated;
19592SDValue DAGCombiner::visitFCEIL(SDNode *
N) {
19594 EVT VT =
N->getValueType(0);
19603SDValue DAGCombiner::visitFTRUNC(SDNode *
N) {
19605 EVT VT =
N->getValueType(0);
19628SDValue DAGCombiner::visitFFREXP(SDNode *
N) {
19637SDValue DAGCombiner::visitFFLOOR(SDNode *
N) {
19639 EVT VT =
N->getValueType(0);
19648SDValue DAGCombiner::visitFNEG(SDNode *
N) {
19650 EVT VT =
N->getValueType(0);
19651 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19674 if (
SDValue Cast = foldSignChangeInBitcast(
N))
19680SDValue DAGCombiner::visitFMinMax(SDNode *
N) {
19683 EVT VT =
N->getValueType(0);
19684 const SDNodeFlags
Flags =
N->getFlags();
19685 unsigned Opc =
N->getOpcode();
19687 bool ReturnsOtherForAllNaNs =
19691 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19700 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0);
19712 if (PropAllNaNsToQNaNs) {
19716 }
else if (ReturnsOtherForAllNaNs || !AF.
isSignaling()) {
19717 return N->getOperand(0);
19730 (ReturnsOtherForAllNaNs ||
Flags.hasNoNaNs()))
19731 return N->getOperand(1);
19739 if (IsMin != AF.
isNegative() && (PropAllNaNsToQNaNs ||
Flags.hasNoNaNs()))
19740 return N->getOperand(0);
19748 if (
SDValue SD = reassociateReduction(
19752 Opc, SDLoc(
N), VT, N0, N1, Flags))
19758SDValue DAGCombiner::visitFABS(SDNode *
N) {
19760 EVT VT =
N->getValueType(0);
19770 if (
SDValue Cast = foldSignChangeInBitcast(
N))
19776SDValue DAGCombiner::visitBRCOND(SDNode *
N) {
19803 bool Updated =
false;
19815 return True || False;
19819 if (!IsAlwaysTrueOrFalse(
Cond, S1C)) {
19826 S1 =
S1->getOperand(0);
19857 HandleSDNode ChainHandle(Chain);
19858 if (
SDValue NewN1 = rebuildSetCC(N1))
19860 ChainHandle.getValue(), NewN1, N2,
N->getFlags());
19869 (
N.getOperand(0).hasOneUse() &&
19870 N.getOperand(0).getOpcode() ==
ISD::SRL))) {
19873 N =
N.getOperand(0);
19920 HandleSDNode XORHandle(
N);
19922 SDValue Tmp = visitXOR(
N.getNode());
19929 N = XORHandle.getValue();
19941 bool Equal =
false;
19951 EVT SetCCVT =
N.getValueType();
19960 return DAG.
getSetCC(SDLoc(
N), SetCCVT, Op0, Op1, CC);
19969SDValue DAGCombiner::visitBR_CC(SDNode *
N) {
19981 CondLHS, CondRHS, CC->
get(), SDLoc(
N),
19996 bool &IsLoad,
bool &IsMasked,
SDValue &Ptr,
19999 if (LD->isIndexed())
20001 EVT VT = LD->getMemoryVT();
20004 Ptr = LD->getBasePtr();
20006 if (ST->isIndexed())
20008 EVT VT = ST->getMemoryVT();
20011 Ptr = ST->getBasePtr();
20014 if (LD->isIndexed())
20016 EVT VT = LD->getMemoryVT();
20020 Ptr = LD->getBasePtr();
20023 if (ST->isIndexed())
20025 EVT VT = ST->getMemoryVT();
20029 Ptr = ST->getBasePtr();
20043bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *
N) {
20047 bool IsLoad =
true;
20048 bool IsMasked =
false;
20070 bool Swapped =
false;