InstCombine rule to fold truncs whose value is available
We can fold truncs whose operand feeds from a load, if the trunc value
is available through a prior load/store.
This change is from: http://reviews.llvm.org/D21246, which folded the
trunc but missed the bitcast or ptrtoint/inttoptr required in the RAUW
call, when the load type didnt match the prior load/store type.
Differential Revision: http://reviews.llvm.org/D21791
llvm-svn: 274853
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 309a1d9..1a2f8e7 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -297,27 +297,17 @@
"to scan backward from a given instruction, when searching for "
"available loaded value"));
-Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB,
+
+Value *llvm::FindAvailableLoadedValue(Value *Ptr, Type *AccessTy,
+ bool IsAtomicMemOp, BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan,
AliasAnalysis *AA, AAMDNodes *AATags,
bool *IsLoadCSE) {
+
if (MaxInstsToScan == 0)
MaxInstsToScan = ~0U;
-
- Value *Ptr = Load->getPointerOperand();
- Type *AccessTy = Load->getType();
-
- // We can never remove a volatile load
- if (Load->isVolatile())
- return nullptr;
-
- // Anything stronger than unordered is currently unimplemented.
- if (!Load->isUnordered())
- return nullptr;
-
const DataLayout &DL = ScanBB->getModule()->getDataLayout();
-
// Try to get the store size for the type.
uint64_t AccessSize = DL.getTypeStoreSize(AccessTy);
@@ -348,7 +338,7 @@
// We can value forward from an atomic to a non-atomic, but not the
// other way around.
- if (LI->isAtomic() < Load->isAtomic())
+ if (LI->isAtomic() < IsAtomicMemOp)
return nullptr;
if (AATags)
@@ -369,7 +359,7 @@
// We can value forward from an atomic to a non-atomic, but not the
// other way around.
- if (SI->isAtomic() < Load->isAtomic())
+ if (SI->isAtomic() < IsAtomicMemOp)
return nullptr;
if (AATags)
@@ -413,3 +403,24 @@
// block.
return nullptr;
}
+
+
+Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB,
+ BasicBlock::iterator &ScanFrom,
+ unsigned MaxInstsToScan,
+ AliasAnalysis *AA, AAMDNodes *AATags,
+ bool *IsLoadCSE) {
+
+ // We can never remove a volatile load
+ if (Load->isVolatile())
+ return nullptr;
+
+ // Anything stronger than unordered is currently unimplemented.
+ if (!Load->isUnordered())
+ return nullptr;
+
+ // Return the full value of the load if available.
+ return FindAvailableLoadedValue(Load->getPointerOperand(), Load->getType(),
+ Load->isAtomic(), ScanBB, ScanFrom,
+ MaxInstsToScan, AA, AATags, IsLoadCSE);
+}