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);
484 SDValue visitCTLZ_ZERO_UNDEF(SDNode *
N);
486 SDValue visitCTTZ_ZERO_UNDEF(SDNode *
N);
494 SDValue visitSIGN_EXTEND(SDNode *
N);
495 SDValue visitZERO_EXTEND(SDNode *
N);
498 SDValue visitAssertAlign(SDNode *
N);
499 SDValue visitSIGN_EXTEND_INREG(SDNode *
N);
500 SDValue visitEXTEND_VECTOR_INREG(SDNode *
N);
502 SDValue visitTRUNCATE_USAT_U(SDNode *
N);
509 SDValue visitSTRICT_FADD(SDNode *
N);
512 template <
class MatchContextClass>
SDValue visitFMA(SDNode *
N);
520 SDValue visitFCANONICALIZE(SDNode *
N);
540 SDValue replaceStoreOfFPConstant(StoreSDNode *ST);
541 SDValue replaceStoreOfInsertLoad(StoreSDNode *ST);
543 bool refineExtractVectorEltIntoMultipleNarrowExtractVectorElts(SDNode *
N);
546 SDValue visitATOMIC_STORE(SDNode *
N);
547 SDValue visitLIFETIME_END(SDNode *
N);
548 SDValue visitINSERT_VECTOR_ELT(SDNode *
N);
549 SDValue visitEXTRACT_VECTOR_ELT(SDNode *
N);
550 SDValue visitBUILD_VECTOR(SDNode *
N);
551 SDValue visitCONCAT_VECTORS(SDNode *
N);
552 SDValue visitVECTOR_INTERLEAVE(SDNode *
N);
553 SDValue visitEXTRACT_SUBVECTOR(SDNode *
N);
554 SDValue visitVECTOR_SHUFFLE(SDNode *
N);
555 SDValue visitSCALAR_TO_VECTOR(SDNode *
N);
556 SDValue visitINSERT_SUBVECTOR(SDNode *
N);
557 SDValue visitVECTOR_COMPRESS(SDNode *
N);
563 SDValue visitPARTIAL_REDUCE_MLA(SDNode *
N);
566 SDValue visitVP_STRIDED_LOAD(SDNode *
N);
567 SDValue visitVP_STRIDED_STORE(SDNode *
N);
574 SDValue visitGET_FPENV_MEM(SDNode *
N);
575 SDValue visitSET_FPENV_MEM(SDNode *
N);
577 template <
class MatchContextClass>
578 SDValue visitFADDForFMACombine(SDNode *
N);
579 template <
class MatchContextClass>
580 SDValue visitFSUBForFMACombine(SDNode *
N);
581 SDValue visitFMULForFMADistributiveCombine(SDNode *
N);
583 SDValue XformToShuffleWithZero(SDNode *
N);
584 bool reassociationCanBreakAddressingModePattern(
unsigned Opc,
590 SDValue N1, SDNodeFlags Flags);
592 SDValue N1, SDNodeFlags Flags);
593 SDValue reassociateReduction(
unsigned RedOpc,
unsigned Opc,
const SDLoc &
DL,
595 SDNodeFlags Flags = SDNodeFlags());
597 SDValue visitShiftByConstant(SDNode *
N);
599 SDValue foldSelectOfConstants(SDNode *
N);
600 SDValue foldVSelectOfConstants(SDNode *
N);
601 SDValue foldBinOpIntoSelect(SDNode *BO);
603 SDValue hoistLogicOpWithSameOpcodeHands(SDNode *
N);
607 bool NotExtCompare =
false);
608 SDValue convertSelectOfFPConstantsToLoadOffset(
611 SDValue foldSignChangeInBitcast(SDNode *
N);
614 SDValue foldSelectOfBinops(SDNode *
N);
618 SDValue foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL);
619 SDValue foldABSToABD(SDNode *
N,
const SDLoc &
DL);
624 SDValue unfoldMaskedMerge(SDNode *
N);
625 SDValue unfoldExtremeBitClearingToShifts(SDNode *
N);
627 const SDLoc &
DL,
bool foldBooleans);
631 SDValue &CC,
bool MatchStrict =
false)
const;
632 bool isOneUseSetCC(
SDValue N)
const;
634 SDValue foldAddToAvg(SDNode *
N,
const SDLoc &
DL);
635 SDValue foldSubToAvg(SDNode *
N,
const SDLoc &
DL);
639 SDValue SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
641 SDValue CombineConsecutiveLoads(SDNode *
N, EVT VT);
642 SDValue foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
643 const TargetLowering &TLI);
644 SDValue foldPartialReduceMLAMulOp(SDNode *
N);
645 SDValue foldPartialReduceAdd(SDNode *
N);
648 SDValue CombineZExtLogicopShiftLoad(SDNode *
N);
649 SDValue combineRepeatedFPDivisors(SDNode *
N);
650 SDValue combineFMulOrFDivWithIntPow2(SDNode *
N);
651 SDValue replaceShuffleOfInsert(ShuffleVectorSDNode *Shuf);
652 SDValue mergeInsertEltWithShuffle(SDNode *
N,
unsigned InsIndex);
653 SDValue combineInsertEltToShuffle(SDNode *
N,
unsigned InsIndex);
654 SDValue combineInsertEltToLoad(SDNode *
N,
unsigned InsIndex);
661 bool KnownNeverZero =
false,
662 bool InexpensiveOnly =
false,
663 std::optional<EVT> OutVT = std::nullopt);
673 bool DemandHighBits =
true);
677 bool HasPos,
unsigned PosOpcode,
678 unsigned NegOpcode,
const SDLoc &
DL);
681 bool HasPos,
unsigned PosOpcode,
682 unsigned NegOpcode,
const SDLoc &
DL);
685 SDValue MatchLoadCombine(SDNode *
N);
686 SDValue mergeTruncStores(StoreSDNode *
N);
688 SDValue ReduceLoadOpStoreWidth(SDNode *
N);
690 SDValue TransformFPLoadStorePair(SDNode *
N);
691 SDValue convertBuildVecZextToZext(SDNode *
N);
692 SDValue convertBuildVecZextToBuildVecWithZeros(SDNode *
N);
693 SDValue reduceBuildVecExtToExtBuildVec(SDNode *
N);
694 SDValue reduceBuildVecTruncToBitCast(SDNode *
N);
695 SDValue reduceBuildVecToShuffle(SDNode *
N);
696 SDValue createBuildVecShuffle(
const SDLoc &
DL, SDNode *
N,
697 ArrayRef<int> VectorMask,
SDValue VecIn1,
698 SDValue VecIn2,
unsigned LeftIdx,
700 SDValue matchVSelectOpSizesWithSetCC(SDNode *Cast);
704 void GatherAllAliases(SDNode *
N,
SDValue OriginalChain,
705 SmallVectorImpl<SDValue> &Aliases);
708 bool mayAlias(SDNode *Op0, SDNode *Op1)
const;
720 bool findBetterNeighborChains(StoreSDNode *St);
724 bool parallelizeChainedStores(StoreSDNode *St);
730 LSBaseSDNode *MemNode;
733 int64_t OffsetFromBase;
735 MemOpLink(LSBaseSDNode *
N, int64_t
Offset)
736 : MemNode(
N), OffsetFromBase(
Offset) {}
741 StoreSource getStoreSource(
SDValue StoreVal) {
745 return StoreSource::Constant;
749 return StoreSource::Constant;
750 return StoreSource::Unknown;
753 return StoreSource::Extract;
755 return StoreSource::Load;
757 return StoreSource::Unknown;
765 bool isMulAddWithConstProfitable(SDNode *MulNode,
SDValue AddNode,
771 bool isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
772 EVT LoadResultTy, EVT &ExtVT);
777 EVT &MemVT,
unsigned ShAmt = 0);
780 bool SearchForAndLoads(SDNode *
N, SmallVectorImpl<LoadSDNode*> &Loads,
781 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
782 ConstantSDNode *Mask, SDNode *&NodeToMask);
785 bool BackwardsPropagateMask(SDNode *
N);
789 SDValue getMergeStoreChains(SmallVectorImpl<MemOpLink> &StoreNodes,
801 bool mergeStoresOfConstantsOrVecElts(SmallVectorImpl<MemOpLink> &StoreNodes,
802 EVT MemVT,
unsigned NumStores,
803 bool IsConstantSrc,
bool UseVector,
809 SDNode *getStoreMergeCandidates(StoreSDNode *St,
810 SmallVectorImpl<MemOpLink> &StoreNodes);
816 bool checkMergeStoreCandidatesForDependencies(
817 SmallVectorImpl<MemOpLink> &StoreNodes,
unsigned NumStores,
822 bool hasCallInLdStChain(StoreSDNode *St, LoadSDNode *Ld);
827 unsigned getConsecutiveStores(SmallVectorImpl<MemOpLink> &StoreNodes,
828 int64_t ElementSizeBytes)
const;
832 bool tryStoreMergeOfConstants(SmallVectorImpl<MemOpLink> &StoreNodes,
833 unsigned NumConsecutiveStores,
834 EVT MemVT, SDNode *Root,
bool AllowVectors);
840 bool tryStoreMergeOfExtracts(SmallVectorImpl<MemOpLink> &StoreNodes,
841 unsigned NumConsecutiveStores, EVT MemVT,
846 bool tryStoreMergeOfLoads(SmallVectorImpl<MemOpLink> &StoreNodes,
847 unsigned NumConsecutiveStores, EVT MemVT,
848 SDNode *Root,
bool AllowVectors,
849 bool IsNonTemporalStore,
bool IsNonTemporalLoad);
854 bool mergeConsecutiveStores(StoreSDNode *St);
862 SDValue distributeTruncateThroughAnd(SDNode *
N);
868 bool hasOperation(
unsigned Opcode, EVT VT) {
869 return TLI.isOperationLegalOrCustom(Opcode, VT, LegalOperations);
872 bool hasUMin(EVT VT)
const {
873 auto LK = TLI.getTypeConversion(*DAG.getContext(), VT);
876 TLI.isOperationLegalOrCustom(
ISD::UMIN, LK.second);
883 SelectionDAG &getDAG()
const {
return DAG; }
886 EVT getShiftAmountTy(EVT LHSTy) {
887 return TLI.getShiftAmountTy(LHSTy, DAG.getDataLayout());
892 bool isTypeLegal(
const EVT &VT) {
893 if (!LegalTypes)
return true;
894 return TLI.isTypeLegal(VT);
898 EVT getSetCCResultType(EVT VT)
const {
899 return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
902 void ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
913 explicit WorklistRemover(DAGCombiner &dc)
914 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
916 void NodeDeleted(SDNode *
N, SDNode *
E)
override {
917 DC.removeFromWorklist(
N);
925 explicit WorklistInserter(DAGCombiner &dc)
926 : SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
930 void NodeInserted(SDNode *
N)
override { DC.ConsiderForPruning(
N); }
940 ((DAGCombiner*)
DC)->AddToWorklist(
N);
945 return ((DAGCombiner*)
DC)->CombineTo(
N, &To[0], To.
size(), AddTo);
950 return ((DAGCombiner*)
DC)->CombineTo(
N, Res, AddTo);
955 return ((DAGCombiner*)
DC)->CombineTo(
N, Res0, Res1, AddTo);
960 return ((DAGCombiner*)
DC)->recursivelyDeleteUnusedNodes(
N);
965 return ((DAGCombiner*)
DC)->CommitTargetLoweringOpt(TLO);
972void DAGCombiner::deleteAndRecombine(
SDNode *
N) {
973 removeFromWorklist(
N);
981 if (
Op->hasOneUse() ||
Op->getNumValues() > 1)
982 AddToWorklist(
Op.getNode());
991 unsigned Bits =
Offset + std::max(
LHS.getBitWidth(),
RHS.getBitWidth());
1002 SDValue &CC,
bool MatchStrict)
const {
1004 LHS =
N.getOperand(0);
1005 RHS =
N.getOperand(1);
1013 LHS =
N.getOperand(1);
1014 RHS =
N.getOperand(2);
1027 LHS =
N.getOperand(0);
1028 RHS =
N.getOperand(1);
1036bool DAGCombiner::isOneUseSetCC(
SDValue N)
const {
1038 if (isSetCCEquivalent(
N, N0, N1, N2) &&
N->hasOneUse())
1050 MaskForTy = 0xFFULL;
1053 MaskForTy = 0xFFFFULL;
1056 MaskForTy = 0xFFFFFFFFULL;
1074 bool AllowTruncation =
false) {
1076 return !(Const->isOpaque() && NoOpaques);
1079 unsigned BitWidth =
N.getScalarValueSizeInBits();
1084 if (!Const || (Const->isOpaque() && NoOpaques))
1088 if ((AllowTruncation &&
1089 Const->getAPIntValue().getActiveBits() >
BitWidth) ||
1090 (!AllowTruncation && Const->getAPIntValue().getBitWidth() !=
BitWidth))
1112bool DAGCombiner::reassociationCanBreakAddressingModePattern(
unsigned Opc,
1140 : (N1.
getOperand(0).getConstantOperandVal(0) *
1145 ScalableOffset = -ScalableOffset;
1146 if (
all_of(
N->users(), [&](SDNode *Node) {
1147 if (auto *LoadStore = dyn_cast<MemSDNode>(Node);
1148 LoadStore && LoadStore->hasUniqueMemOperand() &&
1149 LoadStore->getBasePtr().getNode() == N) {
1150 TargetLoweringBase::AddrMode AM;
1151 AM.HasBaseReg = true;
1152 AM.ScalableOffset = ScalableOffset;
1153 EVT VT = LoadStore->getMemoryVT();
1154 unsigned AS = LoadStore->getAddressSpace();
1155 Type *AccessTy = VT.getTypeForEVT(*DAG.getContext());
1156 return TLI.isLegalAddressingMode(DAG.getDataLayout(), AM, AccessTy,
1171 const APInt &C2APIntVal = C2->getAPIntValue();
1179 const APInt &C1APIntVal = C1->getAPIntValue();
1180 const APInt CombinedValueIntVal = C1APIntVal + C2APIntVal;
1183 const int64_t CombinedValue = CombinedValueIntVal.
getSExtValue();
1185 for (SDNode *Node :
N->users()) {
1192 TargetLoweringBase::AddrMode AM;
1194 AM.
BaseOffs = C2APIntVal.getSExtValue();
1196 unsigned AS =
LoadStore->getAddressSpace();
1212 for (SDNode *Node :
N->users()) {
1214 if (!LoadStore || !
LoadStore->hasUniqueMemOperand())
1219 TargetLoweringBase::AddrMode AM;
1221 AM.
BaseOffs = C2APIntVal.getSExtValue();
1223 unsigned AS =
LoadStore->getAddressSpace();
1236SDValue DAGCombiner::reassociateOpsCommutative(
unsigned Opc,
const SDLoc &
DL,
1238 SDNodeFlags Flags) {
1248 SDNodeFlags NewFlags;
1250 Flags.hasNoUnsignedWrap())
1258 return DAG.
getNode(
Opc,
DL, VT, N00, OpNode, NewFlags);
1266 return DAG.
getNode(
Opc,
DL, VT, OpNode, N01, NewFlags);
1276 if (N1 == N00 || N1 == N01)
1322 if (CC1 == CC00 && CC1 != CC01) {
1326 if (CC1 == CC01 && CC1 != CC00) {
1340 SDValue N1, SDNodeFlags Flags) {
1346 if (!
Flags.hasAllowReassociation() || !
Flags.hasNoSignedZeros())
1349 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N0, N1, Flags))
1351 if (
SDValue Combined = reassociateOpsCommutative(
Opc,
DL, N1, N0, Flags))
1359SDValue DAGCombiner::reassociateReduction(
unsigned RedOpc,
unsigned Opc,
1361 SDValue N1, SDNodeFlags Flags) {
1367 SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
1389 A.getValueType() ==
C.getValueType() &&
1390 hasOperation(
Opc,
A.getValueType()) &&
1398 SelectionDAG::FlagInserter FlagsInserter(
1409SDValue DAGCombiner::CombineTo(SDNode *
N,
const SDValue *To,
unsigned NumTo,
1411 assert(
N->getNumValues() == NumTo &&
"Broken CombineTo call!");
1415 dbgs() <<
" and " << NumTo - 1 <<
" other values\n");
1416 for (
unsigned i = 0, e = NumTo; i !=
e; ++i)
1418 N->getValueType(i) == To[i].getValueType()) &&
1419 "Cannot combine value to value of different type!");
1421 WorklistRemover DeadNodes(*
this);
1425 for (
unsigned i = 0, e = NumTo; i !=
e; ++i) {
1427 AddToWorklistWithUsers(To[i].
getNode());
1435 deleteAndRecombine(
N);
1440CommitTargetLoweringOpt(
const TargetLowering::TargetLoweringOpt &TLO) {
1453 recursivelyDeleteUnusedNodes(TLO.
Old.
getNode());
1458bool DAGCombiner::SimplifyDemandedBits(
SDValue Op,
const APInt &DemandedBits,
1459 const APInt &DemandedElts,
1460 bool AssumeSingleUse) {
1461 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1468 AddToWorklist(
Op.getNode());
1470 CommitTargetLoweringOpt(TLO);
1477bool DAGCombiner::SimplifyDemandedVectorElts(
SDValue Op,
1478 const APInt &DemandedElts,
1479 bool AssumeSingleUse) {
1480 TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations);
1481 APInt KnownUndef, KnownZero;
1483 TLO, 0, AssumeSingleUse))
1487 AddToWorklist(
Op.getNode());
1489 CommitTargetLoweringOpt(TLO);
1493void DAGCombiner::ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad) {
1495 EVT VT =
Load->getValueType(0);
1504 AddToWorklist(Trunc.
getNode());
1505 recursivelyDeleteUnusedNodes(Load);
1513 EVT MemVT =
LD->getMemoryVT();
1515 :
LD->getExtensionType();
1518 LD->getChain(),
LD->getBasePtr(),
1519 MemVT,
LD->getMemOperand());
1522 unsigned Opc =
Op.getOpcode();
1526 if (
SDValue Op0 = SExtPromoteOperand(
Op.getOperand(0), PVT))
1530 if (
SDValue Op0 = ZExtPromoteOperand(
Op.getOperand(0), PVT))
1548 EVT OldVT =
Op.getValueType();
1554 AddToWorklist(NewOp.
getNode());
1557 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1563 EVT OldVT =
Op.getValueType();
1569 AddToWorklist(NewOp.
getNode());
1572 ReplaceLoadWithPromotedLoad(
Op.getNode(), NewOp.
getNode());
1580 if (!LegalOperations)
1583 EVT VT =
Op.getValueType();
1589 unsigned Opc =
Op.getOpcode();
1597 assert(PVT != VT &&
"Don't know what type to promote to!");
1601 bool Replace0 =
false;
1603 SDValue NN0 = PromoteOperand(N0, PVT, Replace0);
1605 bool Replace1 =
false;
1607 SDValue NN1 = PromoteOperand(N1, PVT, Replace1);
1619 Replace1 &= (N0 != N1) && !N1->
hasOneUse();
1622 CombineTo(
Op.getNode(), RV);
1648 if (!LegalOperations)
1651 EVT VT =
Op.getValueType();
1657 unsigned Opc =
Op.getOpcode();
1665 assert(PVT != VT &&
"Don't know what type to promote to!");
1669 SDNodeFlags TruncFlags;
1673 N0 = SExtPromoteOperand(N0, PVT);
1675 N0 = ZExtPromoteOperand(N0, PVT);
1677 if (
Op->getFlags().hasNoUnsignedWrap()) {
1678 N0 = ZExtPromoteOperand(N0, PVT);
1680 }
else if (
Op->getFlags().hasNoSignedWrap()) {
1681 N0 = SExtPromoteOperand(N0, PVT);
1684 N0 = PromoteOperand(N0, PVT,
Replace);
1697 ReplaceLoadWithPromotedLoad(
Op.getOperand(0).getNode(), N0.
getNode());
1707 if (!LegalOperations)
1710 EVT VT =
Op.getValueType();
1716 unsigned Opc =
Op.getOpcode();
1724 assert(PVT != VT &&
"Don't know what type to promote to!");
1729 return DAG.
getNode(
Op.getOpcode(), SDLoc(
Op), VT,
Op.getOperand(0));
1734bool DAGCombiner::PromoteLoad(
SDValue Op) {
1735 if (!LegalOperations)
1741 EVT VT =
Op.getValueType();
1747 unsigned Opc =
Op.getOpcode();
1755 assert(PVT != VT &&
"Don't know what type to promote to!");
1758 SDNode *
N =
Op.getNode();
1760 EVT MemVT =
LD->getMemoryVT();
1762 :
LD->getExtensionType();
1764 LD->getChain(),
LD->getBasePtr(),
1765 MemVT,
LD->getMemOperand());
1774 AddToWorklist(
Result.getNode());
1775 recursivelyDeleteUnusedNodes(
N);
1788bool DAGCombiner::recursivelyDeleteUnusedNodes(SDNode *
N) {
1789 if (!
N->use_empty())
1792 SmallSetVector<SDNode *, 16> Nodes;
1799 if (
N->use_empty()) {
1800 for (
const SDValue &ChildN :
N->op_values())
1801 Nodes.
insert(ChildN.getNode());
1803 removeFromWorklist(
N);
1808 }
while (!Nodes.
empty());
1823 WorklistInserter AddNodes(*
this);
1831 for (SDNode &Node : DAG.
allnodes())
1832 AddToWorklist(&Node,
Node.use_empty());
1837 HandleSDNode Dummy(DAG.
getRoot());
1840 while (SDNode *
N = getNextWorklistEntry()) {
1844 if (recursivelyDeleteUnusedNodes(
N))
1847 WorklistRemover DeadNodes(*
this);
1852 SmallSetVector<SDNode *, 16> UpdatedNodes;
1855 for (SDNode *LN : UpdatedNodes)
1856 AddToWorklistWithUsers(LN);
1868 for (
const SDValue &ChildN :
N->op_values())
1869 AddToWorklist(ChildN.getNode(),
true,
1880 ChainsWithoutMergeableStores.
clear();
1891 "Node was deleted but visit returned new node!");
1899 N->getNumValues() == 1 &&
"Type mismatch");
1909 AddToWorklistWithUsers(RV.
getNode());
1915 recursivelyDeleteUnusedNodes(
N);
1919 DAG.
setRoot(Dummy.getValue());
1923SDValue DAGCombiner::visit(SDNode *
N) {
1925 switch (
N->getOpcode()) {
1952 case ISD::MUL:
return visitMUL<EmptyMatchContext>(
N);
2019 case ISD::FMA:
return visitFMA<EmptyMatchContext>(
N);
2072 return visitPARTIAL_REDUCE_MLA(
N);
2098#define BEGIN_REGISTER_VP_SDNODE(SDOPC, ...) case ISD::SDOPC:
2099#include "llvm/IR/VPIntrinsics.def"
2100 return visitVPOp(
N);
2106SDValue DAGCombiner::combine(SDNode *
N) {
2111 if (!DisableGenericCombines)
2117 "Node was deleted but visit returned NULL!");
2123 TargetLowering::DAGCombinerInfo
2124 DagCombineInfo(DAG, Level,
false,
this);
2132 switch (
N->getOpcode()) {
2140 RV = PromoteIntBinOp(
SDValue(
N, 0));
2145 RV = PromoteIntShiftOp(
SDValue(
N, 0));
2181 if (
unsigned NumOps =
N->getNumOperands()) {
2182 if (
N->getOperand(0).getValueType() == MVT::Other)
2183 return N->getOperand(0);
2184 if (
N->getOperand(
NumOps-1).getValueType() == MVT::Other)
2185 return N->getOperand(
NumOps-1);
2186 for (
unsigned i = 1; i <
NumOps-1; ++i)
2187 if (
N->getOperand(i).getValueType() == MVT::Other)
2188 return N->getOperand(i);
2193SDValue DAGCombiner::visitFCANONICALIZE(SDNode *
N) {
2194 SDValue Operand =
N->getOperand(0);
2206SDValue DAGCombiner::visitTokenFactor(SDNode *
N) {
2209 if (
N->getNumOperands() == 2) {
2211 return N->getOperand(0);
2213 return N->getOperand(1);
2228 AddToWorklist(*(
N->user_begin()));
2232 SmallPtrSet<SDNode*, 16> SeenOps;
2240 for (
unsigned i = 0; i < TFs.
size(); ++i) {
2245 for (
unsigned j = i;
j < TFs.
size();
j++)
2246 Ops.emplace_back(TFs[j], 0);
2253 SDNode *TF = TFs[i];
2256 switch (
Op.getOpcode()) {
2274 if (SeenOps.
insert(
Op.getNode()).second)
2285 for (
unsigned i = 1, e = TFs.
size(); i < e; i++)
2286 AddToWorklist(TFs[i]);
2296 SmallVector<unsigned, 8> OpWorkCount;
2297 SmallPtrSet<SDNode *, 16> SeenChains;
2298 bool DidPruneOps =
false;
2300 unsigned NumLeftToConsider = 0;
2302 Worklist.
push_back(std::make_pair(
Op.getNode(), NumLeftToConsider++));
2306 auto AddToWorklist = [&](
unsigned CurIdx, SDNode *
Op,
unsigned OpNumber) {
2312 unsigned OrigOpNumber = 0;
2313 while (OrigOpNumber <
Ops.size() &&
Ops[OrigOpNumber].getNode() !=
Op)
2316 "expected to find TokenFactor Operand");
2318 for (
unsigned i = CurIdx + 1; i < Worklist.
size(); ++i) {
2319 if (Worklist[i].second == OrigOpNumber) {
2320 Worklist[i].second = OpNumber;
2323 OpWorkCount[OpNumber] += OpWorkCount[OrigOpNumber];
2324 OpWorkCount[OrigOpNumber] = 0;
2325 NumLeftToConsider--;
2328 if (SeenChains.
insert(
Op).second) {
2329 OpWorkCount[OpNumber]++;
2334 for (
unsigned i = 0; i < Worklist.
size() && i < 1024; ++i) {
2336 if (NumLeftToConsider <= 1)
2338 auto CurNode = Worklist[i].first;
2339 auto CurOpNumber = Worklist[i].second;
2340 assert((OpWorkCount[CurOpNumber] > 0) &&
2341 "Node should not appear in worklist");
2342 switch (CurNode->getOpcode()) {
2348 NumLeftToConsider++;
2351 for (
const SDValue &
Op : CurNode->op_values())
2352 AddToWorklist(i,
Op.getNode(), CurOpNumber);
2358 AddToWorklist(i, CurNode->getOperand(0).getNode(), CurOpNumber);
2362 AddToWorklist(i, MemNode->getChain().getNode(), CurOpNumber);
2365 OpWorkCount[CurOpNumber]--;
2366 if (OpWorkCount[CurOpNumber] == 0)
2367 NumLeftToConsider--;
2381 if (SeenChains.
count(
Op.getNode()) == 0)
2395SDValue DAGCombiner::visitMERGE_VALUES(SDNode *
N) {
2396 WorklistRemover DeadNodes(*
this);
2402 AddUsersToWorklist(
N);
2407 }
while (!
N->use_empty());
2408 deleteAndRecombine(
N);
2416 return Const !=
nullptr && !Const->isOpaque() ? Const :
nullptr;
2426 Op =
N->getOperand(0);
2428 if (
N->getFlags().hasNoUnsignedWrap())
2433 if (
N.getValueType().getScalarType() != MVT::i1 ||
2450 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2452 VT = LD->getMemoryVT();
2453 AS = LD->getAddressSpace();
2455 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2457 VT = ST->getMemoryVT();
2458 AS = ST->getAddressSpace();
2460 if (LD->isIndexed() || LD->getBasePtr().getNode() !=
N)
2462 VT = LD->getMemoryVT();
2463 AS = LD->getAddressSpace();
2465 if (ST->isIndexed() || ST->getBasePtr().getNode() !=
N)
2467 VT = ST->getMemoryVT();
2468 AS = ST->getAddressSpace();
2474 if (
N->isAnyAdd()) {
2483 }
else if (
N->getOpcode() ==
ISD::SUB) {
2505 bool ShouldCommuteOperands) {
2511 if (ShouldCommuteOperands)
2525 unsigned Opcode =
N->getOpcode();
2526 EVT VT =
N->getValueType(0);
2531 unsigned OpNo = ShouldCommuteOperands ? 0 : 1;
2551SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
2554 "Unexpected binary operator");
2566 unsigned SelOpNo = 0;
2603 bool CanFoldNonConst =
2609 if (!CanFoldNonConst &&
2618 if (CanFoldNonConst) {
2637 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CT, CBO});
2642 : DAG.FoldConstantArithmetic(BinOpcode,
DL, VT, {CF, CBO});
2653 "Expecting add or sub");
2658 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2659 SDValue C = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2660 SDValue Z = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2666 if (Z.getOperand(0).getValueType() != MVT::i1)
2678 EVT VT =
C.getValueType();
2686SDValue DAGCombiner::foldSubToAvg(SDNode *
N,
const SDLoc &
DL) {
2691 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
2696 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
2707SDValue DAGCombiner::visitPTRADD(SDNode *
N) {
2717 "PTRADD with different operand types is not supported");
2728 !reassociationCanBreakAddressingModePattern(
ISD::PTRADD,
DL,
N, N0, N1)) {
2739 if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
2744 AddToWorklist(
Add.getNode());
2768 if (
const GlobalAddressSDNode *GA =
2783 AddToWorklist(Inner.
getNode());
2805 SDNodeFlags CommonFlags =
N->getFlags() & N1->
getFlags();
2813 if (ZIsConstant != YIsConstant) {
2817 AddToWorklist(Inner.
getNode());
2827 bool TransformCannotBreakAddrMode =
none_of(
N->users(), [&](SDNode *User) {
2828 return canFoldInAddressingMode(N, User, DAG, TLI);
2831 if (TransformCannotBreakAddrMode)
2843 "Expecting add or sub");
2847 bool IsAdd =
N->getOpcode() ==
ISD::ADD;
2848 SDValue ConstantOp = IsAdd ?
N->getOperand(1) :
N->getOperand(0);
2849 SDValue ShiftOp = IsAdd ?
N->getOperand(0) :
N->getOperand(1);
2871 {ConstantOp, DAG.getConstant(1, DL, VT)})) {
2873 Not.getOperand(0), ShAmt);
2889SDValue DAGCombiner::visitADDLike(SDNode *
N) {
2915 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
2947 if ((!LegalOperations ||
2950 X.getScalarValueSizeInBits() == 1) {
2966 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
2970 if (!reassociationCanBreakAddressingModePattern(
ISD::ADD,
DL,
N, N0, N1)) {
3057 auto MatchUSUBSAT = [](ConstantSDNode *
Max, ConstantSDNode *
Op) {
3058 return (!Max && !
Op) ||
3059 (
Max &&
Op &&
Max->getAPIntValue() == (-
Op->getAPIntValue()));
3100 !
N->getFlags().hasNoSignedWrap()))) {
3121 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3125 if (
N->getFlags().hasNoUnsignedWrap() &&
3129 if (
N->getFlags().hasNoSignedWrap() &&
3138 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3146 (CA * CM + CB->getAPIntValue()).getSExtValue())) {
3152 if (
N->getFlags().hasNoUnsignedWrap() &&
3157 if (
N->getFlags().hasNoSignedWrap() &&
3168 DAG.
getConstant(CA * CM + CB->getAPIntValue(),
DL, VT), Flags);
3173 if (
SDValue Combined = visitADDLikeCommutative(N0, N1,
N))
3176 if (
SDValue Combined = visitADDLikeCommutative(N1, N0,
N))
3185SDValue DAGCombiner::foldAddToAvg(SDNode *
N,
const SDLoc &
DL) {
3211 if ((!LegalOperations || hasOperation(
ISD::AVGCEILU, VT)) &&
3218 if ((!LegalOperations || hasOperation(
ISD::AVGCEILS, VT)) &&
3229SDValue DAGCombiner::visitADD(SDNode *
N) {
3235 if (
SDValue Combined = visitADDLike(
N))
3244 if (
SDValue V = MatchRotate(N0, N1, SDLoc(
N),
true))
3278 APInt NewStep = C0 + C1;
3288 APInt NewStep = SV0 + SV1;
3296SDValue DAGCombiner::visitADDSAT(SDNode *
N) {
3297 unsigned Opcode =
N->getOpcode();
3315 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
3319 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
3339 bool ForceCarryReconstruction =
false) {
3344 if (ForceCarryReconstruction && V.getValueType() == MVT::i1)
3348 V = V.getOperand(0);
3353 if (ForceCarryReconstruction)
3357 V = V.getOperand(0);
3365 if (V.getResNo() != 1)
3372 EVT VT = V->getValueType(0);
3416 SDNode *LocReference) {
3418 SDLoc
DL(LocReference);
3480 if (TN->
getVT() == MVT::i1) {
3497 DAG.
getVTList(VT, Carry.getValueType()), N0,
3503SDValue DAGCombiner::visitADDC(SDNode *
N) {
3510 if (!
N->hasAnyUseOfValue(1))
3550 return V.getOperand(0);
3556SDValue DAGCombiner::visitADDO(SDNode *
N) {
3562 EVT CarryVT =
N->getValueType(1);
3566 if (!
N->hasAnyUseOfValue(1))
3573 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
3598 if (
SDValue Combined = visitUADDOLike(N0, N1,
N))
3601 if (
SDValue Combined = visitUADDOLike(N1, N0,
N))
3632SDValue DAGCombiner::visitADDE(SDNode *
N) {
3651SDValue DAGCombiner::visitUADDO_CARRY(SDNode *
N) {
3665 if (!LegalOperations ||
3675 AddToWorklist(CarryExt.
getNode());
3681 if (
SDValue Combined = visitUADDO_CARRYLike(N0, N1, CarryIn,
N))
3684 if (
SDValue Combined = visitUADDO_CARRYLike(N1, N0, CarryIn,
N))
3831 EVT CarryOutType =
N->getValueType(0);
3847 unsigned CarryInOperandNum =
3849 if (Opcode ==
ISD::USUBO && CarryInOperandNum != 1)
3940SDValue DAGCombiner::visitSADDO_CARRY(SDNode *
N) {
3954 if (!LegalOperations ||
3959 if (
SDValue Combined = visitSADDO_CARRYLike(N0, N1, CarryIn,
N))
3962 if (
SDValue Combined = visitSADDO_CARRYLike(N1, N0, CarryIn,
N))
3974 "Illegal truncation");
3998SDValue DAGCombiner::foldSubToUSubSat(EVT DstVT, SDNode *
N,
const SDLoc &
DL) {
4000 !(!LegalOperations || hasOperation(
ISD::USUBSAT, DstVT)))
4003 EVT SubVT =
N->getValueType(0);
4071template <
class MatchContextClass>
4094 if ((
BitWidth - Src.getValueType().getScalarSizeInBits()) != BitWidthDiff)
4105 unsigned AndMaskWidth =
BitWidth - BitWidthDiff;
4106 if (!(AndMask.
isMask(AndMaskWidth) && XorMask.
countr_one() >= AndMaskWidth))
4141 if (
SDValue Res = CheckAndFoldMulCase(Mul0, Mul1))
4144 if (
SDValue Res = CheckAndFoldMulCase(Mul1, Mul0))
4182SDValue DAGCombiner::visitSUB(SDNode *
N) {
4202 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4229 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4252 if (
N->getFlags().hasNoUnsignedWrap())
4258 if (
N->getFlags().hasNoSignedWrap())
4284 if (hasOperation(NewOpc, VT))
4426 if (!reassociationCanBreakAddressingModePattern(
ISD::SUB,
DL,
N, N0, N1) &&
4464 if ((!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4474 if (GA->getGlobal() == GB->getGlobal())
4475 return DAG.
getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
4482 if (TN->
getVT() == MVT::i1) {
4493 if (!
IntVal.isPowerOf2() ||
4538 DAG.
getVTList(VT, Carry.getValueType()), NegX, Zero,
4546 if (!C0->isOpaque()) {
4547 const APInt &C0Val = C0->getAPIntValue();
4548 const APInt &MaybeOnes = ~DAG.computeKnownBits(N1).Zero;
4549 if ((C0Val - MaybeOnes) == (C0Val ^ MaybeOnes))
4555 if ((!LegalOperations || hasOperation(
ISD::ABDS, VT)) &&
4567 if ((!LegalOperations || hasOperation(
ISD::ABDU, VT)) &&
4581SDValue DAGCombiner::visitSUBSAT(SDNode *
N) {
4582 unsigned Opcode =
N->getOpcode();
4603 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4622SDValue DAGCombiner::visitSUBC(SDNode *
N) {
4629 if (!
N->hasAnyUseOfValue(1))
4650SDValue DAGCombiner::visitSUBO(SDNode *
N) {
4656 EVT CarryVT =
N->getValueType(1);
4660 if (!
N->hasAnyUseOfValue(1))
4692SDValue DAGCombiner::visitSUBE(SDNode *
N) {
4704SDValue DAGCombiner::visitUSUBO_CARRY(SDNode *
N) {
4711 if (!LegalOperations ||
4719SDValue DAGCombiner::visitSSUBO_CARRY(SDNode *
N) {
4726 if (!LegalOperations ||
4736SDValue DAGCombiner::visitMULFIX(SDNode *
N) {
4749 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0, Scale);
4758template <
class MatchContextClass>
SDValue DAGCombiner::visitMUL(SDNode *
N) {
4764 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
4765 MatchContextClass Matcher(DAG, TLI,
N);
4780 bool N1IsConst =
false;
4781 bool N1IsOpaqueConst =
false;
4788 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
4793 "Splat APInt should be element width");
4803 if (N1IsConst && ConstValue1.
isZero())
4807 if (N1IsConst && ConstValue1.
isOne())
4811 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
4815 if (N1IsConst && ConstValue1.
isAllOnes())
4821 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
4825 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap());
4827 return Matcher.getNode(
ISD::SHL,
DL, VT, N0, Trunc, Flags);
4833 unsigned Log2Val = (-ConstValue1).logBase2();
4837 return Matcher.getNode(
4848 SDVTList LoHiVT = DAG.
getVTList(VT, VT);
4851 if (LoHi->hasAnyUseOfValue(1))
4854 if (LoHi->hasAnyUseOfValue(1))
4875 if (!UseVP && N1IsConst &&
4881 APInt MulC = ConstValue1.
abs();
4883 unsigned TZeros = MulC == 2 ? 0 : MulC.
countr_zero();
4885 if ((MulC - 1).isPowerOf2())
4887 else if ((MulC + 1).isPowerOf2())
4892 MathOp ==
ISD::ADD ? (MulC - 1).logBase2() : (MulC + 1).logBase2();
4895 "multiply-by-constant generated out of bounds shift");
4899 TZeros ? DAG.
getNode(MathOp,
DL, VT, Shl,
4941 return Matcher.getNode(
4962 APInt NewStep = C0 * MulVal;
4968 if (!UseVP && (!LegalOperations || hasOperation(
ISD::ABS, VT)) &&
4982 SmallBitVector ClearMask;
4984 auto IsClearMask = [&ClearMask](ConstantSDNode *
V) {
4985 if (!V ||
V->isZero()) {
4999 for (
unsigned I = 0;
I != NumElts; ++
I)
5030 EVT NodeType =
Node->getValueType(0);
5031 if (!NodeType.isSimple())
5033 switch (NodeType.getSimpleVT().SimpleTy) {
5034 default:
return false;
5035 case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
5036 case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
5037 case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
5038 case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
5039 case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
5046SDValue DAGCombiner::useDivRem(SDNode *Node) {
5047 if (
Node->use_empty())
5050 unsigned Opcode =
Node->getOpcode();
5055 EVT VT =
Node->getValueType(0);
5069 unsigned OtherOpcode = 0;
5083 for (SDNode *User : Op0->
users()) {
5090 unsigned UserOpc =
User->getOpcode();
5091 if ((UserOpc == Opcode || UserOpc == OtherOpcode || UserOpc == DivRemOpc) &&
5092 User->getOperand(0) == Op0 &&
5093 User->getOperand(1) == Op1) {
5095 if (UserOpc == OtherOpcode) {
5097 combined = DAG.
getNode(DivRemOpc, SDLoc(Node), VTs, Op0, Op1);
5098 }
else if (UserOpc == DivRemOpc) {
5101 assert(UserOpc == Opcode);
5106 CombineTo(User, combined);
5108 CombineTo(User, combined.
getValue(1));
5117 EVT VT =
N->getValueType(0);
5120 unsigned Opc =
N->getOpcode();
5139 if (N0C && N0C->
isZero())
5159SDValue DAGCombiner::visitSDIV(SDNode *
N) {
5162 EVT VT =
N->getValueType(0);
5172 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5189 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5197 if (
SDValue V = visitSDIVLike(N0, N1,
N)) {
5204 if (!
N->getFlags().hasExact()) {
5207 AddToWorklist(
Mul.getNode());
5208 AddToWorklist(
Sub.getNode());
5209 CombineTo(RemNode,
Sub);
5230 if (
C->isZero() ||
C->isOpaque())
5232 if (
C->getAPIntValue().isPowerOf2())
5234 if (
C->getAPIntValue().isNegatedPowerOf2())
5245 EVT VT =
N->getValueType(0);
5256 if ((!
N->getFlags().hasExact() ||
BitWidth > MaxLegalDivRemBitWidth) &&
5274 AddToWorklist(Sign.
getNode());
5280 AddToWorklist(
Add.getNode());
5291 Sra = DAG.
getSelect(
DL, VT, IsOneOrAllOnes, N0, Sra);
5317SDValue DAGCombiner::visitUDIV(SDNode *
N) {
5320 EVT VT =
N->getValueType(0);
5330 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5344 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5347 if (
SDValue V = visitUDIVLike(N0, N1,
N)) {
5354 if (!
N->getFlags().hasExact()) {
5357 AddToWorklist(
Mul.getNode());
5358 AddToWorklist(
Sub.getNode());
5359 CombineTo(RemNode,
Sub);
5384 EVT VT =
N->getValueType(0);
5389 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5390 AddToWorklist(LogBase2.getNode());
5394 AddToWorklist(Trunc.
getNode());
5404 if (
SDValue LogBase2 = BuildLogBase2(N10,
DL)) {
5405 AddToWorklist(LogBase2.getNode());
5409 AddToWorklist(Trunc.
getNode());
5411 AddToWorklist(
Add.getNode());
5439SDValue DAGCombiner::visitREM(SDNode *
N) {
5440 unsigned Opcode =
N->getOpcode();
5443 EVT VT =
N->getValueType(0);
5465 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
5478 AddToWorklist(
Add.getNode());
5495 if (
SDValue OptimizedRem = buildOptimizedSREM(N0, N1,
N))
5496 return OptimizedRem;
5500 isSigned ? visitSDIVLike(N0, N1,
N) : visitUDIVLike(N0, N1,
N);
5503 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
5504 if (SDNode *DivNode = DAG.getNodeIfExists(DivOpcode, N->getVTList(),
5506 CombineTo(DivNode, OptimizedDiv);
5509 AddToWorklist(OptimizedDiv.
getNode());
5510 AddToWorklist(
Mul.getNode());
5517 return DivRem.getValue(1);
5540SDValue DAGCombiner::visitMULHS(SDNode *
N) {
5543 EVT VT =
N->getValueType(0);
5556 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5599SDValue DAGCombiner::visitMULHU(SDNode *
N) {
5602 EVT VT =
N->getValueType(0);
5615 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5640 if (
SDValue LogBase2 = BuildLogBase2(N1,
DL)) {
5655 unsigned SimpleSize =
Simple.getSizeInBits();
5676SDValue DAGCombiner::visitAVG(SDNode *
N) {
5677 unsigned Opcode =
N->getOpcode();
5680 EVT VT =
N->getValueType(0);
5691 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5694 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5720 X.getValueType() ==
Y.getValueType() &&
5721 hasOperation(Opcode,
X.getValueType())) {
5727 X.getValueType() ==
Y.getValueType() &&
5728 hasOperation(Opcode,
X.getValueType())) {
5761 if (IsSigned &&
Add->getFlags().hasNoSignedWrap())
5764 if (!IsSigned &&
Add->getFlags().hasNoUnsignedWrap())
5778SDValue DAGCombiner::visitABD(SDNode *
N) {
5779 unsigned Opcode =
N->getOpcode();
5782 EVT VT =
N->getValueType(0);
5792 return DAG.
getNode(Opcode,
DL,
N->getVTList(), N1, N0);
5795 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
5810 (!LegalOperations || hasOperation(
ISD::ABS, VT)))
5825 EVT SmallVT =
X.getScalarValueSizeInBits() >
Y.getScalarValueSizeInBits()
5828 if (!LegalOperations || hasOperation(Opcode, SmallVT)) {
5840 EVT SmallVT =
X.getValueType();
5841 if (!LegalOperations || hasOperation(Opcode, SmallVT)) {
5843 unsigned RelevantBits =
5850 const APInt &YConst =
C->getAsAPIntVal();
5857 if (RelevantBits <= Bits && TruncatingYIsCheap) {
5871SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *
N,
unsigned LoOp,
5874 bool HiExists =
N->hasAnyUseOfValue(1);
5875 if (!HiExists && (!LegalOperations ||
5878 return CombineTo(
N, Res, Res);
5882 bool LoExists =
N->hasAnyUseOfValue(0);
5883 if (!LoExists && (!LegalOperations ||
5886 return CombineTo(
N, Res, Res);
5890 if (LoExists && HiExists)
5896 AddToWorklist(
Lo.getNode());
5899 (!LegalOperations ||
5901 return CombineTo(
N, LoOpt, LoOpt);
5906 AddToWorklist(
Hi.getNode());
5909 (!LegalOperations ||
5911 return CombineTo(
N, HiOpt, HiOpt);
5917SDValue DAGCombiner::visitSMUL_LOHI(SDNode *
N) {
5923 EVT VT =
N->getValueType(0);
5939 unsigned SimpleSize =
Simple.getSizeInBits();
5951 return CombineTo(
N,
Lo,
Hi);
5958SDValue DAGCombiner::visitUMUL_LOHI(SDNode *
N) {
5964 EVT VT =
N->getValueType(0);
5979 return CombineTo(
N, Zero, Zero);
5985 return CombineTo(
N, N0, Zero);
5992 unsigned SimpleSize =
Simple.getSizeInBits();
6004 return CombineTo(
N,
Lo,
Hi);
6011SDValue DAGCombiner::visitMULO(SDNode *
N) {
6017 EVT CarryVT =
N->getValueType(1);
6038 return DAG.
getNode(
N->getOpcode(),
DL,
N->getVTList(), N1, N0);
6050 N->getVTList(), N0, N0);
6057 return CombineTo(
N,
And, Cmp);
6095 unsigned Opcode0 = isSignedMinMax(N0, N1, N2, N3, CC);
6149 unsigned Opcode1 = isSignedMinMax(N00, N01, N02, N03, N0CC);
6150 if (!Opcode1 || Opcode0 == Opcode1)
6160 APInt MinCPlus1 = MinC + 1;
6161 if (-MaxC == MinCPlus1 && MinCPlus1.
isPowerOf2()) {
6167 if (MaxC == 0 && MinC != 0 && MinCPlus1.
isPowerOf2()) {
6216 unsigned BW = (C1 + 1).exactLogBase2();
6230SDValue DAGCombiner::visitIMINMAX(SDNode *
N) {
6234 unsigned Opcode =
N->getOpcode();
6248 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
6252 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
6256 if (
SDValue RMINMAX = reassociateOps(Opcode,
DL, N0, N1,
N->getFlags()))
6267 if (IsSatBroken || IsOpIllegal) {
6269 if (
A.isUndef() ||
B.isUndef())
6282 if (HasKnownSameSign(N0, N1)) {
6285 return DAG.
getNode(AltOpcode,
DL, VT, N0, N1);
6298 auto ReductionOpcode = [](
unsigned Opcode) {
6312 if (
SDValue SD = reassociateReduction(ReductionOpcode(Opcode), Opcode,
6313 SDLoc(
N), VT, N0, N1))
6321 return C0 > C1 ? N0 : N1;
6323 return C0 > C1 ? N1 : N0;
6331 ConstantRange
Range =
6335 const APInt &C1V = C1->getAPIntValue();
6354SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *
N) {
6357 unsigned LogicOpcode =
N->getOpcode();
6382 if (XVT !=
Y.getValueType())
6386 if ((VT.
isVector() || LegalOperations) &&
6396 SDNodeFlags LogicFlags;
6402 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6412 if (XVT !=
Y.getValueType())
6424 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6445 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6460 return DAG.
getNode(HandOpcode,
DL, VT, Logic0, Logic1, S);
6473 if (XVT.
isInteger() && XVT ==
Y.getValueType() &&
6477 return DAG.
getNode(HandOpcode,
DL, VT, Logic);
6496 assert(
X.getValueType() ==
Y.getValueType() &&
6497 "Inputs to shuffles are not the same type");
6503 if (!SVN0->hasOneUse() || !SVN1->hasOneUse() ||
6504 !SVN0->getMask().equals(SVN1->getMask()))
6540 SDValue LL, LR, RL, RR, N0CC, N1CC;
6541 if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
6542 !isSetCCEquivalent(N1, RL, RR, N1CC))
6546 "Unexpected operand types for bitwise logic op");
6549 "Unexpected operand types for setcc");
6565 if (LR == RR && CC0 == CC1 && IsInteger) {
6570 bool AndEqZero = IsAnd && CC1 ==
ISD::SETEQ && IsZero;
6572 bool AndGtNeg1 = IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6574 bool OrNeZero = !IsAnd && CC1 ==
ISD::SETNE && IsZero;
6576 bool OrLtZero = !IsAnd && CC1 ==
ISD::SETLT && IsZero;
6582 if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
6584 AddToWorklist(
Or.getNode());
6589 bool AndEqNeg1 = IsAnd && CC1 ==
ISD::SETEQ && IsNeg1;
6591 bool AndLtZero = IsAnd && CC1 ==
ISD::SETLT && IsZero;
6593 bool OrNeNeg1 = !IsAnd && CC1 ==
ISD::SETNE && IsNeg1;
6595 bool OrGtNeg1 = !IsAnd && CC1 ==
ISD::SETGT && IsNeg1;
6601 if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
6603 AddToWorklist(
And.getNode());
6617 AddToWorklist(
Add.getNode());
6638 auto MatchDiffPow2 = [&](ConstantSDNode *C0, ConstantSDNode *C1) {
6644 return !C0->
isOpaque() && !C1->isOpaque() && (CMax - CMin).isPowerOf2();
6662 if (LL == RR && LR == RL) {
6669 if (LL == RL && LR == RR) {
6673 (!LegalOperations ||
6710 unsigned OrAndOpcode,
SelectionDAG &DAG,
bool isFMAXNUMFMINNUM_IEEE,
6711 bool isFMAXNUMFMINNUM) {
6722 isFMAXNUMFMINNUM_IEEE
6730 isFMAXNUMFMINNUM_IEEE
6748 isFMAXNUMFMINNUM_IEEE
6757 isFMAXNUMFMINNUM_IEEE
6768 (LogicOp->getOpcode() ==
ISD::AND || LogicOp->getOpcode() ==
ISD::OR) &&
6769 "Invalid Op to combine SETCC with");
6775 !
LHS->hasOneUse() || !
RHS->hasOneUse())
6782 LogicOp,
LHS.getNode(),
RHS.getNode());
6794 EVT VT = LogicOp->getValueType(0);
6817 (isFMAXNUMFMINNUM_IEEE || isFMAXNUMFMINNUM))) &&
6823 SDValue CommonValue, Operand1, Operand2;
6831 }
else if (LHS1 == RHS1) {
6844 }
else if (RHS0 == LHS1) {
6861 bool IsSigned = isSignedIntSetCC(CC);
6865 bool IsOr = (LogicOp->getOpcode() ==
ISD::OR);
6874 LogicOp->getOpcode(), DAG, isFMAXNUMFMINNUM_IEEE, isFMAXNUMFMINNUM);
6880 DAG.
getNode(NewOpcode,
DL, OpVT, Operand1, Operand2, Flags);
6881 return DAG.
getSetCC(
DL, VT, MinMaxValue, CommonValue, CC, {},
6887 if (LHS0 == LHS1 && RHS0 == RHS1 && CCL == CCR &&
6891 return DAG.
getSetCC(
DL, VT, LHS0, RHS0, CCL);
6898 LHS0 == RHS0 && LHS1C && RHS1C && OpVT.
isInteger()) {
6899 const APInt &APLhs = LHS1C->getAPIntValue();
6900 const APInt &APRhs = RHS1C->getAPIntValue();
6904 if (APLhs == (-APRhs) &&
6915 }
else if (TargetPreference &
6936 APInt Dif = MaxC - MinC;
6970 EVT CondVT =
Cond.getValueType();
6981 EVT OpVT =
T.getValueType();
7000 if (
SDValue V = foldLogicOfSetCCs(
true, N0, N1,
DL))
7017 APInt
ADDC = ADDI->getAPIntValue();
7018 APInt SRLC = SRLI->getAPIntValue();
7030 CombineTo(N0.
getNode(), NewAdd);
7043bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
7044 EVT LoadResultTy, EVT &ExtVT) {
7053 if (ExtVT == LoadedVT &&
7054 (!LegalOperations ||
7070 if (LegalOperations &&
7080bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
7089 const unsigned ByteShAmt = ShAmt / 8;
7108 if (LdStMemVT.
bitsLT(MemVT))
7123 if (PtrType == MVT::Untyped || PtrType.
isExtended())
7130 if (!
SDValue(Load, 0).hasOneUse())
7133 if (LegalOperations &&
7142 if (
Load->getNumValues() > 2)
7161 if (LegalOperations &&
7168bool DAGCombiner::SearchForAndLoads(SDNode *
N,
7169 SmallVectorImpl<LoadSDNode*> &Loads,
7170 SmallPtrSetImpl<SDNode*> &NodesWithConsts,
7171 ConstantSDNode *Mask,
7172 SDNode *&NodeToMask) {
7176 if (
Op.getValueType().isVector())
7182 "Expected bitwise logic operation");
7183 if (!
C->getAPIntValue().isSubsetOf(
Mask->getAPIntValue()))
7188 if (!
Op.hasOneUse())
7191 switch(
Op.getOpcode()) {
7195 if (isAndLoadExtLoad(Mask, Load,
Load->getValueType(0), ExtVT) &&
7213 unsigned ActiveBits =
Mask->getAPIntValue().countr_one();
7217 Op.getOperand(0).getValueType();
7228 if (!SearchForAndLoads(
Op.getNode(), Loads, NodesWithConsts, Mask,
7239 NodeToMask =
Op.getNode();
7242 for (
unsigned i = 0, e = NodeToMask->
getNumValues(); i < e; ++i) {
7243 MVT VT =
SDValue(NodeToMask, i).getSimpleValueType();
7244 if (VT != MVT::Glue && VT != MVT::Other) {
7246 NodeToMask =
nullptr;
7258bool DAGCombiner::BackwardsPropagateMask(SDNode *
N) {
7263 if (!
Mask->getAPIntValue().isMask())
7271 SmallPtrSet<SDNode*, 2> NodesWithConsts;
7272 SDNode *FixupNode =
nullptr;
7273 if (SearchForAndLoads(
N, Loads, NodesWithConsts, Mask, FixupNode)) {
7286 SDValue(FixupNode, 0), MaskOp);
7288 if (
And.getOpcode() == ISD ::AND)
7293 for (
auto *LogicN : NodesWithConsts) {
7299 if (LogicN->getOpcode() ==
ISD::AND &&
7318 for (
auto *Load : Loads) {
7323 if (
And.getOpcode() == ISD ::AND)
7326 SDValue NewLoad = reduceLoadWidth(
And.getNode());
7328 "Shouldn't be masking the load if it can't be narrowed");
7329 CombineTo(Load, NewLoad, NewLoad.
getValue(1));
7342SDValue DAGCombiner::unfoldExtremeBitClearingToShifts(SDNode *
N) {
7353 unsigned OuterShift;
7354 unsigned InnerShift;
7356 auto matchMask = [&OuterShift, &InnerShift, &
Y](
SDValue M) ->
bool {
7359 OuterShift =
M->getOpcode();
7368 Y =
M->getOperand(1);
7375 else if (matchMask(N0))
7381 EVT VT =
N->getValueType(0);
7398 SDValue And0 =
And->getOperand(0), And1 =
And->getOperand(1);
7408 bool FoundNot =
false;
7411 Src = Src.getOperand(0);
7417 Src = Src.getOperand(0);
7421 if (Src.getOpcode() !=
ISD::SRL || !Src.hasOneUse())
7425 EVT SrcVT = Src.getValueType();
7434 if (!ShiftAmtC || !ShiftAmtC->getAPIntValue().ult(
BitWidth))
7438 Src = Src.getOperand(0);
7445 Src = Src.getOperand(0);
7469 EVT VT =
N->getValueType(0);
7495 unsigned LogicOpcode =
N->getOpcode();
7497 "Expected bitwise logic operation");
7499 if (!LogicOp.hasOneUse() || !ShiftOp.
hasOneUse())
7503 unsigned ShiftOpcode = ShiftOp.
getOpcode();
7504 if (LogicOp.getOpcode() != LogicOpcode ||
7516 if (LogicOp.getOperand(0).getOpcode() == ShiftOpcode &&
7517 LogicOp.getOperand(0).getOperand(1) ==
Y) {
7519 Z = LogicOp.getOperand(1);
7520 }
else if (LogicOp.getOperand(1).getOpcode() == ShiftOpcode &&
7521 LogicOp.getOperand(1).getOperand(1) ==
Y) {
7523 Z = LogicOp.getOperand(0);
7528 EVT VT =
N->getValueType(0);
7532 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift, Z);
7543 unsigned LogicOpcode =
N->getOpcode();
7545 "Expected bitwise logic operation");
7546 if (LeftHand.
getOpcode() != LogicOpcode ||
7567 EVT VT =
N->getValueType(0);
7569 return DAG.
getNode(LogicOpcode,
DL, VT, CombinedShifts, W);
7581 "Must be called with ISD::OR or ISD::AND node");
7595 EVT VT = M.getValueType();
7603SDValue DAGCombiner::visitAND(SDNode *
N) {
7627 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
7645 EVT MemVT =
MLoad->getMemoryVT();
7655 MLoad->isExpandingLoad());
7656 CombineTo(
N, Frozen ? N0 : NewLoad);
7657 CombineTo(MLoad, NewLoad, NewLoad.
getValue(1));
7677 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
7690 auto MatchSubset = [](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
7691 return RHS->getAPIntValue().isSubsetOf(
LHS->getAPIntValue());
7701 APInt
Mask = ~N1C->getAPIntValue();
7726 {N0Op0.getOperand(1)})) {
7759 unsigned EltBitWidth =
Vector->getValueType(0).getScalarSizeInBits();
7760 APInt SplatValue, SplatUndef;
7761 unsigned SplatBitSize;
7768 const bool IsBigEndian =
false;
7770 Vector->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
7771 HasAnyUndefs, EltBitWidth, IsBigEndian);
7775 if (IsSplat && (SplatBitSize % EltBitWidth) == 0) {
7778 SplatValue |= SplatUndef;
7785 for (
unsigned i = 0, n = (SplatBitSize / EltBitWidth); i < n; ++i)
7786 Constant &= SplatValue.
extractBits(EltBitWidth, i * EltBitWidth);
7794 Load->getValueType(0),
7795 Load->getMemoryVT());
7803 switch (
Load->getExtensionType()) {
7804 default:
B =
false;
break;
7816 CombineTo(
N, (N0.
getNode() == Load) ? NewLoad : N0);
7820 Load->getValueType(0), SDLoc(Load),
7821 Load->getChain(),
Load->getBasePtr(),
7822 Load->getOffset(),
Load->getMemoryVT(),
7823 Load->getMemOperand());
7825 if (
Load->getNumValues() == 3) {
7827 SDValue To[] = { NewLoad.getValue(0), NewLoad.getValue(1),
7828 NewLoad.getValue(2) };
7829 CombineTo(Load, To, 3,
true);
7831 CombineTo(Load, NewLoad.getValue(0), NewLoad.getValue(1));
7841 if (
SDValue Shuffle = XformToShuffleWithZero(
N))
7868 EVT MemVT = GN0->getMemoryVT();
7871 if (
SDValue(GN0, 0).hasOneUse() &&
7874 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
7875 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
7878 DAG.
getVTList(VT, MVT::Other), MemVT,
DL,
Ops, GN0->getMemOperand(),
7881 CombineTo(
N, ZExtLoad);
7882 AddToWorklist(ZExtLoad.
getNode());
7891 if (
SDValue Res = reduceLoadWidth(
N))
7899 if (BackwardsPropagateMask(
N))
7903 if (
SDValue Combined = visitANDLike(N0, N1,
N))
7908 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
7939 if (
SDValue Folded = foldBitwiseOpWithNeg(
N,
DL, VT))
7961 X.getOperand(0).getScalarValueSizeInBits() == 1)
7964 X.getOperand(0).getScalarValueSizeInBits() == 1)
7979 EVT MemVT = LN0->getMemoryVT();
7986 ((!LegalOperations && LN0->isSimple()) ||
7990 LN0->getBasePtr(), MemVT, LN0->getMemOperand());
8004 if (
SDValue Shifts = unfoldExtremeBitClearingToShifts(
N))
8024 if (!
C->getAPIntValue().isMask(
8025 LHS.getOperand(0).getValueType().getFixedSizeInBits()))
8032 if (IsAndZeroExtMask(N0, N1))
8041 if (LegalOperations || VT.
isVector())
8054 bool DemandHighBits) {
8055 if (!LegalOperations)
8058 EVT VT =
N->getValueType(0);
8059 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16)
8065 bool LookPassAnd0 =
false;
8066 bool LookPassAnd1 =
false;
8081 LookPassAnd0 =
true;
8091 LookPassAnd1 =
true;
8117 LookPassAnd0 =
true;
8131 LookPassAnd1 =
true;
8140 if (OpSizeInBits > 16) {
8144 if (DemandHighBits && !LookPassAnd0)
8151 if (!LookPassAnd1) {
8152 unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
8160 if (OpSizeInBits > 16) {
8175 if (!
N->hasOneUse())
8178 unsigned Opc =
N.getOpcode();
8196 unsigned MaskByteOffset;
8200 case 0xFF: MaskByteOffset = 0;
break;
8201 case 0xFF00: MaskByteOffset = 1;
break;
8210 case 0xFF0000: MaskByteOffset = 2;
break;
8211 case 0xFF000000: MaskByteOffset = 3;
break;
8216 if (MaskByteOffset == 0 || MaskByteOffset == 2) {
8222 if (!
C ||
C->getZExtValue() != 8)
8230 if (!
C ||
C->getZExtValue() != 8)
8236 if (MaskByteOffset != 0 && MaskByteOffset != 2)
8239 if (!
C ||
C->getZExtValue() != 8)
8244 if (MaskByteOffset != 1 && MaskByteOffset != 3)
8247 if (!
C ||
C->getZExtValue() != 8)
8251 if (Parts[MaskByteOffset])
8266 if (!
C ||
C->getAPIntValue() != 16)
8268 Parts[0] = Parts[1] =
N.getOperand(0).getOperand(0).getNode();
8283 "MatchBSwapHWordOrAndAnd: expecting i32");
8293 if (!Mask0 || !Mask1)
8304 if (!ShiftAmt0 || !ShiftAmt1)
8324 if (!LegalOperations)
8327 EVT VT =
N->getValueType(0);
8345 SDNode *Parts[4] = {};
8365 if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
8393 if (
SDValue V = foldLogicOfSetCCs(
false, N0, N1,
DL))
8402 if (
const ConstantSDNode *N0O1C =
8404 if (
const ConstantSDNode *N1O1C =
8408 const APInt &LHSMask = N0O1C->getAPIntValue();
8409 const APInt &RHSMask = N1O1C->getAPIntValue();
8443 auto peekThroughResize = [](
SDValue V) {
8445 return V->getOperand(0);
8449 SDValue N0Resized = peekThroughResize(N0);
8451 SDValue N1Resized = peekThroughResize(N1);
8456 if (N00 == N1Resized || N01 == N1Resized)
8463 if (peekThroughResize(NotOperand) == N1Resized)
8471 if (peekThroughResize(NotOperand) == N1Resized)
8492 auto peekThroughZext = [](
SDValue V) {
8494 return V->getOperand(0);
8534 if (S0 &&
S1 && S0->getZExtValue() < BW &&
S1->getZExtValue() < BW &&
8535 S0->getZExtValue() == (BW -
S1->getZExtValue())) {
8552 Lo.getScalarValueSizeInBits() == (BW / 2) &&
8553 Lo.getValueType() ==
Hi.getValueType()) {
8569SDValue DAGCombiner::visitOR(SDNode *
N) {
8590 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
8606 if (BV0 && BV1 && !BV0->getSplatValue() && !BV1->getSplatValue() &&
8608 BV0->getOperand(0).getValueType() ==
8609 BV1->getOperand(0).getValueType()) {
8612 EVT EltVT = BV0->getOperand(0).getValueType();
8613 for (
unsigned I = 0;
I != NumElts; ++
I) {
8619 else if (C0 && C0->
isZero())
8621 else if (C1 && C1->isZero())
8625 else if (C1 && C1->isAllOnes())
8627 else if (BV0->getOperand(
I) == BV1->getOperand(
I))
8632 if (MergedOps.
size() == NumElts)
8646 if ((ZeroN00 != ZeroN01) && (ZeroN10 != ZeroN11)) {
8647 assert((!ZeroN00 || !ZeroN01) &&
"Both inputs zero!");
8648 assert((!ZeroN10 || !ZeroN11) &&
"Both inputs zero!");
8649 bool CanFold =
true;
8651 SmallVector<int, 4>
Mask(NumElts, -1);
8653 for (
int i = 0; i != NumElts; ++i) {
8654 int M0 = SV0->getMaskElt(i);
8655 int M1 = SV1->getMaskElt(i);
8658 bool M0Zero =
M0 < 0 || (ZeroN00 == (
M0 < NumElts));
8659 bool M1Zero =
M1 < 0 || (ZeroN10 == (
M1 < NumElts));
8663 if ((M0Zero &&
M1 < 0) || (M1Zero &&
M0 < 0))
8667 if (M0Zero == M1Zero) {
8672 assert((
M0 >= 0 ||
M1 >= 0) &&
"Undef index!");
8678 Mask[i] = M1Zero ?
M0 % NumElts : (
M1 % NumElts) + NumElts;
8687 return LegalShuffle;
8701 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
8712 if (
SDValue Combined = visitORLike(N0, N1,
DL))
8719 if (
SDValue BSwap = MatchBSwapHWord(
N, N0, N1))
8721 if (
SDValue BSwap = MatchBSwapHWordLow(
N, N0, N1))
8735 auto MatchIntersect = [](ConstantSDNode *C1, ConstantSDNode *C2) {
8755 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
8759 if (
SDValue Rot = MatchRotate(N0, N1,
DL,
false))
8762 if (
SDValue Load = MatchLoadCombine(
N))
8772 if (
SDValue Combined = visitADDLike(
N))
8777 if (LegalOperations || VT.
isVector())
8792 Mask =
Op.getOperand(1);
8793 return Op.getOperand(0);
8836 assert(OppShift && ExtractFrom &&
"Empty SDValue");
8864 bool IsMulOrDiv =
false;
8867 auto SelectOpcode = [&](
unsigned NeededShift,
unsigned MulOrDivVariant) {
8868 IsMulOrDiv = ExtractFrom.
getOpcode() == MulOrDivVariant;
8869 if (!IsMulOrDiv && ExtractFrom.
getOpcode() != NeededShift)
8871 Opcode = NeededShift;
8921 if (Rem != 0 || ResultAmt != OppLHSAmt)
8927 if (OppLHSAmt != ExtractFromAmt - NeededShiftAmt.
zextOrTrunc(
8936 return DAG.
getNode(Opcode,
DL, ResVT, OppShiftLHS, NewShiftNode);
8990 unsigned MaskLoBits = 0;
8992 unsigned Bits =
Log2_64(EltSize);
8994 if (NegBits >= Bits) {
9017 if (PosBits >= MaskLoBits) {
9039 if ((Pos == NegOp1) ||
9063 return Width.
getLoBits(MaskLoBits) == 0;
9064 return Width == EltSize;
9074 SDValue InnerNeg,
bool FromAdd,
9075 bool HasPos,
unsigned PosOpcode,
9076 unsigned NegOpcode,
const SDLoc &
DL) {
9087 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, Shifted,
9088 HasPos ? Pos : Neg);
9101 SDValue InnerNeg,
bool FromAdd,
9102 bool HasPos,
unsigned PosOpcode,
9103 unsigned NegOpcode,
const SDLoc &
DL) {
9116 return DAG.
getNode(HasPos ? PosOpcode : NegOpcode,
DL, VT, N0, N1,
9117 HasPos ? Pos : Neg);
9162 EVT VT =
LHS.getValueType();
9167 bool HasROTL = hasOperation(
ISD::ROTL, VT);
9168 bool HasROTR = hasOperation(
ISD::ROTR, VT);
9169 bool HasFSHL = hasOperation(
ISD::FSHL, VT);
9170 bool HasFSHR = hasOperation(
ISD::FSHR, VT);
9181 if (LegalOperations && !HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9186 LHS.getOperand(0).getValueType() ==
RHS.getOperand(0).getValueType()) {
9189 MatchRotate(
LHS.getOperand(0),
RHS.getOperand(0),
DL, FromAdd))
9203 if (!LHSShift && !RHSShift)
9218 RHSShift = NewRHSShift;
9223 LHSShift = NewLHSShift;
9226 if (!RHSShift || !LHSShift)
9251 auto MatchRotateSum = [EltSizeInBits](ConstantSDNode *
LHS,
9252 ConstantSDNode *
RHS) {
9253 return (
LHS->getAPIntValue() +
RHS->getAPIntValue()) == EltSizeInBits;
9256 auto ApplyMasks = [&](
SDValue Res) {
9280 bool IsRotate = LHSShiftArg == RHSShiftArg;
9281 if (!IsRotate && !(HasFSHL || HasFSHR)) {
9290 if (CommonOp ==
Or.getOperand(0)) {
9292 Y =
Or.getOperand(1);
9295 if (CommonOp ==
Or.getOperand(1)) {
9297 Y =
Or.getOperand(0);
9304 if (matchOr(LHSShiftArg, RHSShiftArg)) {
9309 }
else if (matchOr(RHSShiftArg, LHSShiftArg)) {
9318 return ApplyMasks(Res);
9331 if (IsRotate && (HasROTL || HasROTR || !(HasFSHL || HasFSHR))) {
9332 bool UseROTL = !LegalOperations || HasROTL;
9334 UseROTL ? LHSShiftAmt : RHSShiftAmt);
9336 bool UseFSHL = !LegalOperations || HasFSHL;
9338 RHSShiftArg, UseFSHL ? LHSShiftAmt : RHSShiftAmt);
9341 return ApplyMasks(Res);
9346 if (!HasROTL && !HasROTR && !HasFSHL && !HasFSHR)
9355 SDValue LExtOp0 = LHSShiftAmt;
9356 SDValue RExtOp0 = RHSShiftAmt;
9369 if (IsRotate && (HasROTL || HasROTR)) {
9370 if (
SDValue TryL = MatchRotatePosNeg(LHSShiftArg, LHSShiftAmt, RHSShiftAmt,
9371 LExtOp0, RExtOp0, FromAdd, HasROTL,
9375 if (
SDValue TryR = MatchRotatePosNeg(RHSShiftArg, RHSShiftAmt, LHSShiftAmt,
9376 RExtOp0, LExtOp0, FromAdd, HasROTR,
9381 if (
SDValue TryL = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, LHSShiftAmt,
9382 RHSShiftAmt, LExtOp0, RExtOp0, FromAdd,
9386 if (
SDValue TryR = MatchFunnelPosNeg(LHSShiftArg, RHSShiftArg, RHSShiftAmt,
9387 LHSShiftAmt, RExtOp0, LExtOp0, FromAdd,
9437static std::optional<SDByteProvider>
9439 std::optional<uint64_t> VectorIndex,
9440 unsigned StartingIndex = 0) {
9444 return std::nullopt;
9448 if (
Depth && !
Op.hasOneUse() &&
9449 (
Op.getOpcode() !=
ISD::LOAD || !
Op.getValueType().isVector()))
9450 return std::nullopt;
9454 if (
Op.getOpcode() !=
ISD::LOAD && VectorIndex.has_value())
9455 return std::nullopt;
9457 unsigned BitWidth =
Op.getScalarValueSizeInBits();
9459 return std::nullopt;
9461 assert(Index < ByteWidth &&
"invalid index requested");
9464 switch (
Op.getOpcode()) {
9469 return std::nullopt;
9473 return std::nullopt;
9475 if (
LHS->isConstantZero())
9477 if (
RHS->isConstantZero())
9479 return std::nullopt;
9484 return std::nullopt;
9486 uint64_t BitShift = ShiftOp->getZExtValue();
9488 if (BitShift % 8 != 0)
9489 return std::nullopt;
9495 return Index < ByteShift
9498 Depth + 1, VectorIndex, Index);
9505 if (NarrowBitWidth % 8 != 0)
9506 return std::nullopt;
9507 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9509 if (Index >= NarrowByteWidth)
9511 ? std::optional<SDByteProvider>(
9519 Depth + 1, VectorIndex, StartingIndex);
9523 return std::nullopt;
9525 VectorIndex =
OffsetOp->getZExtValue();
9529 if (NarrowBitWidth % 8 != 0)
9530 return std::nullopt;
9531 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9534 if (Index >= NarrowByteWidth)
9535 return std::nullopt;
9543 if (*VectorIndex * NarrowByteWidth > StartingIndex)
9544 return std::nullopt;
9545 if ((*VectorIndex + 1) * NarrowByteWidth <= StartingIndex)
9546 return std::nullopt;
9549 VectorIndex, StartingIndex);
9553 if (!L->isSimple() || L->isIndexed())
9554 return std::nullopt;
9556 unsigned NarrowBitWidth = L->getMemoryVT().getScalarSizeInBits();
9557 if (NarrowBitWidth % 8 != 0)
9558 return std::nullopt;
9559 uint64_t NarrowByteWidth = NarrowBitWidth / 8;
9564 if (Index >= NarrowByteWidth)
9566 ? std::optional<SDByteProvider>(
9570 unsigned BPVectorIndex = VectorIndex.value_or(0U);
9575 return std::nullopt;
9590 int64_t FirstOffset) {
9592 unsigned Width = ByteOffsets.
size();
9594 return std::nullopt;
9596 bool BigEndian =
true, LittleEndian =
true;
9597 for (
unsigned i = 0; i < Width; i++) {
9598 int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
9601 if (!BigEndian && !LittleEndian)
9602 return std::nullopt;
9605 assert((BigEndian != LittleEndian) &&
"It should be either big endian or"
9612 switch (
Value.getOpcode()) {
9617 return Value.getOperand(0);
9644SDValue DAGCombiner::mergeTruncStores(StoreSDNode *
N) {
9655 EVT MemVT =
N->getMemoryVT();
9656 if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
9657 !
N->isSimple() ||
N->isIndexed())
9664 unsigned MaxWideNumBits = 64;
9665 unsigned MaxStores = MaxWideNumBits / NarrowNumBits;
9674 if (
Store->getMemoryVT() != MemVT || !
Store->isSimple() ||
9678 Chain =
Store->getChain();
9679 if (MaxStores < Stores.
size())
9683 if (Stores.
size() < 2)
9688 unsigned NumStores = Stores.
size();
9689 unsigned WideNumBits = NumStores * NarrowNumBits;
9690 if (WideNumBits != 16 && WideNumBits != 32 && WideNumBits != 64)
9698 StoreSDNode *FirstStore =
nullptr;
9699 std::optional<BaseIndexOffset>
Base;
9700 for (
auto *Store : Stores) {
9719 if (ShiftAmtC % NarrowNumBits != 0)
9726 Offset = ShiftAmtC / NarrowNumBits;
9732 SourceValue = WideVal;
9733 else if (SourceValue != WideVal) {
9741 SourceValue = WideVal;
9750 int64_t ByteOffsetFromBase = 0;
9753 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9757 if (ByteOffsetFromBase < FirstOffset) {
9759 FirstOffset = ByteOffsetFromBase;
9765 OffsetMap[
Offset] = ByteOffsetFromBase;
9771 assert(FirstStore &&
"First store must be set");
9778 if (!Allowed || !
Fast)
9783 auto checkOffsets = [&](
bool MatchLittleEndian) {
9784 if (MatchLittleEndian) {
9785 for (
unsigned i = 0; i != NumStores; ++i)
9786 if (OffsetMap[i] != i * (NarrowNumBits / 8) + FirstOffset)
9789 for (
unsigned i = 0, j = NumStores - 1; i != NumStores; ++i, --
j)
9790 if (OffsetMap[j] != i * (NarrowNumBits / 8) + FirstOffset)
9797 bool NeedBswap =
false;
9798 bool NeedRotate =
false;
9801 if (NarrowNumBits == 8 && checkOffsets(Layout.
isBigEndian()))
9803 else if (NumStores == 2 && checkOffsets(Layout.
isBigEndian()))
9812 "Unexpected store value to merge");
9821 }
else if (NeedRotate) {
9822 assert(WideNumBits % 2 == 0 &&
"Unexpected type for rotate");
9866SDValue DAGCombiner::MatchLoadCombine(SDNode *
N) {
9868 "Can only match load combining against OR nodes");
9871 EVT VT =
N->getValueType(0);
9872 if (VT != MVT::i16 && VT != MVT::i32 && VT != MVT::i64)
9878 assert(
P.hasSrc() &&
"Must be a memory byte provider");
9881 unsigned LoadBitWidth =
Load->getMemoryVT().getScalarSizeInBits();
9883 assert(LoadBitWidth % 8 == 0 &&
9884 "can only analyze providers for individual bytes not bit");
9885 unsigned LoadByteWidth = LoadBitWidth / 8;
9890 std::optional<BaseIndexOffset>
Base;
9893 SmallPtrSet<LoadSDNode *, 8> Loads;
9894 std::optional<SDByteProvider> FirstByteProvider;
9900 unsigned ZeroExtendedBytes = 0;
9901 for (
int i = ByteWidth - 1; i >= 0; --i) {
9908 if (
P->isConstantZero()) {
9911 if (++ZeroExtendedBytes != (ByteWidth -
static_cast<unsigned>(i)))
9915 assert(
P->hasSrc() &&
"provenance should either be memory or zero");
9922 else if (Chain != LChain)
9927 int64_t ByteOffsetFromBase = 0;
9936 if (
L->getMemoryVT().isVector()) {
9937 unsigned LoadWidthInBit =
L->getMemoryVT().getScalarSizeInBits();
9938 if (LoadWidthInBit % 8 != 0)
9940 unsigned ByteOffsetFromVector =
P->SrcOffset * LoadWidthInBit / 8;
9941 Ptr.addToOffset(ByteOffsetFromVector);
9947 else if (!
Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
9951 ByteOffsetFromBase += MemoryByteOffset(*
P);
9952 ByteOffsets[i] = ByteOffsetFromBase;
9955 if (ByteOffsetFromBase < FirstOffset) {
9956 FirstByteProvider =
P;
9957 FirstOffset = ByteOffsetFromBase;
9963 assert(!Loads.
empty() &&
"All the bytes of the value must be loaded from "
9964 "memory, so there must be at least one load which produces the value");
9965 assert(
Base &&
"Base address of the accessed memory location must be set");
9968 bool NeedsZext = ZeroExtendedBytes > 0;
9979 if (LegalOperations &&
9987 ArrayRef(ByteOffsets).drop_back(ZeroExtendedBytes), FirstOffset);
9991 assert(FirstByteProvider &&
"must be set");
9995 if (MemoryByteOffset(*FirstByteProvider) != 0)
10004 bool NeedsBswap = IsBigEndianTarget != *IsBigEndian;
10011 if (NeedsBswap && (LegalOperations || NeedsZext) &&
10017 if (NeedsBswap && NeedsZext && LegalOperations &&
10025 *FirstLoad->getMemOperand(), &
Fast);
10026 if (!Allowed || !
Fast)
10031 Chain, FirstLoad->getBasePtr(),
10032 FirstLoad->getPointerInfo(), MemVT, FirstLoad->getAlign());
10035 for (LoadSDNode *L : Loads)
10065SDValue DAGCombiner::unfoldMaskedMerge(SDNode *
N) {
10072 EVT VT =
N->getValueType(0);
10094 M =
And.getOperand(XorIdx ? 0 : 1);
10100 if (!matchAndXor(N0, 0, N1) && !matchAndXor(N0, 1, N1) &&
10101 !matchAndXor(N1, 0, N0) && !matchAndXor(N1, 1, N0))
10148SDValue DAGCombiner::visitXOR(SDNode *
N) {
10175 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10187 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10208 if (
SDValue Combined = visitADDLike(
N))
10216 isSetCCEquivalent(N0,
LHS,
RHS, CC,
true) &&
10218 N->use_begin()->getUser()->getOpcode() ==
ISD::AND)) {
10220 LHS.getValueType());
10221 if (!LegalOperations ||
10223 switch (N0Opcode) {
10239 CombineTo(
N, SetCC);
10241 recursivelyDeleteUnusedNodes(N0.
getNode());
10257 AddToWorklist(
V.getNode());
10266 if (isOneUseSetCC(N01) || isOneUseSetCC(N00)) {
10271 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10284 return DAG.
getNode(NewOpcode,
DL, VT, N00, N01);
10294 APInt NotYValue = ~YConst->getAPIntValue();
10310 AddToWorklist(NotX.
getNode());
10315 if (!LegalOperations || hasOperation(
ISD::ABS, VT)) {
10319 SDValue A0 =
A.getOperand(0), A1 =
A.getOperand(1);
10321 if ((A0 == S && A1 == S0) || (A1 == S && A0 == S0))
10358 if (
SDValue V = hoistLogicOpWithSameOpcodeHands(
N))
10369 if (
SDValue MM = unfoldMaskedMerge(
N))
10438 if (!LogicOp.hasOneUse())
10441 unsigned LogicOpcode = LogicOp.getOpcode();
10447 unsigned ShiftOpcode = Shift->
getOpcode();
10450 assert(C1Node &&
"Expected a shift with constant operand");
10453 const APInt *&ShiftAmtVal) {
10454 if (V.getOpcode() != ShiftOpcode || !V.hasOneUse())
10462 ShiftOp = V.getOperand(0);
10467 if (ShiftAmtVal->getBitWidth() != C1Val.
getBitWidth())
10472 bool Overflow =
false;
10473 APInt NewShiftAmt = C1Val.
uadd_ov(*ShiftAmtVal, Overflow);
10478 if (NewShiftAmt.
uge(V.getScalarValueSizeInBits()))
10486 const APInt *C0Val;
10487 if (matchFirstShift(LogicOp.getOperand(0),
X, C0Val))
10488 Y = LogicOp.getOperand(1);
10489 else if (matchFirstShift(LogicOp.getOperand(1),
X, C0Val))
10490 Y = LogicOp.getOperand(0);
10501 return DAG.
getNode(LogicOpcode,
DL, VT, NewShift1, NewShift2,
10511SDValue DAGCombiner::visitShiftByConstant(SDNode *
N) {
10531 switch (
LHS.getOpcode()) {
10555 if (!IsShiftByConstant && !IsCopyOrSelect)
10558 if (IsCopyOrSelect &&
N->hasOneUse())
10563 EVT VT =
N->getValueType(0);
10565 N->getOpcode(),
DL, VT, {LHS.getOperand(1), N->getOperand(1)})) {
10568 return DAG.
getNode(
LHS.getOpcode(),
DL, VT, NewShift, NewRHS);
10574SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *
N) {
10579 EVT TruncVT =
N->getValueType(0);
10580 if (
N->hasOneUse() &&
N->getOperand(0).hasOneUse() &&
10588 AddToWorklist(Trunc00.
getNode());
10589 AddToWorklist(Trunc01.
getNode());
10597SDValue DAGCombiner::visitRotate(SDNode *
N) {
10601 EVT VT =
N->getValueType(0);
10616 bool OutOfRange =
false;
10617 auto MatchOutOfRange = [Bitsize, &OutOfRange](ConstantSDNode *
C) {
10618 OutOfRange |=
C->getAPIntValue().uge(Bitsize);
10626 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, Amt);
10631 if (RotAmtC && RotAmtC->getAPIntValue() == 8 &&
10642 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10643 return DAG.
getNode(
N->getOpcode(), dl, VT, N0, NewOp1);
10655 bool SameSide = (
N->getOpcode() == NextOp);
10662 if (Norm1 && Norm2)
10664 CombineOp, dl, ShiftVT, {Norm1, Norm2})) {
10666 {CombinedShift, BitsizeC});
10668 ISD::UREM, dl, ShiftVT, {CombinedShift, BitsizeC});
10670 CombinedShiftNorm);
10677SDValue DAGCombiner::visitSHL(SDNode *
N) {
10694 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
10717 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
10727 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
10733 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
10734 ConstantSDNode *
RHS) {
10735 APInt c1 =
LHS->getAPIntValue();
10736 APInt c2 =
RHS->getAPIntValue();
10738 return (c1 + c2).uge(OpSizeInBits);
10743 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
10744 ConstantSDNode *
RHS) {
10745 APInt c1 =
LHS->getAPIntValue();
10746 APInt c2 =
RHS->getAPIntValue();
10748 return (c1 + c2).ult(OpSizeInBits);
10770 auto MatchOutOfRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10771 ConstantSDNode *
RHS) {
10772 APInt c1 =
LHS->getAPIntValue();
10773 APInt c2 =
RHS->getAPIntValue();
10775 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10776 (c1 + c2).uge(OpSizeInBits);
10783 auto MatchInRange = [OpSizeInBits, InnerBitwidth](ConstantSDNode *
LHS,
10784 ConstantSDNode *
RHS) {
10785 APInt c1 =
LHS->getAPIntValue();
10786 APInt c2 =
RHS->getAPIntValue();
10788 return c2.
uge(OpSizeInBits - InnerBitwidth) &&
10789 (c1 + c2).ult(OpSizeInBits);
10809 auto MatchEqual = [VT](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
10810 APInt c1 =
LHS->getAPIntValue();
10811 APInt c2 =
RHS->getAPIntValue();
10821 AddToWorklist(NewSHL.
getNode());
10827 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
10828 ConstantSDNode *
RHS) {
10829 const APInt &LHSC =
LHS->getAPIntValue();
10830 const APInt &RHSC =
RHS->getAPIntValue();
10831 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
10903 AddToWorklist(Shl0.
getNode());
10922 {Add.getOperand(1)})) {
10942 if (
SDValue NewSHL = visitShiftByConstant(
N))
10976 Flags.setNoUnsignedWrap(
N->getFlags().hasNoUnsignedWrap() &&
10989 APInt NewStep = C0 << ShlVal;
11004 "SRL or SRA node is required here!");
11013 SDValue ShiftOperand =
N->getOperand(0);
11024 if (!IsSignExt && !IsZeroExt)
11031 auto UserOfLowerBits = [NarrowVTSize](
SDNode *U) {
11036 if (!UShiftAmtSrc) {
11040 return UShiftAmt < NarrowVTSize;
11054 unsigned ActiveBits = IsSignExt
11055 ?
Constant->getAPIntValue().getSignificantBits()
11056 :
Constant->getAPIntValue().getActiveBits();
11057 if (ActiveBits > NarrowVTSize)
11074 "Cannot have a multiply node with two different operand types.");
11085 if (ShiftAmt != NarrowVTSize)
11095 EVT TransformVT = NarrowVT;
11106 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
11113 unsigned Opcode =
N->getOpcode();
11118 EVT VT =
N->getValueType(0);
11137SDValue DAGCombiner::visitSRA(SDNode *
N) {
11159 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11162 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11174 auto SumOfShifts = [&](ConstantSDNode *
LHS, ConstantSDNode *
RHS) {
11175 APInt c1 =
LHS->getAPIntValue();
11176 APInt c2 =
RHS->getAPIntValue();
11178 APInt Sum = c1 + c2;
11179 unsigned ShiftSum =
11180 Sum.
uge(OpSizeInBits) ? (OpSizeInBits - 1) : Sum.getZExtValue();
11190 "Expected matchBinaryPredicate to return one element for "
11194 ShiftValue = ShiftValues[0];
11208 APInt Sum = C1 + C2;
11212 return DAG.
getNOT(
DL, NewShift, VT);
11236 if ((ShiftAmt > 0) &&
11246 N->getValueType(0), Trunc);
11263 if (ConstantSDNode *AddC =
11280 DAG.
getConstant(AddC->getAPIntValue().lshr(ShiftAmt).trunc(
11297 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11314 if (LargeShift->getAPIntValue() == TruncBits) {
11335 if (
SDValue NewSRA = visitShiftByConstant(
N))
11344 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11353SDValue DAGCombiner::visitSRL(SDNode *
N) {
11370 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
11373 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
11384 auto MatchOutOfRange = [OpSizeInBits](ConstantSDNode *
LHS,
11385 ConstantSDNode *
RHS) {
11386 APInt c1 =
LHS->getAPIntValue();
11387 APInt c2 =
RHS->getAPIntValue();
11389 return (c1 + c2).uge(OpSizeInBits);
11394 auto MatchInRange = [OpSizeInBits](ConstantSDNode *
LHS,
11395 ConstantSDNode *
RHS) {
11396 APInt c1 =
LHS->getAPIntValue();
11397 APInt c2 =
RHS->getAPIntValue();
11399 return (c1 + c2).ult(OpSizeInBits);
11419 if (c1 + OpSizeInBits == InnerShiftSize) {
11420 if (c1 + c2 >= InnerShiftSize)
11430 c1 + c2 < InnerShiftSize) {
11435 OpSizeInBits - c2),
11452 auto MatchShiftAmount = [OpSizeInBits](ConstantSDNode *
LHS,
11453 ConstantSDNode *
RHS) {
11454 const APInt &LHSC =
LHS->getAPIntValue();
11455 const APInt &RHSC =
RHS->getAPIntValue();
11456 return LHSC.
ult(OpSizeInBits) && RHSC.
ult(OpSizeInBits) &&
11498 AddToWorklist(SmallShift.
getNode());
11526 APInt UnknownBits = ~Known.Zero;
11527 if (UnknownBits == 0)
return DAG.
getConstant(1, SDLoc(N0), VT);
11542 AddToWorklist(
Op.getNode());
11551 if (
SDValue NewOp1 = distributeTruncateThroughAnd(N1.
getNode()))
11577 if (
SDValue NewSRL = visitShiftByConstant(
N))
11581 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
11608 if (
N->hasOneUse()) {
11609 SDNode *
User = *
N->user_begin();
11617 AddToWorklist(User);
11633 X.getScalarValueSizeInBits() == HalfBW &&
11634 Y.getScalarValueSizeInBits() == HalfBW) {
11636 (!LegalOperations ||
11642 (!LegalOperations ||
11660SDValue DAGCombiner::visitFunnelShift(SDNode *
N) {
11661 EVT VT =
N->getValueType(0);
11679 return IsFSHL ? N0 : N1;
11681 auto IsUndefOrZero = [](
SDValue V) {
11690 if (Cst->getAPIntValue().uge(
BitWidth)) {
11691 uint64_t RotAmt = Cst->getAPIntValue().urem(
BitWidth);
11692 return DAG.
getNode(
N->getOpcode(),
DL, VT, N0, N1,
11696 unsigned ShAmt = Cst->getZExtValue();
11698 return IsFSHL ? N0 : N1;
11704 if (IsUndefOrZero(N0))
11708 if (IsUndefOrZero(N1))
11722 "ShAmt must be in [1, BW-1] for the identity fold to be valid");
11724 unsigned C0Expected = IsFSHL ? ShAmt :
BitWidth - ShAmt;
11725 unsigned C1Expected = IsFSHL ?
BitWidth - ShAmt : ShAmt;
11748 if (
LHS &&
RHS &&
LHS->isSimple() &&
RHS->isSimple() &&
11749 LHS->getAddressSpace() ==
RHS->getAddressSpace() &&
11750 (
LHS->hasNUsesOfValue(1, 0) ||
RHS->hasNUsesOfValue(1, 0)) &&
11759 RHS->getAddressSpace(), NewAlign,
11760 RHS->getMemOperand()->getFlags(), &
Fast) &&
11764 AddToWorklist(NewPtr.
getNode());
11766 VT,
DL,
RHS->getChain(), NewPtr,
11767 RHS->getPointerInfo().getWithOffset(PtrOff), NewAlign,
11768 RHS->getMemOperand()->getFlags(),
RHS->getAAInfo());
11796 if (N0 == N1 && hasOperation(RotOpc, VT))
11797 return DAG.
getNode(RotOpc,
DL, VT, N0, N2);
11806SDValue DAGCombiner::visitSHLSAT(SDNode *
N) {
11841SDValue DAGCombiner::foldABSToABD(SDNode *
N,
const SDLoc &
DL) {
11842 EVT SrcVT =
N->getValueType(0);
11845 N =
N->getOperand(0).getNode();
11847 EVT VT =
N->getValueType(0);
11853 SDValue AbsOp0 =
N->getOperand(0);
11890 EVT MaxVT = VT0.
bitsGT(VT1) ? VT0 : VT1;
11891 if ((VT0 == MaxVT || Op0->
hasOneUse()) &&
11893 (!LegalTypes || hasOperation(ABDOpcode, MaxVT))) {
11903 if (!LegalOperations || hasOperation(ABDOpcode, VT)) {
11911SDValue DAGCombiner::visitABS(SDNode *
N) {
11913 EVT VT =
N->getValueType(0);
11946SDValue DAGCombiner::visitCLMUL(SDNode *
N) {
11947 unsigned Opcode =
N->getOpcode();
11950 EVT VT =
N->getValueType(0);
11960 return DAG.
getNode(Opcode,
DL, VT, N1, N0);
11981SDValue DAGCombiner::visitBSWAP(SDNode *
N) {
11983 EVT VT =
N->getValueType(0);
12008 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
12009 ShAmt->getZExtValue() >= (BW / 2) &&
12010 (ShAmt->getZExtValue() % 16) == 0 && TLI.
isTypeLegal(HalfVT) &&
12012 (!LegalOperations || hasOperation(
ISD::BSWAP, HalfVT))) {
12014 if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2)))
12030 if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
12031 ShAmt->getZExtValue() % 8 == 0) {
12044SDValue DAGCombiner::visitBITREVERSE(SDNode *
N) {
12046 EVT VT =
N->getValueType(0);
12080 EVT VT = Src.getValueType();
12090 bool NeedAdd =
true;
12112SDValue DAGCombiner::visitCTLZ(SDNode *
N) {
12114 EVT VT =
N->getValueType(0);
12126 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
12132SDValue DAGCombiner::visitCTLZ_ZERO_UNDEF(SDNode *
N) {
12134 EVT VT =
N->getValueType(0);
12142 if (
SDValue V = foldCTLZToCTLS(N0,
DL))
12148SDValue DAGCombiner::visitCTTZ(SDNode *
N) {
12150 EVT VT =
N->getValueType(0);
12165SDValue DAGCombiner::visitCTTZ_ZERO_UNDEF(SDNode *
N) {
12167 EVT VT =
N->getValueType(0);
12177SDValue DAGCombiner::visitCTPOP(SDNode *
N) {
12179 EVT VT =
N->getValueType(0);
12191 const APInt &Amt = AmtC->getAPIntValue();
12192 if (Amt.
ult(NumBits)) {
12226 EVT VT =
LHS.getValueType();
12230 return Flags.hasNoSignedZeros() &&
12232 (Flags.hasNoNaNs() ||
12282SDValue DAGCombiner::foldShiftToAvg(SDNode *
N,
const SDLoc &
DL) {
12283 const unsigned Opcode =
N->getOpcode();
12287 EVT VT =
N->getValueType(0);
12288 bool IsUnsigned = Opcode ==
ISD::SRL;
12295 SDNodeFlags
Flags =
12302 if (hasOperation(FloorISD, VT))
12309SDValue DAGCombiner::foldBitwiseOpWithNeg(SDNode *
N,
const SDLoc &
DL, EVT VT) {
12310 unsigned Opc =
N->getOpcode();
12329 if ((
LHS == True &&
RHS == False) || (
LHS == False &&
RHS == True))
12335 True, DAG, LegalOperations, ForCodeSize);
12339 HandleSDNode NegTrueHandle(NegTrue);
12347 if (
LHS == NegTrue) {
12351 RHS, DAG, LegalOperations, ForCodeSize);
12353 HandleSDNode NegRHSHandle(NegRHS);
12354 if (NegRHS == False) {
12356 False, CC, TLI, DAG);
12376 EVT VT =
N->getValueType(0);
12378 VT !=
Cond.getOperand(0).getValueType())
12421SDValue DAGCombiner::foldSelectOfConstants(SDNode *
N) {
12425 EVT VT =
N->getValueType(0);
12426 EVT CondVT =
Cond.getValueType();
12437 if (CondVT != MVT::i1 || LegalOperations) {
12452 C1->
isZero() && C2->isOne()) {
12467 assert(CondVT == MVT::i1 && !LegalOperations);
12470 if (C1->
isOne() && C2->isZero())
12478 if (C1->
isZero() && C2->isOne()) {
12485 if (C1->
isZero() && C2->isAllOnes()) {
12498 const APInt &C1Val = C1->getAPIntValue();
12499 const APInt &C2Val = C2->getAPIntValue();
12502 if (C1Val - 1 == C2Val) {
12508 if (C1Val + 1 == C2Val) {
12528 if (C2->isAllOnes()) {
12540template <
class MatchContextClass>
12544 N->getOpcode() == ISD::VP_SELECT) &&
12545 "Expected a (v)(vp.)select");
12547 SDValue T =
N->getOperand(1),
F =
N->getOperand(2);
12548 EVT VT =
N->getValueType(0);
12550 MatchContextClass matcher(DAG, TLI,
N);
12586 EVT VT =
N->getValueType(0);
12650 EVT VT =
LHS.getValueType();
12652 if (LegalOperations && !hasOperation(ABDOpc, VT))
12684 hasOperation(ABDOpc, VT))
12700 hasOperation(ABDOpc, VT))
12734SDValue DAGCombiner::visitSELECT(SDNode *
N) {
12738 EVT VT =
N->getValueType(0);
12741 SDNodeFlags
Flags =
N->getFlags();
12753 if (
SDValue V = foldSelectOfConstants(
N))
12757 if (SimplifySelectOps(
N, N1, N2))
12760 if (VT0 == MVT::i1) {
12769 bool normalizeToSequence =
12778 if (normalizeToSequence || !InnerSelect.
use_empty())
12780 InnerSelect, N2, Flags);
12783 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12790 Cond1, N1, N2, Flags);
12791 if (normalizeToSequence || !InnerSelect.
use_empty())
12793 InnerSelect, Flags);
12796 recursivelyDeleteUnusedNodes(InnerSelect.
getNode());
12806 if (!normalizeToSequence) {
12812 if (
SDValue Combined = visitANDLike(N0, N1_0,
N)) {
12825 if (!normalizeToSequence) {
12831 if (
SDValue Combined = visitORLike(N0, N2_0,
DL))
12867 combineMinNumMaxNum(
DL, VT, Cond0, Cond1, N1, N2, CC))
12880 if (
C && NotC &&
C->getAPIntValue() == ~NotC->getAPIntValue()) {
12900 (!LegalOperations &&
12908 if (
SDValue ABD = foldSelectToABD(Cond0, Cond1, N1, N2, CC,
DL))
12911 if (
SDValue NewSel = SimplifySelect(
DL, N0, N1, N2))
12916 if (
SDValue UMin = foldSelectToUMin(Cond0, Cond1, N1, N2, CC,
DL))
12921 if (
SDValue BinOp = foldSelectOfBinops(
N))
12937 EVT VT =
N->getValueType(0);
12945 if (
LHS->getNumOperands() != 2 ||
RHS->getNumOperands() != 2)
12954 for (
int i = 0; i < NumElems / 2; ++i) {
12955 if (
Cond->getOperand(i)->isUndef())
12958 if (BottomHalf ==
nullptr)
12960 else if (
Cond->getOperand(i).getNode() != BottomHalf)
12966 for (
int i = NumElems / 2; i < NumElems; ++i) {
12967 if (
Cond->getOperand(i)->isUndef())
12970 if (TopHalf ==
nullptr)
12972 else if (
Cond->getOperand(i).getNode() != TopHalf)
12976 assert(TopHalf && BottomHalf &&
12977 "One half of the selector was all UNDEFs and the other was all the "
12978 "same value. This should have been addressed before this function.");
12981 BottomHalf->
isZero() ?
RHS->getOperand(0) :
LHS->getOperand(0),
12982 TopHalf->
isZero() ?
RHS->getOperand(1) :
LHS->getOperand(1));
12995 EVT VT = BasePtr.getValueType();
12999 SplatVal.getValueType() == VT) {
13005 if (Index.getOpcode() !=
ISD::ADD)
13032 Index = Index.getOperand(0);
13045 Index = Index.getOperand(0);
13052SDValue DAGCombiner::visitVPSCATTER(SDNode *
N) {
13083SDValue DAGCombiner::visitMSCATTER(SDNode *
N) {
13115SDValue DAGCombiner::visitMSTORE(SDNode *
N) {
13129 MST1->isSimple() && MST1->getBasePtr() == Ptr &&
13132 MST1->getMemoryVT().getStoreSize()) ||
13136 CombineTo(MST1, MST1->getChain());
13153 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13157 Value.getValueType().isInteger() &&
13160 APInt TruncDemandedBits =
13186 Value.getOperand(0).getValueType());
13196SDValue DAGCombiner::visitVP_STRIDED_STORE(SDNode *
N) {
13201 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13202 return DAG.
getStoreVP(SST->getChain(), SDLoc(
N), SST->getValue(),
13203 SST->getBasePtr(), SST->getOffset(), SST->getMask(),
13204 SST->getVectorLength(), SST->getMemoryVT(),
13205 SST->getMemOperand(), SST->getAddressingMode(),
13206 SST->isTruncatingStore(), SST->isCompressingStore());
13211SDValue DAGCombiner::visitVECTOR_COMPRESS(SDNode *
N) {
13215 SDValue Passthru =
N->getOperand(2);
13218 bool HasPassthru = !Passthru.
isUndef();
13231 unsigned NumSelected = 0;
13233 for (
unsigned I = 0;
I < NumElmts; ++
I) {
13242 Ops.push_back(VecI);
13246 for (
unsigned Rest = NumSelected; Rest < NumElmts; ++Rest) {
13252 Ops.push_back(Val);
13260SDValue DAGCombiner::visitVPGATHER(SDNode *
N) {
13288SDValue DAGCombiner::visitMGATHER(SDNode *
N) {
13301 return CombineTo(
N, PassThru, MGT->
getChain());
13320SDValue DAGCombiner::visitMLOAD(SDNode *
N) {
13336 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13340 if (CombineToPreIndexedLoadStore(
N) || CombineToPostIndexedLoadStore(
N))
13346SDValue DAGCombiner::visitMHISTOGRAM(SDNode *
N) {
13356 EVT DataVT =
Index.getValueType();
13374SDValue DAGCombiner::visitPARTIAL_REDUCE_MLA(SDNode *
N) {
13375 if (
SDValue Res = foldPartialReduceMLAMulOp(
N))
13377 if (
SDValue Res = foldPartialReduceAdd(
N))
13393SDValue DAGCombiner::foldPartialReduceMLAMulOp(SDNode *
N) {
13425 RHS.getValueType().getScalarType()));
13433 auto IsIntOrFPExtOpcode = [](
unsigned int Opcode) {
13437 unsigned LHSOpcode =
LHS->getOpcode();
13438 if (!IsIntOrFPExtOpcode(LHSOpcode))
13449 EVT OpVT =
Op.getValueType();
13463 unsigned LHSBits =
LHS.getValueType().getScalarSizeInBits();
13480 ApplyPredicate(
C, LHSExtOp);
13481 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, LHSExtOp,
C);
13484 unsigned RHSOpcode =
RHS->getOpcode();
13485 if (!IsIntOrFPExtOpcode(RHSOpcode))
13512 NewOpc !=
N->getOpcode())
13522 ApplyPredicate(RHSExtOp, LHSExtOp);
13523 return DAG.
getNode(NewOpc,
DL,
N->getValueType(0), Acc, LHSExtOp, RHSExtOp);
13533SDValue DAGCombiner::foldPartialReduceAdd(SDNode *
N) {
13558 if (Op1IsSigned != NodeIsSigned &&
13585 return DAG.
getNode(NewOpcode,
DL,
N->getValueType(0), Acc, UnextOp1,
13589SDValue DAGCombiner::visitVP_STRIDED_LOAD(SDNode *
N) {
13594 CStride && CStride->getZExtValue() == EltVT.
getStoreSize()) {
13596 SLD->getAddressingMode(), SLD->getExtensionType(), SLD->getValueType(0),
13597 SDLoc(
N), SLD->getChain(), SLD->getBasePtr(), SLD->getOffset(),
13598 SLD->getMask(), SLD->getVectorLength(), SLD->getMemoryVT(),
13599 SLD->getMemOperand(), SLD->isExpandingLoad());
13600 return CombineTo(
N, NewLd, NewLd.
getValue(1));
13607SDValue DAGCombiner::foldVSelectOfConstants(SDNode *
N) {
13611 EVT VT =
N->getValueType(0);
13612 if (!
Cond.hasOneUse() ||
Cond.getScalarValueSizeInBits() != 1 ||
13621 bool AllAddOne =
true;
13622 bool AllSubOne =
true;
13624 for (
unsigned i = 0; i != Elts; ++i) {
13647 if (AllAddOne || AllSubOne) {
13674SDValue DAGCombiner::visitVP_SELECT(SDNode *
N) {
13698 EVT CondVT =
Cond.getValueType();
13699 assert(CondVT.
isVector() &&
"Vector select expects a vector selector!");
13707 if (!IsTAllZero && !IsTAllOne && !IsFAllZero && !IsFAllOne)
13711 if (IsTAllZero && IsFAllZero) {
13720 Cond.getOperand(0).getValueType() == VT && VT.
isSimple() &&
13722 TValAPInt.
isOne() &&
13741 if (!IsTAllOne && !IsFAllZero &&
Cond.hasOneUse() &&
13745 if (IsTAllZero || IsFAllOne) {
13758 "Select condition no longer all-sign bits");
13761 if (IsTAllOne && IsFAllZero)
13790SDValue DAGCombiner::visitVSELECT(SDNode *
N) {
13794 EVT VT =
N->getValueType(0);
13827 bool isAbs =
false;
13846 AddToWorklist(Shift.
getNode());
13847 AddToWorklist(
Add.getNode());
13859 if (
SDValue FMinMax = combineMinNumMaxNum(
DL, VT,
LHS,
RHS, N1, N2, CC))
13874 EVT NarrowVT =
LHS.getValueType();
13882 SetCCWidth != 1 && SetCCWidth < WideWidth &&
13928 (OpLHS == CondLHS || OpRHS == CondLHS))
13931 if (OpRHS.getOpcode() == CondRHS.getOpcode() &&
13934 CondLHS == OpLHS) {
13938 auto MatchUADDSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13939 return Cond->getAPIntValue() == ~Op->getAPIntValue();
13980 if (OpLHS ==
LHS) {
13995 auto MatchUSUBSAT = [](ConstantSDNode *
Op, ConstantSDNode *
Cond) {
13996 return (!
Op && !
Cond) ||
13998 Cond->getAPIntValue() == (-
Op->getAPIntValue() - 1));
14034 if (SimplifySelectOps(
N, N1, N2))
14054 if (
SDValue V = foldVSelectOfConstants(
N))
14070SDValue DAGCombiner::visitSELECT_CC(SDNode *
N) {
14091 AddToWorklist(
SCC.getNode());
14096 return SCCC->isZero() ? N3 : N2;
14100 if (
SCC->isUndef())
14106 SCC.getOperand(0),
SCC.getOperand(1), N2, N3,
14107 SCC.getOperand(2),
SCC->getFlags());
14112 if (SimplifySelectOps(
N, N2, N3))
14116 return SimplifySelectCC(
DL, N0, N1, N2, N3, CC);
14119SDValue DAGCombiner::visitSETCC(SDNode *
N) {
14124 N->hasOneUse() &&
N->user_begin()->getOpcode() ==
ISD::BRCOND;
14127 EVT VT =
N->getValueType(0);
14134 if (PreferSetCC && Combined.getOpcode() !=
ISD::SETCC) {
14135 SDValue NewSetCC = rebuildSetCC(Combined);
14163 A.getOperand(0) ==
B.getOperand(0);
14167 B.getOperand(0) ==
A;
14170 bool IsRotate =
false;
14173 if (IsAndWithShift(N0, N1)) {
14175 ShiftOrRotate = N1;
14176 }
else if (IsAndWithShift(N1, N0)) {
14178 ShiftOrRotate = N0;
14179 }
else if (IsRotateWithOp(N0, N1)) {
14182 ShiftOrRotate = N1;
14183 }
else if (IsRotateWithOp(N1, N0)) {
14186 ShiftOrRotate = N0;
14189 if (AndOrOp && ShiftOrRotate && ShiftOrRotate.hasOneUse() &&
14194 auto GetAPIntValue = [](
SDValue Op) -> std::optional<APInt> {
14197 if (CNode ==
nullptr)
14198 return std::nullopt;
14201 std::optional<APInt> AndCMask =
14202 IsRotate ? std::nullopt : GetAPIntValue(AndOrOp.
getOperand(1));
14203 std::optional<APInt> ShiftCAmt =
14204 GetAPIntValue(ShiftOrRotate.getOperand(1));
14208 if (ShiftCAmt && (IsRotate || AndCMask) && ShiftCAmt->ult(NumBits)) {
14209 unsigned ShiftOpc = ShiftOrRotate.getOpcode();
14211 bool CanTransform = IsRotate;
14212 if (!CanTransform) {
14214 CanTransform = *ShiftCAmt == (~*AndCMask).
popcount();
14216 CanTransform &= (*ShiftCAmt + AndCMask->popcount()) == NumBits;
14224 OpVT, ShiftOpc, ShiftCAmt->isPowerOf2(), *ShiftCAmt, AndCMask);
14226 if (CanTransform && NewShiftOpc != ShiftOpc) {
14228 DAG.
getNode(NewShiftOpc,
DL, OpVT, ShiftOrRotate.getOperand(0),
14229 ShiftOrRotate.getOperand(1));
14236 NumBits - ShiftCAmt->getZExtValue())
14237 : APInt::getLowBitsSet(NumBits,
14238 NumBits - ShiftCAmt->getZExtValue());
14246 return DAG.
getSetCC(
DL, VT, NewAndOrOp, NewShiftOrRotate,
Cond);
14254SDValue DAGCombiner::visitSETCCCARRY(SDNode *
N) {
14275 if (!
N.hasOneUse())
14304 unsigned Opcode =
N->getOpcode();
14306 EVT VT =
N->getValueType(0);
14309 "Expected EXTEND dag node in input!");
14349 unsigned Opcode =
N->getOpcode();
14351 EVT VT =
N->getValueType(0);
14354 "Expected EXTEND dag node in input!");
14360 return DAG.
getNode(Opcode,
DL, VT, N0);
14379 unsigned FoldOpc = Opcode;
14402 for (
unsigned i = 0; i != NumElts; ++i) {
14404 if (
Op.isUndef()) {
14415 APInt C =
Op->getAsAPIntVal().zextOrTrunc(EVTBits);
14433 bool HasCopyToRegUses =
false;
14448 for (
unsigned i = 0; i != 2; ++i) {
14466 HasCopyToRegUses =
true;
14469 if (HasCopyToRegUses) {
14470 bool BothLiveOut =
false;
14473 BothLiveOut =
true;
14480 return !ExtendNodes.
empty();
14485void DAGCombiner::ExtendSetCCUses(
const SmallVectorImpl<SDNode *> &SetCCs,
14490 for (SDNode *SetCC : SetCCs) {
14493 for (
unsigned j = 0;
j != 2; ++
j) {
14494 SDValue SOp = SetCC->getOperand(j);
14495 if (SOp == OrigLoad)
14496 Ops.push_back(ExtLoad);
14501 Ops.push_back(SetCC->getOperand(2));
14507SDValue DAGCombiner::CombineExtLoad(SDNode *
N) {
14509 EVT DstVT =
N->getValueType(0);
14514 "Unexpected node type (not an extend)!");
14552 EVT SplitSrcVT = SrcVT;
14553 EVT SplitDstVT = DstVT;
14566 const unsigned NumSplits =
14573 for (
unsigned Idx = 0; Idx < NumSplits; Idx++) {
14574 const unsigned Offset = Idx * Stride;
14592 AddToWorklist(NewChain.
getNode());
14594 CombineTo(
N, NewValue);
14600 ExtendSetCCUses(SetCCs, N0, NewValue, (
ISD::NodeType)
N->getOpcode());
14601 CombineTo(N0.
getNode(), Trunc, NewChain);
14607SDValue DAGCombiner::CombineZExtLogicopShiftLoad(SDNode *
N) {
14609 EVT VT =
N->getValueType(0);
14610 EVT OrigVT =
N->getOperand(0).getValueType();
14632 EVT MemVT =
Load->getMemoryVT();
14653 Load->getChain(),
Load->getBasePtr(),
14654 Load->getMemoryVT(),
Load->getMemOperand());
14667 if (
SDValue(Load, 0).hasOneUse()) {
14671 Load->getValueType(0), ExtLoad);
14672 CombineTo(Load, Trunc, ExtLoad.
getValue(1));
14676 recursivelyDeleteUnusedNodes(N0.
getNode());
14685SDValue DAGCombiner::matchVSelectOpSizesWithSetCC(SDNode *Cast) {
14686 unsigned CastOpcode = Cast->
getOpcode();
14690 "Unexpected opcode for vector select narrowing/widening");
14730 bool LegalOperations,
SDNode *
N,
14744 EVT MemVT = OldExtLoad->getMemoryVT();
14745 if ((LegalOperations || !OldExtLoad->isSimple() || VT.
isVector()) &&
14751 OldExtLoad->getBasePtr(), MemVT,
14752 OldExtLoad->getMemOperand());
14759 DAG.
getValueType(OldExtLoad->getValueType(0).getScalarType()));
14777 bool NonNegZExt =
false) {
14783 (Frozen && !Load->hasNUsesOfValue(1, 0)))
14789 "Unexpected load type or opcode");
14809 bool DoXform =
true;
14813 ExtOpc, SetCCs, TLI);
14823 DAG.
getExtLoad(ExtLoadType,
DL, VT, Load->getChain(), Load->getBasePtr(),
14824 Load->getValueType(0), Load->getMemOperand());
14831 DAG.
getValueType(Load->getValueType(0).getScalarType()));
14833 Combiner.ExtendSetCCUses(SetCCs, N0, Res, ExtOpc);
14835 if (NoReplaceTrunc) {
14886 EVT MemoryVT = ALoad->getMemoryVT();
14895 EVT OrigVT = ALoad->getValueType(0);
14898 ExtLoadType,
SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
14899 ALoad->getBasePtr(), ALoad->getMemOperand()));
14909 bool LegalOperations) {
14921 EVT VT =
N->getValueType(0);
14922 EVT XVT =
X.getValueType();
14938 return DAG.
getNode(ShiftOpcode,
DL, VT, NotX, ShiftAmount);
14944SDValue DAGCombiner::foldSextSetcc(SDNode *
N) {
14952 EVT VT =
N->getValueType(0);
14962 if (VT.
isVector() && !LegalOperations &&
14975 return DAG.
getSetCC(
DL, VT, N00, N01, CC, {},
14982 if (SVT == MatchingVecType) {
14999 auto IsFreeToExtend = [&](
SDValue V) {
15013 for (SDUse &Use :
V->uses()) {
15015 SDNode *
User =
Use.getUser();
15016 if (
Use.getResNo() != 0 || User == N0.
getNode())
15021 if (
User->getOpcode() != ExtOpcode ||
User->getValueType(0) != VT)
15027 if (IsFreeToExtend(N00) && IsFreeToExtend(N01)) {
15030 return DAG.
getSetCC(
DL, VT, Ext0, Ext1, CC, {},
15048 SDValue ExtTrueVal = (SetCCWidth == 1)
15052 if (
SDValue SCC = SimplifySelectCC(
DL, N00, N01, ExtTrueVal, Zero, CC,
true))
15065 return DAG.
getSelect(
DL, VT, SetCC, ExtTrueVal, Zero, Flags);
15072SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *
N) {
15074 EVT VT =
N->getValueType(0);
15078 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15124 if (NarrowLoad.getNode() != N0.
getNode()) {
15125 CombineTo(N0.
getNode(), NarrowLoad);
15127 AddToWorklist(oye);
15135 unsigned OpBits =
Op.getScalarValueSizeInBits();
15141 if (OpBits == DestBits) {
15147 if (OpBits < DestBits) {
15156 Flags.setNoSignedWrap(
true);
15164 if (OpBits < DestBits)
15166 else if (OpBits > DestBits)
15186 if (
SDValue ExtLoad = CombineExtLoad(
N))
15221 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15222 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15225 if (NoReplaceTruncAnd) {
15228 CombineTo(N0.
getNode(), TruncAnd);
15230 if (NoReplaceTrunc) {
15235 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
15254 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15285 if (NewXor.getNode() == N0.
getNode()) {
15311 "Expected extend op");
15355SDValue DAGCombiner::visitZERO_EXTEND(SDNode *
N) {
15357 EVT VT =
N->getValueType(0);
15361 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
15392 APInt TruncatedBits =
15394 APInt(
Op.getScalarValueSizeInBits(), 0) :
15395 APInt::getBitsSet(
Op.getScalarValueSizeInBits(),
15396 N0.getScalarValueSizeInBits(),
15397 std::min(
Op.getScalarValueSizeInBits(),
15400 SDValue ZExtOrTrunc = DAG.getZExtOrTrunc(Op, DL, VT);
15401 DAG.salvageDebugInfo(*N0.getNode());
15403 return ZExtOrTrunc;
15413 if (NarrowLoad.getNode() != N0.
getNode()) {
15414 CombineTo(N0.
getNode(), NarrowLoad);
15416 AddToWorklist(oye);
15424 if (
N->getFlags().hasNonNeg()) {
15432 if (OpBits == DestBits) {
15438 if (OpBits < DestBits) {
15448 Flags.setNoSignedWrap(
true);
15449 Flags.setNoUnsignedWrap(
true);
15461 AddToWorklist(
Op.getNode());
15465 return ZExtOrTrunc;
15471 AddToWorklist(
Op.getNode());
15507 if (
SDValue ExtLoad = CombineExtLoad(
N))
15527 bool DoXform =
true;
15534 if (isAndLoadExtLoad(AndC, LN00, LoadResultTy, ExtVT))
15550 bool NoReplaceTruncAnd = !N0.
hasOneUse();
15551 bool NoReplaceTrunc =
SDValue(LN00, 0).hasOneUse();
15554 if (NoReplaceTruncAnd) {
15557 CombineTo(N0.
getNode(), TruncAnd);
15559 if (NoReplaceTrunc) {
15564 CombineTo(LN00, Trunc, ExtLoad.
getValue(1));
15573 if (
SDValue ZExtLoad = CombineZExtLogicopShiftLoad(
N))
15586 SelectionDAG::FlagInserter FlagsInserter(DAG, N0->
getFlags());
15589 if (!LegalOperations && VT.
isVector() &&
15621 if (
SDValue SCC = SimplifySelectCC(
15641 if (ShAmtC->getAPIntValue().ugt(KnownZeroBits)) {
15662 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
15684SDValue DAGCombiner::visitANY_EXTEND(SDNode *
N) {
15686 EVT VT =
N->getValueType(0);
15720 if (NarrowLoad.getNode() != N0.
getNode()) {
15721 CombineTo(N0.
getNode(), NarrowLoad);
15723 AddToWorklist(oye);
15757 bool DoXform =
true;
15770 CombineTo(
N, ExtLoad);
15771 if (NoReplaceTrunc) {
15773 recursivelyDeleteUnusedNodes(LN0);
15777 CombineTo(LN0, Trunc, ExtLoad.
getValue(1));
15791 if (!LegalOperations || TLI.
isLoadExtLegal(ExtType, VT, MemVT)) {
15795 CombineTo(
N, ExtLoad);
15797 recursivelyDeleteUnusedNodes(LN0);
15805 SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
15812 if (VT.
isVector() && !LegalOperations) {
15839 if (
SDValue SCC = SimplifySelectCC(
15855SDValue DAGCombiner::visitAssertExt(SDNode *
N) {
15856 unsigned Opcode =
N->getOpcode();
15876 EVT MinAssertVT = AssertVT.
bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
15891 if (AssertVT.
bitsLT(BigA_AssertVT)) {
15909 if (AssertVT.
bitsLT(BigA_AssertVT) &&
15929SDValue DAGCombiner::visitAssertAlign(SDNode *
N) {
15939 std::max(AL, AAN->getAlign()));
15950 unsigned AlignShift =
Log2(AL);
15955 if (LHSAlignShift >= AlignShift || RHSAlignShift >= AlignShift) {
15956 if (LHSAlignShift < AlignShift)
15958 if (RHSAlignShift < AlignShift)
15972SDValue DAGCombiner::reduceLoadWidth(SDNode *
N) {
15973 unsigned Opc =
N->getOpcode();
15977 EVT VT =
N->getValueType(0);
15987 unsigned ShAmt = 0;
15992 unsigned ShiftedOffset = 0;
16012 uint64_t MemoryWidth = LN->getMemoryVT().getScalarSizeInBits();
16013 if (MemoryWidth <= ShAmt)
16024 LN->getExtensionType() != ExtType)
16033 unsigned ActiveBits = 0;
16034 if (
Mask.isMask()) {
16035 ActiveBits =
Mask.countr_one();
16036 }
else if (
Mask.isShiftedMask(ShAmt, ActiveBits)) {
16037 ShiftedOffset = ShAmt;
16058 if (!
SRL.hasOneUse())
16071 ShAmt = SRL1C->getZExtValue();
16072 uint64_t MemoryWidth = LN->getMemoryVT().getSizeInBits();
16073 if (ShAmt >= MemoryWidth)
16098 SDNode *
Mask = *(
SRL->user_begin());
16101 unsigned Offset, ActiveBits;
16102 const APInt& ShiftMask =
Mask->getConstantOperandAPInt(1);
16103 if (ShiftMask.
isMask()) {
16125 N0 =
SRL.getOperand(0);
16133 unsigned ShLeftAmt = 0;
16137 ShLeftAmt = N01->getZExtValue();
16150 !isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
16153 auto AdjustBigEndianShift = [&](
unsigned ShAmt) {
16154 unsigned LVTStoreBits =
16157 return LVTStoreBits - EVTStoreBits - ShAmt;
16162 unsigned PtrAdjustmentInBits =
16165 uint64_t PtrOff = PtrAdjustmentInBits / 8;
16171 AddToWorklist(NewPtr.
getNode());
16175 const MDNode *OldRanges = LN0->
getRanges();
16176 const MDNode *NewRanges =
nullptr;
16180 if (ShAmt == 0 && OldRanges) {
16188 ConstantRange TruncatedCR = CR.
truncate(BitSize);
16198 NewRanges = OldRanges;
16211 WorklistRemover DeadNodes(*
this);
16216 if (ShLeftAmt != 0) {
16228 if (ShiftedOffset != 0) {
16242SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *
N) {
16245 EVT VT =
N->getValueType(0);
16276 if ((N00Bits <= ExtVTBits ||
16289 if ((N00Bits == ExtVTBits ||
16290 (!IsZext && (N00Bits < ExtVTBits ||
16292 (!LegalOperations ||
16317 if (
SDValue NarrowLoad = reduceLoadWidth(
N))
16325 if (ShAmt->getAPIntValue().ule(VTBits - ExtVTBits)) {
16329 if (((VTBits - ExtVTBits) - ShAmt->getZExtValue()) < InSignBits)
16348 CombineTo(
N, ExtLoad);
16350 AddToWorklist(ExtLoad.
getNode());
16363 CombineTo(
N, ExtLoad);
16372 if (ExtVT == Ld->getMemoryVT() && Ld->hasNUsesOfValue(1, 0) &&
16376 VT,
DL, Ld->getChain(), Ld->getBasePtr(), Ld->getOffset(),
16377 Ld->getMask(), Ld->getPassThru(), ExtVT, Ld->getMemOperand(),
16378 Ld->getAddressingMode(),
ISD::SEXTLOAD, Ld->isExpandingLoad());
16379 CombineTo(
N, Frozen ? N0 : ExtMaskedLoad);
16380 CombineTo(Ld, ExtMaskedLoad, ExtMaskedLoad.
getValue(1));
16387 if (
SDValue(GN0, 0).hasOneUse() && ExtVT == GN0->getMemoryVT() &&
16389 SDValue Ops[] = {GN0->getChain(), GN0->getPassThru(), GN0->getMask(),
16390 GN0->getBasePtr(), GN0->getIndex(), GN0->getScale()};
16393 DAG.
getVTList(VT, MVT::Other), ExtVT,
DL,
Ops, GN0->getMemOperand(),
16396 CombineTo(
N, ExtLoad);
16398 AddToWorklist(ExtLoad.
getNode());
16421 (!LegalOperations ||
16435 bool LegalOperations) {
16436 unsigned InregOpcode =
N->getOpcode();
16440 EVT VT =
N->getValueType(0);
16442 *DAG.
getContext(), Src.getValueType().getVectorElementType());
16445 "Expected EXTEND_VECTOR_INREG dag node in input!");
16454 Src = Src.getOperand(0);
16455 if (Src.getValueType() != SrcVT)
16461 return DAG.
getNode(Opcode,
DL, VT, Src);
16464SDValue DAGCombiner::visitEXTEND_VECTOR_INREG(SDNode *
N) {
16466 EVT VT =
N->getValueType(0);
16490SDValue DAGCombiner::visitTRUNCATE_USAT_U(SDNode *
N) {
16491 EVT VT =
N->getValueType(0);
16512 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16514 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16535 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16537 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16558 unsigned NumSrcBits = In.getScalarValueSizeInBits();
16560 assert(NumSrcBits > NumDstBits &&
"Unexpected types for truncate operation");
16583 auto AllowedTruncateSat = [&](
unsigned Opc,
EVT SrcVT,
EVT VT) ->
bool {
16595 }
else if (Src.getOpcode() ==
ISD::UMIN) {
16607SDValue DAGCombiner::visitTRUNCATE(SDNode *
N) {
16609 EVT VT =
N->getValueType(0);
16624 return SaturatedTR;
16676 if (LegalTypes && !LegalOperations && VT.
isScalarInteger() && VT != MVT::i1 &&
16678 EVT TrTy =
N->getValueType(0);
16683 if (Src.getOpcode() ==
ISD::SRL && Src.getOperand(0)->hasOneUse()) {
16686 Src = Src.getOperand(0);
16693 EVT VecTy = Src.getOperand(0).getValueType();
16694 EVT ExTy = Src.getValueType();
16698 auto NewEltCnt = EltCnt * SizeRatio;
16703 SDValue EltNo = Src->getOperand(1);
16706 int Index = isLE ? (Elt * SizeRatio + EltOffset)
16707 : (Elt * SizeRatio + (SizeRatio - 1) - EltOffset);
16718 if (!LegalOperations ||
16741 AddToWorklist(Amt.
getNode());
16791 if (BuildVectEltTy == TruncVecEltTy) {
16795 unsigned TruncEltOffset = BuildVecNumElts / TruncVecNumElts;
16796 unsigned FirstElt = isLE ? 0 : (TruncEltOffset - 1);
16798 assert((BuildVecNumElts % TruncVecNumElts) == 0 &&
16799 "Invalid number of elements");
16802 for (
unsigned i = FirstElt, e = BuildVecNumElts; i <
e;
16803 i += TruncEltOffset)
16813 if (
SDValue Reduced = reduceLoadWidth(
N))
16836 unsigned NumDefs = 0;
16840 if (!
X.isUndef()) {
16857 if (NumDefs == 1) {
16858 assert(
V.getNode() &&
"The single defined operand is empty!");
16860 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
16866 AddToWorklist(
NV.getNode());
16881 (!LegalOperations ||
16909 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
16923 if (!LegalOperations && N0.
hasOneUse() &&
16940 Flags.setNoUnsignedWrap(
true);
16965 if (!LegalOperations && N0.
hasOneUse() &&
17006 if (!LegalOperations && N0.
hasOneUse() &&
17014 bool CanFold =
false;
17022 unsigned NeededBits = SrcBits - TruncBits;
17048SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *
N, EVT VT) {
17061 !LD1->hasOneUse() || !LD2->hasOneUse() ||
17062 LD1->getAddressSpace() != LD2->getAddressSpace())
17065 unsigned LD1Fast = 0;
17066 EVT LD1VT = LD1->getValueType(0);
17071 *LD1->getMemOperand(), &LD1Fast) && LD1Fast)
17072 return DAG.
getLoad(VT, SDLoc(
N), LD1->getChain(), LD1->getBasePtr(),
17073 LD1->getPointerInfo(), LD1->getAlign());
17084SDValue DAGCombiner::foldBitcastedFPLogic(SDNode *
N, SelectionDAG &DAG,
17088 EVT VT =
N->getValueType(0);
17125 auto IsBitCastOrFree = [&TLI, FPOpcode](
SDValue Op, EVT VT) {
17139 IsBitCastOrFree(LogicOp0, VT)) {
17142 NumFPLogicOpsConv++;
17151SDValue DAGCombiner::visitBITCAST(SDNode *
N) {
17153 EVT VT =
N->getValueType(0);
17178 if (!LegalOperations ||
17184 if (
C.getNode() !=
N)
17197 auto IsFreeBitcast = [VT](
SDValue V) {
17199 V.getOperand(0).getValueType() == VT) ||
17212 auto CastLoad = [
this, &VT](
SDValue N0,
const SDLoc &
DL) {
17229 if ((LegalOperations || !LN0->
isSimple()) &&
17239 if (
const MDNode *MD = LN0->
getRanges()) {
17251 if (
SDValue NewLd = CastLoad(N0, SDLoc(
N)))
17258 if (
SDValue V = foldBitcastedFPLogic(
N, DAG, TLI))
17278 AddToWorklist(NewConv.
getNode());
17281 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17288 AddToWorklist(FlipBit.
getNode());
17295 AddToWorklist(
Hi.getNode());
17297 AddToWorklist(FlipBit.
getNode());
17301 AddToWorklist(FlipBits.
getNode());
17331 AddToWorklist(
X.getNode());
17335 if (OrigXWidth < VTWidth) {
17337 AddToWorklist(
X.getNode());
17338 }
else if (OrigXWidth > VTWidth) {
17343 X.getValueType(),
X,
17345 X.getValueType()));
17346 AddToWorklist(
X.getNode());
17348 AddToWorklist(
X.getNode());
17351 if (N0.
getValueType() == MVT::ppcf128 && !LegalTypes) {
17354 AddToWorklist(Cst.
getNode());
17356 AddToWorklist(
X.getNode());
17358 AddToWorklist(XorResult.
getNode());
17362 SDLoc(XorResult)));
17363 AddToWorklist(XorResult64.
getNode());
17366 DAG.
getConstant(SignBit, SDLoc(XorResult64), MVT::i64));
17367 AddToWorklist(FlipBit.
getNode());
17370 AddToWorklist(FlipBits.
getNode());
17376 AddToWorklist(
X.getNode());
17381 AddToWorklist(Cst.
getNode());
17389 if (
SDValue CombineLD = CombineConsecutiveLoads(N0.
getNode(), VT))
17412 auto PeekThroughBitcast = [&](
SDValue Op) {
17414 Op.getOperand(0).getValueType() == VT)
17431 SmallVector<int, 8> NewMask;
17433 for (
int i = 0; i != MaskScale; ++i)
17434 NewMask.
push_back(M < 0 ? -1 : M * MaskScale + i);
17439 return LegalShuffle;
17445SDValue DAGCombiner::visitBUILD_PAIR(SDNode *
N) {
17446 EVT VT =
N->getValueType(0);
17447 return CombineConsecutiveLoads(
N, VT);
17450SDValue DAGCombiner::visitFREEZE(SDNode *
N) {
17464 assert(
N->getOperand(0) == FrozenN0 &&
"Expected cycle in DAG");
17492 bool AllowMultipleMaybePoisonOperands =
17520 SmallSet<SDValue, 8> MaybePoisonOperands;
17521 SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
17525 bool HadMaybePoisonOperands = !MaybePoisonOperands.
empty();
17526 bool IsNewMaybePoisonOperand = MaybePoisonOperands.
insert(
Op).second;
17527 if (IsNewMaybePoisonOperand)
17528 MaybePoisonOperandNumbers.
push_back(OpNo);
17529 if (!HadMaybePoisonOperands)
17531 if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
17540 for (
unsigned OpNo : MaybePoisonOperandNumbers) {
17551 SDValue MaybePoisonOperand =
N->getOperand(0).getOperand(OpNo);
17553 if (MaybePoisonOperand.
isUndef())
17560 FrozenMaybePoisonOperand.
getOperand(0) == FrozenMaybePoisonOperand) {
17564 MaybePoisonOperand);
17600 SDNodeFlags SrcFlags = N0->
getFlags();
17601 SDNodeFlags SafeFlags;
17615 N->getFlags().hasAllowContract();
17619template <
class MatchContextClass>
17620SDValue DAGCombiner::visitFADDForFMACombine(SDNode *
N) {
17623 EVT VT =
N->getValueType(0);
17625 MatchContextClass matcher(DAG, TLI,
N);
17628 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17633 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17637 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17641 if (!HasFMAD && !HasFMA)
17644 bool AllowFusionGlobally =
17647 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17673 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17684 return matcher.getNode(PreferredFusedOpcode, SL, VT, N0.
getOperand(0),
17691 return matcher.getNode(PreferredFusedOpcode, SL, VT, N1.
getOperand(0),
17703 bool CanReassociate =
N->getFlags().hasAllowReassociation();
17704 if (CanReassociate) {
17709 }
else if (isFusedOp(N1) && N1.
hasOneUse()) {
17715 while (
E && isFusedOp(TmpFMA) && TmpFMA.
hasOneUse()) {
17720 SDValue CDE = matcher.getNode(PreferredFusedOpcode, SL, VT,
C,
D,
E);
17739 return matcher.getNode(
17740 PreferredFusedOpcode, SL, VT,
17753 return matcher.getNode(
17754 PreferredFusedOpcode, SL, VT,
17766 return matcher.getNode(
17767 PreferredFusedOpcode, SL, VT,
X,
Y,
17768 matcher.getNode(PreferredFusedOpcode, SL, VT,
17772 if (isFusedOp(N0)) {
17793 return matcher.getNode(
17794 PreferredFusedOpcode, SL, VT,
17797 matcher.getNode(PreferredFusedOpcode, SL, VT,
17803 if (isFusedOp(N00)) {
17817 if (isFusedOp(N1)) {
17838 if (isFusedOp(N10)) {
17855template <
class MatchContextClass>
17856SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *
N) {
17859 EVT VT =
N->getValueType(0);
17861 MatchContextClass matcher(DAG, TLI,
N);
17864 bool UseVP = std::is_same_v<MatchContextClass, VPMatchContext>;
17869 bool HasFMAD = !UseVP && (LegalOperations && TLI.
isFMADLegal(DAG,
N));
17873 (!LegalOperations || matcher.isOperationLegalOrCustom(
ISD::FMA, VT)) &&
17877 if (!HasFMAD && !HasFMA)
17880 const SDNodeFlags
Flags =
N->getFlags();
17881 bool AllowFusionGlobally =
17885 if (!AllowFusionGlobally && !
N->getFlags().hasAllowContract())
17894 bool NoSignedZero =
Flags.hasNoSignedZeros();
17901 return AllowFusionGlobally ||
N->getFlags().hasAllowContract();
17907 return matcher.getNode(PreferredFusedOpcode, SL, VT, XY.
getOperand(0),
17918 return matcher.getNode(
17919 PreferredFusedOpcode, SL, VT,
17920 matcher.getNode(
ISD::FNEG, SL, VT, YZ.getOperand(0)),
17921 YZ.getOperand(1),
X);
17931 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17934 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17938 if (
SDValue V = tryToFoldXYSubZ(N0, N1))
17941 if (
SDValue V = tryToFoldXSubYZ(N0, N1))
17950 return matcher.
getNode(PreferredFusedOpcode, SL, VT,
17951 matcher.getNode(
ISD::FNEG, SL, VT, N00), N01,
17952 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17964 return matcher.getNode(
17965 PreferredFusedOpcode, SL, VT,
17968 matcher.getNode(
ISD::FNEG, SL, VT, N1));
17980 return matcher.getNode(
17981 PreferredFusedOpcode, SL, VT,
18002 return matcher.getNode(
18005 PreferredFusedOpcode, SL, VT,
18026 return matcher.getNode(
18029 PreferredFusedOpcode, SL, VT,
18046 if (
Aggressive &&
N->getFlags().hasAllowReassociation()) {
18047 bool CanFuse =
N->getFlags().hasAllowContract();
18050 if (CanFuse && isFusedOp(N0) &&
18051 isContractableAndReassociableFMUL(N0.
getOperand(2)) &&
18053 return matcher.getNode(
18055 matcher.
getNode(PreferredFusedOpcode, SL, VT,
18063 if (CanFuse && isFusedOp(N1) &&
18064 isContractableAndReassociableFMUL(N1.
getOperand(2)) &&
18069 PreferredFusedOpcode, SL, VT,
18072 matcher.
getNode(PreferredFusedOpcode, SL, VT,
18073 matcher.getNode(
ISD::FNEG, SL, VT, N20), N21, N0));
18078 if (isFusedOp(N0) && N0->
hasOneUse()) {
18082 if (isContractableAndReassociableFMUL(N020) &&
18085 return matcher.getNode(
18088 PreferredFusedOpcode, SL, VT,
18091 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
18104 if (isFusedOp(N00)) {
18106 if (isContractableAndReassociableFMUL(N002) &&
18109 return matcher.getNode(
18110 PreferredFusedOpcode, SL, VT,
18114 PreferredFusedOpcode, SL, VT,
18117 matcher.getNode(
ISD::FNEG, SL, VT, N1)));
18127 if (isContractableAndReassociableFMUL(N120) &&
18133 PreferredFusedOpcode, SL, VT,
18137 PreferredFusedOpcode, SL, VT,
18155 if (isContractableAndReassociableFMUL(N102) &&
18161 PreferredFusedOpcode, SL, VT,
18166 PreferredFusedOpcode, SL, VT,
18180SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *
N) {
18183 EVT VT =
N->getValueType(0);
18193 if (!
FAdd->getFlags().hasNoInfs())
18204 bool HasFMAD = LegalOperations && TLI.
isFMADLegal(DAG,
N);
18207 if (!HasFMAD && !HasFMA)
18219 if (
C->isExactlyValue(+1.0))
18220 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18222 if (
C->isExactlyValue(-1.0))
18223 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18230 if (
SDValue FMA = FuseFADD(N0, N1))
18232 if (
SDValue FMA = FuseFADD(N1, N0))
18242 if (C0->isExactlyValue(+1.0))
18243 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18246 if (C0->isExactlyValue(-1.0))
18247 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
18252 if (C1->isExactlyValue(+1.0))
18253 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18255 if (C1->isExactlyValue(-1.0))
18256 return DAG.
getNode(PreferredFusedOpcode, SL, VT,
X.getOperand(0),
Y,
18263 if (
SDValue FMA = FuseFSUB(N0, N1))
18265 if (
SDValue FMA = FuseFSUB(N1, N0))
18271SDValue DAGCombiner::visitVP_FADD(SDNode *
N) {
18272 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18275 if (
SDValue Fused = visitFADDForFMACombine<VPMatchContext>(
N)) {
18277 AddToWorklist(Fused.getNode());
18283SDValue DAGCombiner::visitFADD(SDNode *
N) {
18288 EVT VT =
N->getValueType(0);
18290 SDNodeFlags
Flags =
N->getFlags();
18291 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18301 if (N0CFP && !N1CFP)
18306 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18311 if (N1C && N1C->
isZero())
18315 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18321 N1, DAG, LegalOperations, ForCodeSize))
18327 N0, DAG, LegalOperations, ForCodeSize))
18334 return C &&
C->isExactlyValue(-2.0);
18338 if (isFMulNegTwo(N0)) {
18344 if (isFMulNegTwo(N1)) {
18355 if (
Flags.hasNoNaNs() && AllowNewConst) {
18368 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18386 if (CFP01 && !CFP00 && N0.
getOperand(0) == N1) {
18407 if (CFP11 && !CFP10 && N1.
getOperand(0) == N0) {
18454 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros()) {
18457 VT, N0, N1, Flags))
18462 if (
SDValue Fused = visitFADDForFMACombine<EmptyMatchContext>(
N)) {
18464 AddToWorklist(Fused.getNode());
18470SDValue DAGCombiner::visitSTRICT_FADD(SDNode *
N) {
18474 EVT VT =
N->getValueType(0);
18475 EVT ChainVT =
N->getValueType(1);
18477 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18482 N1, DAG, LegalOperations, ForCodeSize)) {
18484 {Chain, N0, NegN1});
18490 N0, DAG, LegalOperations, ForCodeSize)) {
18492 {Chain, N1, NegN0});
18497SDValue DAGCombiner::visitFSUB(SDNode *
N) {
18502 EVT VT =
N->getValueType(0);
18504 const SDNodeFlags
Flags =
N->getFlags();
18505 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18516 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18519 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18523 if (N1CFP && N1CFP->
isZero()) {
18531 if (
Flags.hasNoNaNs())
18536 if (N0CFP && N0CFP->
isZero()) {
18553 if (
Flags.hasAllowReassociation() &&
Flags.hasNoSignedZeros() &&
18569 if (
SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(
N)) {
18570 AddToWorklist(Fused.getNode());
18592SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *
N) {
18593 EVT VT =
N->getValueType(0);
18599 std::optional<int> Mantissa;
18600 auto GetConstAndPow2Ops = [&](
unsigned ConstOpIdx) {
18601 if (ConstOpIdx == 1 &&
N->getOpcode() ==
ISD::FDIV)
18617 auto IsFPConstValid = [
N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
18618 if (CFP ==
nullptr)
18621 const APFloat &APF = CFP->getValueAPF();
18629 int CurExp =
ilogb(APF);
18632 N->getOpcode() ==
ISD::FMUL ? CurExp : (CurExp - MaxExpChange);
18635 N->getOpcode() ==
ISD::FDIV ? CurExp : (CurExp + MaxExpChange);
18643 Mantissa = ThisMantissa;
18645 return *Mantissa == ThisMantissa && ThisMantissa > 0;
18652 if (!GetConstAndPow2Ops(0) && !GetConstAndPow2Ops(1))
18680 NewIntVT, DAG.
getBitcast(NewIntVT, ConstOp), Shift);
18685SDValue DAGCombiner::visitFMUL(SDNode *
N) {
18689 EVT VT =
N->getValueType(0);
18691 const SDNodeFlags
Flags =
N->getFlags();
18692 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18708 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
18711 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
18714 if (
Flags.hasAllowReassociation()) {
18740 VT, N0, N1, Flags))
18764 HandleSDNode NegN0Handle(NegN0);
18774 if (
Flags.hasNoNaNs() &&
Flags.hasNoSignedZeros() &&
18785 if (TrueOpnd && FalseOpnd &&
18806 if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
18810 if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
18819 if (
SDValue Fused = visitFMULForFMADistributiveCombine(
N)) {
18820 AddToWorklist(Fused.getNode());
18826 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
18832template <
class MatchContextClass>
SDValue DAGCombiner::visitFMA(SDNode *
N) {
18839 EVT VT =
N->getValueType(0);
18842 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
18843 MatchContextClass matcher(DAG, TLI,
N);
18858 HandleSDNode NegN0Handle(NegN0);
18866 if (
N->getFlags().hasNoNaNs() &&
N->getFlags().hasNoInfs()) {
18867 if (
N->getFlags().hasNoSignedZeros() ||
18869 if (N0CFP && N0CFP->
isZero())
18871 if (N1CFP && N1CFP->
isZero())
18880 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18885 return matcher.getNode(
ISD::FMA,
DL, VT, N1, N0, N2);
18887 bool CanReassociate =
N->getFlags().hasAllowReassociation();
18888 if (CanReassociate) {
18893 return matcher.getNode(
18902 return matcher.getNode(
18912 return matcher.getNode(
ISD::FADD,
DL, VT, N0, N2);
18917 AddToWorklist(RHSNeg.
getNode());
18918 return matcher.getNode(
ISD::FADD,
DL, VT, N2, RHSNeg);
18932 if (CanReassociate) {
18934 if (N1CFP && N0 == N2) {
18952 SDValue(
N, 0), DAG, LegalOperations, ForCodeSize))
18957SDValue DAGCombiner::visitFMAD(SDNode *
N) {
18961 EVT VT =
N->getValueType(0);
18971SDValue DAGCombiner::visitFMULADD(SDNode *
N) {
18975 EVT VT =
N->getValueType(0);
18993SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *
N) {
18997 const SDNodeFlags
Flags =
N->getFlags();
18998 if (LegalDAG || !
Flags.hasAllowReciprocal())
19013 unsigned NumElts = 1;
19014 EVT VT =
N->getValueType(0);
19018 if (!MinUses || (N1->
use_size() * NumElts) < MinUses)
19023 SetVector<SDNode *>
Users;
19024 for (
auto *U : N1->
users()) {
19025 if (
U->getOpcode() ==
ISD::FDIV &&
U->getOperand(1) == N1) {
19027 if (
U->getOperand(1).getOpcode() ==
ISD::FSQRT &&
19028 U->getOperand(0) ==
U->getOperand(1).getOperand(0) &&
19029 U->getFlags().hasAllowReassociation() &&
19030 U->getFlags().hasNoSignedZeros())
19035 if (
U->getFlags().hasAllowReciprocal())
19042 if ((
Users.size() * NumElts) < MinUses)
19050 for (
auto *U :
Users) {
19051 SDValue Dividend =
U->getOperand(0);
19052 if (Dividend != FPOne) {
19054 Reciprocal, Flags);
19055 CombineTo(U, NewNode);
19056 }
else if (U != Reciprocal.
getNode()) {
19059 CombineTo(U, Reciprocal);
19065SDValue DAGCombiner::visitFDIV(SDNode *
N) {
19068 EVT VT =
N->getValueType(0);
19070 SDNodeFlags
Flags =
N->getFlags();
19071 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19082 if (
SDValue FoldedVOp = SimplifyVBinOp(
N,
DL))
19085 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19102 (!LegalOperations ||
19112 if (
Flags.hasAllowReciprocal()) {
19121 N1AllowReciprocal) {
19154 A =
Y.getOperand(0);
19167 recursivelyDeleteUnusedNodes(AAZ.
getNode());
19176 AddToWorklist(Div.
getNode());
19183 if (
Flags.hasNoInfs())
19184 if (
SDValue RV = BuildDivEstimate(N0, N1, Flags))
19190 Flags.hasAllowReassociation())
19202 HandleSDNode NegN0Handle(NegN0);
19210 if (
SDValue R = combineFMulOrFDivWithIntPow2(
N))
19216SDValue DAGCombiner::visitFREM(SDNode *
N) {
19219 EVT VT =
N->getValueType(0);
19220 SDNodeFlags
Flags =
N->getFlags();
19221 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19231 if (
SDValue NewSel = foldBinOpIntoSelect(
N))
19259SDValue DAGCombiner::visitFSQRT(SDNode *
N) {
19260 SDNodeFlags
Flags =
N->getFlags();
19264 if (!
Flags.hasApproximateFuncs() || !
Flags.hasNoInfs())
19272 SelectionDAG::FlagInserter FlagInserter(DAG, Flags);
19277 return buildSqrtEstimate(N0, Flags);
19292 if (YTy == MVT::f128)
19309SDValue DAGCombiner::visitFCOPYSIGN(SDNode *
N) {
19312 EVT VT =
N->getValueType(0);
19350SDValue DAGCombiner::visitFPOW(SDNode *
N) {
19354 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19360 EVT VT =
N->getValueType(0);
19362 if ((ScalarVT == MVT::f32 &&
19364 (ScalarVT == MVT::f64 &&
19372 SDNodeFlags
Flags =
N->getFlags();
19373 if (!
Flags.hasNoSignedZeros() || !
Flags.hasNoInfs() || !
Flags.hasNoNaNs() ||
19374 !
Flags.hasApproximateFuncs())
19396 if (ExponentIs025 || ExponentIs075) {
19404 SDNodeFlags
Flags =
N->getFlags();
19407 if ((!
Flags.hasNoSignedZeros() && ExponentIs025) || !
Flags.hasNoInfs() ||
19408 !
Flags.hasApproximateFuncs())
19445 EVT VT =
N->getValueType(0);
19451 assert(IsSigned || IsUnsigned);
19456 if (IsSigned && !IsSignedZeroSafe)
19460 if (IsUnsigned && !IsSignedZeroSafe && !TLI.
isFAbsFree(VT))
19468 constexpr unsigned MaxClamps = 2;
19472 SDValue IntVal =
N->getOperand(0);
19473 for (
unsigned Level = 0; Level < MaxClamps; ++Level) {
19474 if (!IntVal.hasOneUse() ||
19475 (IntVal.getOpcode() != MinOp && IntVal.getOpcode() != MaxOp))
19480 IntConst = IntConstNode->getAPIntValue();
19490 !IsExact ||
static_cast<const APInt &
>(RoundTrip) != IntConst)
19492 bool IsMin = IntVal.getOpcode() == MinOp;
19494 IntVal = IntVal.getOperand(0);
19499 if (IntVal.getOpcode() != FPToIntOp ||
19500 IntVal.getOperand(0).getValueType() != VT)
19503 SDValue Result = IntVal.getOperand(0);
19504 if (IsUnsigned && !IsSignedZeroSafe && TLI.
isFAbsFree(VT))
19508 for (
const ClampInfo &Clamp :
reverse(Clamps)) {
19509 unsigned FPClampOp =
19513 Result = DAG.
getNode(FPClampOp,
DL, VT, Result, Clamp.Constant);
19518SDValue DAGCombiner::visitSINT_TO_FP(SDNode *
N) {
19520 EVT VT =
N->getValueType(0);
19572SDValue DAGCombiner::visitUINT_TO_FP(SDNode *
N) {
19574 EVT VT =
N->getValueType(0);
19618 EVT VT =
N->getValueType(0);
19624 EVT SrcVT = Src.getValueType();
19639 unsigned ActualSize = std::min(InputSize, OutputSize);
19648 return DAG.
getNode(ExtOp,
DL, VT, Src);
19657SDValue DAGCombiner::visitFP_TO_SINT(SDNode *
N) {
19659 EVT VT =
N->getValueType(0);
19673SDValue DAGCombiner::visitFP_TO_UINT(SDNode *
N) {
19675 EVT VT =
N->getValueType(0);
19689SDValue DAGCombiner::visitXROUND(SDNode *
N) {
19691 EVT VT =
N->getValueType(0);
19707SDValue DAGCombiner::visitFP_ROUND(SDNode *
N) {
19710 EVT VT =
N->getValueType(0);
19723 const bool NIsTrunc =
N->getConstantOperandVal(1) == 1;
19745 if ((
N->getFlags().hasAllowContract() &&
19763 AddToWorklist(Tmp.
getNode());
19767 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19777 EVT VT =
N->getValueType(0);
19779 unsigned NarrowingOp;
19780 switch (
N->getOpcode()) {
19810SDValue DAGCombiner::visitFP_EXTEND(SDNode *
N) {
19811 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19813 EVT VT =
N->getValueType(0);
19817 if (
SDValue FoldedVOp = SimplifyVCastOp(
N,
DL))
19837 if (
In.getValueType() == VT)
return In;
19851 CombineTo(
N, ExtLoad);
19860 if (
SDValue NewVSel = matchVSelectOpSizesWithSetCC(
N))
19864 return CastEliminated;
19869SDValue DAGCombiner::visitFCEIL(SDNode *
N) {
19871 EVT VT =
N->getValueType(0);
19880SDValue DAGCombiner::visitFTRUNC(SDNode *
N) {
19882 EVT VT =
N->getValueType(0);
19905SDValue DAGCombiner::visitFFREXP(SDNode *
N) {
19914SDValue DAGCombiner::visitFFLOOR(SDNode *
N) {
19916 EVT VT =
N->getValueType(0);
19925SDValue DAGCombiner::visitFNEG(SDNode *
N) {
19927 EVT VT =
N->getValueType(0);
19928 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19951 if (
SDValue Cast = foldSignChangeInBitcast(
N))
19957SDValue DAGCombiner::visitFMinMax(SDNode *
N) {
19960 EVT VT =
N->getValueType(0);
19961 const SDNodeFlags
Flags =
N->getFlags();
19962 unsigned Opc =
N->getOpcode();
19967 SelectionDAG::FlagInserter FlagsInserter(DAG,
N);
19976 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), VT, N1, N0);
19990 if (PropAllNaNsToQNaNs || (AF.
isSignaling() && PropOnlySNaNsToQNaNs)) {
19995 return N->getOperand(0);
20008 (!PropAllNaNsToQNaNs ||
Flags.hasNoNaNs()))
20009 return N->getOperand(1);
20017 if (IsMin != AF.
isNegative() && (PropAllNaNsToQNaNs ||
Flags.hasNoNaNs()))
20018 return N->getOperand(0);
20026 if (
SDValue SD = reassociateReduction(
20030 Opc, SDLoc(
N), VT, N0, N1, Flags))