@@ -462,6 +462,49 @@ static bool AreNonOverlapSameBaseLoadAndStore(
462
462
return LoadRange.intersectWith (StoreRange).isEmptySet ();
463
463
}
464
464
465
+ static Value *getAvailableLoadStore (Instruction *Inst, Value *Ptr,
466
+ Type *AccessTy, bool AtLeastAtomic,
467
+ const DataLayout &DL, bool *IsLoadCSE) {
468
+ // If this is a load of Ptr, the loaded value is available.
469
+ // (This is true even if the load is volatile or atomic, although
470
+ // those cases are unlikely.)
471
+ if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
472
+ if (AreEquivalentAddressValues (
473
+ LI->getPointerOperand ()->stripPointerCasts (), Ptr) &&
474
+ CastInst::isBitOrNoopPointerCastable (LI->getType (), AccessTy, DL)) {
475
+ // We can value forward from an atomic to a non-atomic, but not the
476
+ // other way around.
477
+ if (LI->isAtomic () < AtLeastAtomic)
478
+ return nullptr ;
479
+
480
+ if (IsLoadCSE)
481
+ *IsLoadCSE = true ;
482
+ return LI;
483
+ }
484
+ }
485
+
486
+ // If this is a store through Ptr, the value is available!
487
+ // (This is true even if the store is volatile or atomic, although
488
+ // those cases are unlikely.)
489
+ if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
490
+ Value *StorePtr = SI->getPointerOperand ()->stripPointerCasts ();
491
+ if (AreEquivalentAddressValues (StorePtr, Ptr) &&
492
+ CastInst::isBitOrNoopPointerCastable (SI->getValueOperand ()->getType (),
493
+ AccessTy, DL)) {
494
+ // We can value forward from an atomic to a non-atomic, but not the
495
+ // other way around.
496
+ if (SI->isAtomic () < AtLeastAtomic)
497
+ return nullptr ;
498
+
499
+ if (IsLoadCSE)
500
+ *IsLoadCSE = false ;
501
+ return SI->getOperand (0 );
502
+ }
503
+ }
504
+
505
+ return nullptr ;
506
+ }
507
+
465
508
Value *llvm::FindAvailablePtrLoadStore (Value *Ptr, Type *AccessTy,
466
509
bool AtLeastAtomic, BasicBlock *ScanBB,
467
510
BasicBlock::iterator &ScanFrom,
@@ -492,45 +535,16 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
492
535
return nullptr ;
493
536
494
537
--ScanFrom;
495
- // If this is a load of Ptr, the loaded value is available.
496
- // (This is true even if the load is volatile or atomic, although
497
- // those cases are unlikely.)
498
- if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
499
- if (AreEquivalentAddressValues (
500
- LI->getPointerOperand ()->stripPointerCasts (), StrippedPtr) &&
501
- CastInst::isBitOrNoopPointerCastable (LI->getType (), AccessTy, DL)) {
502
-
503
- // We can value forward from an atomic to a non-atomic, but not the
504
- // other way around.
505
- if (LI->isAtomic () < AtLeastAtomic)
506
- return nullptr ;
507
-
508
- if (IsLoadCSE)
509
- *IsLoadCSE = true ;
510
- return LI;
511
- }
538
+
539
+ if (Value *Available = getAvailableLoadStore (Inst, StrippedPtr, AccessTy,
540
+ AtLeastAtomic, DL, IsLoadCSE))
541
+ return Available;
512
542
513
543
// Try to get the store size for the type.
514
544
auto AccessSize = LocationSize::precise (DL.getTypeStoreSize (AccessTy));
515
545
516
546
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
517
547
Value *StorePtr = SI->getPointerOperand ()->stripPointerCasts ();
518
- // If this is a store through Ptr, the value is available!
519
- // (This is true even if the store is volatile or atomic, although
520
- // those cases are unlikely.)
521
- if (AreEquivalentAddressValues (StorePtr, StrippedPtr) &&
522
- CastInst::isBitOrNoopPointerCastable (SI->getValueOperand ()->getType (),
523
- AccessTy, DL)) {
524
-
525
- // We can value forward from an atomic to a non-atomic, but not the
526
- // other way around.
527
- if (SI->isAtomic () < AtLeastAtomic)
528
- return nullptr ;
529
-
530
- if (IsLoadCSE)
531
- *IsLoadCSE = false ;
532
- return SI->getOperand (0 );
533
- }
534
548
535
549
// If both StrippedPtr and StorePtr reach all the way to an alloca or
536
550
// global and they are different, ignore the store. This is a trivial form
0 commit comments