@@ -426,6 +426,49 @@ static bool AreNonOverlapSameBaseLoadAndStore(
426
426
return LoadRange.intersectWith (StoreRange).isEmptySet ();
427
427
}
428
428
429
+ static Value *getAvailableLoadStore (Instruction *Inst, Value *Ptr,
430
+ Type *AccessTy, bool AtLeastAtomic,
431
+ const DataLayout &DL, bool *IsLoadCSE) {
432
+ // If this is a load of Ptr, the loaded value is available.
433
+ // (This is true even if the load is volatile or atomic, although
434
+ // those cases are unlikely.)
435
+ if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
436
+ if (AreEquivalentAddressValues (
437
+ LI->getPointerOperand ()->stripPointerCasts (), Ptr) &&
438
+ CastInst::isBitOrNoopPointerCastable (LI->getType (), AccessTy, DL)) {
439
+ // We can value forward from an atomic to a non-atomic, but not the
440
+ // other way around.
441
+ if (LI->isAtomic () < AtLeastAtomic)
442
+ return nullptr ;
443
+
444
+ if (IsLoadCSE)
445
+ *IsLoadCSE = true ;
446
+ return LI;
447
+ }
448
+ }
449
+
450
+ // If this is a store through Ptr, the value is available!
451
+ // (This is true even if the store is volatile or atomic, although
452
+ // those cases are unlikely.)
453
+ if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
454
+ Value *StorePtr = SI->getPointerOperand ()->stripPointerCasts ();
455
+ if (AreEquivalentAddressValues (StorePtr, Ptr) &&
456
+ CastInst::isBitOrNoopPointerCastable (SI->getValueOperand ()->getType (),
457
+ AccessTy, DL)) {
458
+ // We can value forward from an atomic to a non-atomic, but not the
459
+ // other way around.
460
+ if (SI->isAtomic () < AtLeastAtomic)
461
+ return nullptr ;
462
+
463
+ if (IsLoadCSE)
464
+ *IsLoadCSE = false ;
465
+ return SI->getOperand (0 );
466
+ }
467
+ }
468
+
469
+ return nullptr ;
470
+ }
471
+
429
472
Value *llvm::FindAvailablePtrLoadStore (Value *Ptr, Type *AccessTy,
430
473
bool AtLeastAtomic, BasicBlock *ScanBB,
431
474
BasicBlock::iterator &ScanFrom,
@@ -456,45 +499,16 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
456
499
return nullptr ;
457
500
458
501
--ScanFrom;
459
- // If this is a load of Ptr, the loaded value is available.
460
- // (This is true even if the load is volatile or atomic, although
461
- // those cases are unlikely.)
462
- if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
463
- if (AreEquivalentAddressValues (
464
- LI->getPointerOperand ()->stripPointerCasts (), StrippedPtr) &&
465
- CastInst::isBitOrNoopPointerCastable (LI->getType (), AccessTy, DL)) {
466
-
467
- // We can value forward from an atomic to a non-atomic, but not the
468
- // other way around.
469
- if (LI->isAtomic () < AtLeastAtomic)
470
- return nullptr ;
471
-
472
- if (IsLoadCSE)
473
- *IsLoadCSE = true ;
474
- return LI;
475
- }
502
+
503
+ if (Value *Available = getAvailableLoadStore (Inst, StrippedPtr, AccessTy,
504
+ AtLeastAtomic, DL, IsLoadCSE))
505
+ return Available;
476
506
477
507
// Try to get the store size for the type.
478
508
auto AccessSize = LocationSize::precise (DL.getTypeStoreSize (AccessTy));
479
509
480
510
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
481
511
Value *StorePtr = SI->getPointerOperand ()->stripPointerCasts ();
482
- // If this is a store through Ptr, the value is available!
483
- // (This is true even if the store is volatile or atomic, although
484
- // those cases are unlikely.)
485
- if (AreEquivalentAddressValues (StorePtr, StrippedPtr) &&
486
- CastInst::isBitOrNoopPointerCastable (SI->getValueOperand ()->getType (),
487
- AccessTy, DL)) {
488
-
489
- // We can value forward from an atomic to a non-atomic, but not the
490
- // other way around.
491
- if (SI->isAtomic () < AtLeastAtomic)
492
- return nullptr ;
493
-
494
- if (IsLoadCSE)
495
- *IsLoadCSE = false ;
496
- return SI->getOperand (0 );
497
- }
498
512
499
513
// If both StrippedPtr and StorePtr reach all the way to an alloca or
500
514
// global and they are different, ignore the store. This is a trivial form
0 commit comments