@@ -14229,118 +14229,127 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
14229
14229
return true;
14230
14230
}
14231
14231
14232
- /// Try to combine a load/store with a add/sub of the base pointer node into a
14233
- /// post-indexed load/store. The transformation folded the add/subtract into the
14234
- /// new indexed load/store effectively and all of its uses are redirected to the
14235
- /// new load/store.
14236
- bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
14237
- if (Level < AfterLegalizeDAG)
14232
+ static bool shouldCombineToPostInc(SDNode *N, SDValue Ptr, SDNode *PtrUse,
14233
+ SDValue &BasePtr, SDValue &Offset,
14234
+ ISD::MemIndexedMode &AM,
14235
+ SelectionDAG &DAG,
14236
+ const TargetLowering &TLI) {
14237
+ if (PtrUse == N ||
14238
+ (PtrUse->getOpcode() != ISD::ADD && PtrUse->getOpcode() != ISD::SUB))
14238
14239
return false;
14239
14240
14240
- bool IsLoad = true;
14241
- bool IsMasked = false;
14242
- SDValue Ptr;
14243
- if (!getCombineLoadStoreParts(N, ISD::POST_INC, ISD::POST_DEC, IsLoad, IsMasked,
14244
- Ptr, TLI))
14241
+ if (!TLI.getPostIndexedAddressParts(N, PtrUse, BasePtr, Offset, AM, DAG))
14245
14242
return false;
14246
14243
14247
- if (Ptr.getNode()->hasOneUse())
14244
+ // Don't create a indexed load / store with zero offset.
14245
+ if (isNullConstant(Offset))
14248
14246
return false;
14249
14247
14250
- for (SDNode *Op : Ptr.getNode()->uses()) {
14251
- if (Op == N ||
14252
- (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
14253
- continue;
14254
-
14255
- SDValue BasePtr;
14256
- SDValue Offset;
14257
- ISD::MemIndexedMode AM = ISD::UNINDEXED;
14258
- if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
14259
- // Don't create a indexed load / store with zero offset.
14260
- if (isNullConstant(Offset))
14261
- continue;
14248
+ if (isa<FrameIndexSDNode>(BasePtr) || isa<RegisterSDNode>(BasePtr))
14249
+ return false;
14262
14250
14263
- // Try turning it into a post-indexed load / store except when
14264
- // 1) All uses are load / store ops that use it as base ptr (and
14265
- // it may be folded as addressing mmode).
14266
- // 2) Op must be independent of N, i.e. Op is neither a predecessor
14267
- // nor a successor of N. Otherwise, if Op is folded that would
14268
- // create a cycle.
14251
+ for (SDNode *Use : BasePtr.getNode()->uses()) {
14252
+ if (Use == Ptr.getNode())
14253
+ continue;
14269
14254
14270
- if (isa<FrameIndexSDNode>(BasePtr) || isa<RegisterSDNode>(BasePtr))
14271
- continue;
14255
+ // If all the uses are load / store addresses, then don't do the
14256
+ // transformation.
14257
+ if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB) {
14258
+ for (SDNode *UseUse : Use->uses())
14259
+ if (canFoldInAddressingMode(Use, UseUse, DAG, TLI))
14260
+ return false;
14261
+ }
14262
+ }
14263
+ return true;
14264
+ }
14272
14265
14273
- // Check for #1.
14274
- bool TryNext = false;
14275
- for (SDNode *Use : BasePtr.getNode()->uses()) {
14276
- if (Use == Ptr.getNode())
14277
- continue;
14266
+ static SDNode *getPostIndexedLoadStoreOp(SDNode *N, bool &IsLoad,
14267
+ bool &IsMasked, SDValue &Ptr,
14268
+ SDValue &BasePtr, SDValue &Offset,
14269
+ ISD::MemIndexedMode &AM,
14270
+ SelectionDAG &DAG,
14271
+ const TargetLowering &TLI) {
14272
+ if (!getCombineLoadStoreParts(N, ISD::POST_INC, ISD::POST_DEC, IsLoad,
14273
+ IsMasked, Ptr, TLI) ||
14274
+ Ptr.getNode()->hasOneUse())
14275
+ return nullptr;
14276
+
14277
+ // Try turning it into a post-indexed load / store except when
14278
+ // 1) All uses are load / store ops that use it as base ptr (and
14279
+ // it may be folded as addressing mmode).
14280
+ // 2) Op must be independent of N, i.e. Op is neither a predecessor
14281
+ // nor a successor of N. Otherwise, if Op is folded that would
14282
+ // create a cycle.
14283
+ for (SDNode *Op : Ptr->uses()) {
14284
+ // Check for #1.
14285
+ if (!shouldCombineToPostInc(N, Ptr, Op, BasePtr, Offset, AM, DAG, TLI))
14286
+ continue;
14278
14287
14279
- // If all the uses are load / store addresses, then don't do the
14280
- // transformation.
14281
- if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB) {
14282
- bool RealUse = false;
14283
- for (SDNode *UseUse : Use->uses()) {
14284
- if (!canFoldInAddressingMode(Use, UseUse, DAG, TLI))
14285
- RealUse = true;
14286
- }
14288
+ // Check for #2.
14289
+ SmallPtrSet<const SDNode *, 32> Visited;
14290
+ SmallVector<const SDNode *, 8> Worklist;
14291
+ // Ptr is predecessor to both N and Op.
14292
+ Visited.insert(Ptr.getNode());
14293
+ Worklist.push_back(N);
14294
+ Worklist.push_back(Op);
14295
+ if (!SDNode::hasPredecessorHelper(N, Visited, Worklist) &&
14296
+ !SDNode::hasPredecessorHelper(Op, Visited, Worklist))
14297
+ return Op;
14298
+ }
14299
+ return nullptr;
14300
+ }
14287
14301
14288
- if (!RealUse) {
14289
- TryNext = true;
14290
- break;
14291
- }
14292
- }
14293
- }
14302
+ /// Try to combine a load/store with a add/sub of the base pointer node into a
14303
+ /// post-indexed load/store. The transformation folded the add/subtract into the
14304
+ /// new indexed load/store effectively and all of its uses are redirected to the
14305
+ /// new load/store.
14306
+ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
14307
+ if (Level < AfterLegalizeDAG)
14308
+ return false;
14294
14309
14295
- if (TryNext)
14296
- continue;
14310
+ bool IsLoad = true;
14311
+ bool IsMasked = false;
14312
+ SDValue Ptr;
14313
+ SDValue BasePtr;
14314
+ SDValue Offset;
14315
+ ISD::MemIndexedMode AM = ISD::UNINDEXED;
14316
+ SDNode *Op = getPostIndexedLoadStoreOp(N, IsLoad, IsMasked, Ptr, BasePtr,
14317
+ Offset, AM, DAG, TLI);
14318
+ if (!Op)
14319
+ return false;
14297
14320
14298
- // Check for #2.
14299
- SmallPtrSet<const SDNode *, 32> Visited;
14300
- SmallVector<const SDNode *, 8> Worklist;
14301
- // Ptr is predecessor to both N and Op.
14302
- Visited.insert(Ptr.getNode());
14303
- Worklist.push_back(N);
14304
- Worklist.push_back(Op);
14305
- if (!SDNode::hasPredecessorHelper(N, Visited, Worklist) &&
14306
- !SDNode::hasPredecessorHelper(Op, Visited, Worklist)) {
14307
- SDValue Result;
14308
- if (!IsMasked)
14309
- Result = IsLoad ? DAG.getIndexedLoad(SDValue(N, 0), SDLoc(N), BasePtr,
14310
- Offset, AM)
14311
- : DAG.getIndexedStore(SDValue(N, 0), SDLoc(N),
14321
+ SDValue Result;
14322
+ if (!IsMasked)
14323
+ Result = IsLoad ? DAG.getIndexedLoad(SDValue(N, 0), SDLoc(N), BasePtr,
14324
+ Offset, AM)
14325
+ : DAG.getIndexedStore(SDValue(N, 0), SDLoc(N),
14326
+ BasePtr, Offset, AM);
14327
+ else
14328
+ Result = IsLoad ? DAG.getIndexedMaskedLoad(SDValue(N, 0), SDLoc(N),
14329
+ BasePtr, Offset, AM)
14330
+ : DAG.getIndexedMaskedStore(SDValue(N, 0), SDLoc(N),
14312
14331
BasePtr, Offset, AM);
14313
- else
14314
- Result = IsLoad ? DAG.getIndexedMaskedLoad(SDValue(N, 0), SDLoc(N),
14315
- BasePtr, Offset, AM)
14316
- : DAG.getIndexedMaskedStore(SDValue(N, 0), SDLoc(N),
14317
- BasePtr, Offset, AM);
14318
- ++PostIndexedNodes;
14319
- ++NodesCombined;
14320
- LLVM_DEBUG(dbgs() << "\nReplacing.5 "; N->dump(&DAG);
14321
- dbgs() << "\nWith: "; Result.getNode()->dump(&DAG);
14322
- dbgs() << '\n');
14323
- WorklistRemover DeadNodes(*this);
14324
- if (IsLoad) {
14325
- DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result.getValue(0));
14326
- DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Result.getValue(2));
14327
- } else {
14328
- DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result.getValue(1));
14329
- }
14330
-
14331
- // Finally, since the node is now dead, remove it from the graph.
14332
- deleteAndRecombine(N);
14333
-
14334
- // Replace the uses of Use with uses of the updated base value.
14335
- DAG.ReplaceAllUsesOfValueWith(SDValue(Op, 0),
14336
- Result.getValue(IsLoad ? 1 : 0));
14337
- deleteAndRecombine(Op);
14338
- return true;
14339
- }
14340
- }
14332
+ ++PostIndexedNodes;
14333
+ ++NodesCombined;
14334
+ LLVM_DEBUG(dbgs() << "\nReplacing.5 "; N->dump(&DAG);
14335
+ dbgs() << "\nWith: "; Result.getNode()->dump(&DAG);
14336
+ dbgs() << '\n');
14337
+ WorklistRemover DeadNodes(*this);
14338
+ if (IsLoad) {
14339
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result.getValue(0));
14340
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Result.getValue(2));
14341
+ } else {
14342
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result.getValue(1));
14341
14343
}
14342
14344
14343
- return false;
14345
+ // Finally, since the node is now dead, remove it from the graph.
14346
+ deleteAndRecombine(N);
14347
+
14348
+ // Replace the uses of Use with uses of the updated base value.
14349
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Op, 0),
14350
+ Result.getValue(IsLoad ? 1 : 0));
14351
+ deleteAndRecombine(Op);
14352
+ return true;
14344
14353
}
14345
14354
14346
14355
/// Return the base-pointer arithmetic from an indexed \p LD.
0 commit comments