return LoadRange.intersectWith(StoreRange).isEmptySet();
}
+static Value *getAvailableLoadStore(Instruction *Inst, Value *Ptr,
+ Type *AccessTy, bool AtLeastAtomic,
+ const DataLayout &DL, bool *IsLoadCSE) {
+ // If this is a load of Ptr, the loaded value is available.
+ // (This is true even if the load is volatile or atomic, although
+ // those cases are unlikely.)
+ if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
+ if (AreEquivalentAddressValues(
+ LI->getPointerOperand()->stripPointerCasts(), Ptr) &&
+ CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
+ // We can value forward from an atomic to a non-atomic, but not the
+ // other way around.
+ if (LI->isAtomic() < AtLeastAtomic)
+ return nullptr;
+
+ if (IsLoadCSE)
+ *IsLoadCSE = true;
+ return LI;
+ }
+ }
+
+ // If this is a store through Ptr, the value is available!
+ // (This is true even if the store is volatile or atomic, although
+ // those cases are unlikely.)
+ if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+ Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
+ if (AreEquivalentAddressValues(StorePtr, Ptr) &&
+ CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
+ AccessTy, DL)) {
+ // We can value forward from an atomic to a non-atomic, but not the
+ // other way around.
+ if (SI->isAtomic() < AtLeastAtomic)
+ return nullptr;
+
+ if (IsLoadCSE)
+ *IsLoadCSE = false;
+ return SI->getOperand(0);
+ }
+ }
+
+ return nullptr;
+}
+
Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
bool AtLeastAtomic, BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
return nullptr;
--ScanFrom;
- // If this is a load of Ptr, the loaded value is available.
- // (This is true even if the load is volatile or atomic, although
- // those cases are unlikely.)
- if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
- if (AreEquivalentAddressValues(
- LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
- CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
-
- // We can value forward from an atomic to a non-atomic, but not the
- // other way around.
- if (LI->isAtomic() < AtLeastAtomic)
- return nullptr;
-
- if (IsLoadCSE)
- *IsLoadCSE = true;
- return LI;
- }
+
+ if (Value *Available = getAvailableLoadStore(Inst, StrippedPtr, AccessTy,
+ AtLeastAtomic, DL, IsLoadCSE))
+ return Available;
// Try to get the store size for the type.
auto AccessSize = LocationSize::precise(DL.getTypeStoreSize(AccessTy));
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
- // If this is a store through Ptr, the value is available!
- // (This is true even if the store is volatile or atomic, although
- // those cases are unlikely.)
- if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
- CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
- AccessTy, DL)) {
-
- // We can value forward from an atomic to a non-atomic, but not the
- // other way around.
- if (SI->isAtomic() < AtLeastAtomic)
- return nullptr;
-
- if (IsLoadCSE)
- *IsLoadCSE = false;
- return SI->getOperand(0);
- }
// If both StrippedPtr and StorePtr reach all the way to an alloca or
// global and they are different, ignore the store. This is a trivial form