@@ -360,11 +360,43 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
360
360
return MemDepResult::getNonLocal ();
361
361
}
362
362
363
+ // Check if SI that may alias with MemLoc can be safely skipped. This is
364
+ // possible in case if SI can only must alias or no alias with MemLoc (no
365
+ // partial overlapping possible) and it writes the same value that MemLoc
366
+ // contains now (it was loaded before this store and was not modified in
367
+ // between).
368
+ static bool canSkipClobberingStore (const StoreInst *SI,
369
+ const MemoryLocation &MemLoc,
370
+ Align MemLocAlign, BatchAAResults &BatchAA,
371
+ unsigned ScanLimit) {
372
+ if (!MemLoc.Size .hasValue ())
373
+ return false ;
374
+ if (MemoryLocation::get (SI).Size != MemLoc.Size )
375
+ return false ;
376
+ if (std::min (MemLocAlign, SI->getAlign ()).value () < MemLoc.Size .getValue ())
377
+ return false ;
378
+
379
+ auto *LI = dyn_cast<LoadInst>(SI->getValueOperand ());
380
+ if (!LI || LI->getParent () != SI->getParent ())
381
+ return false ;
382
+ if (BatchAA.alias (MemoryLocation::get (LI), MemLoc) != AliasResult::MustAlias)
383
+ return false ;
384
+ unsigned NumVisitedInsts = 0 ;
385
+ for (const Instruction *I = LI; I != SI; I = I->getNextNonDebugInstruction ())
386
+ if (++NumVisitedInsts > ScanLimit ||
387
+ isModSet (BatchAA.getModRefInfo (I, MemLoc)))
388
+ return false ;
389
+
390
+ return true ;
391
+ }
392
+
363
393
MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom (
364
394
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
365
395
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
366
396
BatchAAResults &BatchAA) {
367
397
bool isInvariantLoad = false ;
398
+ Align MemLocAlign =
399
+ MemLoc.Ptr ->getPointerAlignment (BB->getModule ()->getDataLayout ());
368
400
369
401
unsigned DefaultLimit = getDefaultBlockScanLimit ();
370
402
if (!Limit)
@@ -402,11 +434,12 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
402
434
// do want to respect mustalias results since defs are useful for value
403
435
// forwarding, but any mayalias write can be assumed to be noalias.
404
436
// Arguably, this logic should be pushed inside AliasAnalysis itself.
405
- if (isLoad && QueryInst) {
406
- LoadInst *LI = dyn_cast<LoadInst>(QueryInst);
407
- if (LI && LI->hasMetadata (LLVMContext::MD_invariant_load))
408
- isInvariantLoad = true ;
409
- }
437
+ if (isLoad && QueryInst)
438
+ if (LoadInst *LI = dyn_cast<LoadInst>(QueryInst)) {
439
+ if (LI->hasMetadata (LLVMContext::MD_invariant_load))
440
+ isInvariantLoad = true ;
441
+ MemLocAlign = LI->getAlign ();
442
+ }
410
443
411
444
// True for volatile instruction.
412
445
// For Load/Store return true if atomic ordering is stronger than AO,
@@ -577,6 +610,8 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
577
610
return MemDepResult::getDef (Inst);
578
611
if (isInvariantLoad)
579
612
continue ;
613
+ if (canSkipClobberingStore (SI, MemLoc, MemLocAlign, BatchAA, *Limit))
614
+ continue ;
580
615
return MemDepResult::getClobber (Inst);
581
616
}
582
617
0 commit comments