forked from OSchip/llvm-project
[NFC][InstCombine] Converts isLegalNarrowLoad into isLegalNarrowLdSt
Reuse this function as to test correctness and profitability of reducing width of either load or store operations. Reviewsers: samparker Differential Revision: https://reviews.llvm.org/D48624 llvm-svn: 336800
This commit is contained in:
parent
4f48b3ef90
commit
b0d85ef975
|
@ -512,10 +512,10 @@ namespace {
|
|||
bool isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
|
||||
EVT LoadResultTy, EVT &ExtVT);
|
||||
|
||||
/// Helper function to calculate whether the given Load can have its
|
||||
/// Helper function to calculate whether the given Load/Store can have its
|
||||
/// width reduced to ExtVT.
|
||||
bool isLegalNarrowLoad(LoadSDNode *LoadN, ISD::LoadExtType ExtType,
|
||||
EVT &ExtVT, unsigned ShAmt = 0);
|
||||
bool isLegalNarrowLdSt(LSBaseSDNode *LDSTN, ISD::LoadExtType ExtType,
|
||||
EVT &MemVT, unsigned ShAmt = 0);
|
||||
|
||||
/// Used by BackwardsPropagateMask to find suitable loads.
|
||||
bool SearchForAndLoads(SDNode *N, SmallPtrSetImpl<LoadSDNode*> &Loads,
|
||||
|
@ -3993,64 +3993,78 @@ bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DAGCombiner::isLegalNarrowLoad(LoadSDNode *LoadN, ISD::LoadExtType ExtType,
|
||||
EVT &ExtVT, unsigned ShAmt) {
|
||||
// Don't transform one with multiple uses, this would require adding a new
|
||||
// load.
|
||||
if (!SDValue(LoadN, 0).hasOneUse())
|
||||
bool DAGCombiner::isLegalNarrowLdSt(LSBaseSDNode *LDST,
|
||||
ISD::LoadExtType ExtType, EVT &MemVT,
|
||||
unsigned ShAmt) {
|
||||
if (!LDST)
|
||||
return false;
|
||||
|
||||
if (LegalOperations &&
|
||||
!TLI.isLoadExtLegal(ExtType, LoadN->getValueType(0), ExtVT))
|
||||
// Only allow byte offsets.
|
||||
if (ShAmt % 8)
|
||||
return false;
|
||||
|
||||
// Do not generate loads of non-round integer types since these can
|
||||
// be expensive (and would be wrong if the type is not byte sized).
|
||||
if (!ExtVT.isRound())
|
||||
if (!MemVT.isRound())
|
||||
return false;
|
||||
|
||||
// Don't change the width of a volatile load.
|
||||
if (LoadN->isVolatile())
|
||||
if (LDST->isVolatile())
|
||||
return false;
|
||||
|
||||
// Verify that we are actually reducing a load width here.
|
||||
if (LoadN->getMemoryVT().getSizeInBits() < ExtVT.getSizeInBits())
|
||||
return false;
|
||||
|
||||
// For the transform to be legal, the load must produce only two values
|
||||
// (the value loaded and the chain). Don't transform a pre-increment
|
||||
// load, for example, which produces an extra value. Otherwise the
|
||||
// transformation is not equivalent, and the downstream logic to replace
|
||||
// uses gets things wrong.
|
||||
if (LoadN->getNumValues() > 2)
|
||||
return false;
|
||||
|
||||
// Only allow byte offsets.
|
||||
if (ShAmt % 8)
|
||||
if (LDST->getMemoryVT().getSizeInBits() < MemVT.getSizeInBits())
|
||||
return false;
|
||||
|
||||
// Ensure that this isn't going to produce an unsupported unaligned access.
|
||||
if (ShAmt && !TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(),
|
||||
ExtVT, LoadN->getAddressSpace(),
|
||||
ShAmt / 8))
|
||||
return false;
|
||||
|
||||
|
||||
// If the load that we're shrinking is an extload and we're not just
|
||||
// discarding the extension we can't simply shrink the load. Bail.
|
||||
// TODO: It would be possible to merge the extensions in some cases.
|
||||
if (LoadN->getExtensionType() != ISD::NON_EXTLOAD &&
|
||||
LoadN->getMemoryVT().getSizeInBits() < ExtVT.getSizeInBits() + ShAmt)
|
||||
return false;
|
||||
|
||||
if (!TLI.shouldReduceLoadWidth(LoadN, ExtType, ExtVT))
|
||||
if (ShAmt &&
|
||||
!TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), MemVT,
|
||||
LDST->getAddressSpace(), ShAmt / 8))
|
||||
return false;
|
||||
|
||||
// It's not possible to generate a constant of extended or untyped type.
|
||||
EVT PtrType = LoadN->getOperand(1).getValueType();
|
||||
EVT PtrType = LDST->getBasePtr().getValueType();
|
||||
if (PtrType == MVT::Untyped || PtrType.isExtended())
|
||||
return false;
|
||||
|
||||
if (isa<LoadSDNode>(LDST)) {
|
||||
LoadSDNode *Load = cast<LoadSDNode>(LDST);
|
||||
// Don't transform one with multiple uses, this would require adding a new
|
||||
// load.
|
||||
if (!SDValue(Load, 0).hasOneUse())
|
||||
return false;
|
||||
|
||||
if (LegalOperations &&
|
||||
!TLI.isLoadExtLegal(ExtType, Load->getValueType(0), MemVT))
|
||||
return false;
|
||||
|
||||
// For the transform to be legal, the load must produce only two values
|
||||
// (the value loaded and the chain). Don't transform a pre-increment
|
||||
// load, for example, which produces an extra value. Otherwise the
|
||||
// transformation is not equivalent, and the downstream logic to replace
|
||||
// uses gets things wrong.
|
||||
if (Load->getNumValues() > 2)
|
||||
return false;
|
||||
|
||||
// If the load that we're shrinking is an extload and we're not just
|
||||
// discarding the extension we can't simply shrink the load. Bail.
|
||||
// TODO: It would be possible to merge the extensions in some cases.
|
||||
if (Load->getExtensionType() != ISD::NON_EXTLOAD &&
|
||||
Load->getMemoryVT().getSizeInBits() < MemVT.getSizeInBits() + ShAmt)
|
||||
return false;
|
||||
|
||||
if (!TLI.shouldReduceLoadWidth(Load, ExtType, MemVT))
|
||||
return false;
|
||||
} else {
|
||||
assert(isa<StoreSDNode>(LDST) && "It is not a Load nor a Store SDNode");
|
||||
StoreSDNode *Store = cast<StoreSDNode>(LDST);
|
||||
// Can't write outside the original store
|
||||
if (Store->getMemoryVT().getSizeInBits() < MemVT.getSizeInBits() + ShAmt)
|
||||
return false;
|
||||
|
||||
if (LegalOperations &&
|
||||
!TLI.isTruncStoreLegal(Store->getValue().getValueType(), MemVT))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4083,7 +4097,7 @@ bool DAGCombiner::SearchForAndLoads(SDNode *N,
|
|||
auto *Load = cast<LoadSDNode>(Op);
|
||||
EVT ExtVT;
|
||||
if (isAndLoadExtLoad(Mask, Load, Load->getValueType(0), ExtVT) &&
|
||||
isLegalNarrowLoad(Load, ISD::ZEXTLOAD, ExtVT)) {
|
||||
isLegalNarrowLdSt(Load, ISD::ZEXTLOAD, ExtVT)) {
|
||||
|
||||
// ZEXTLOAD is already small enough.
|
||||
if (Load->getExtensionType() == ISD::ZEXTLOAD &&
|
||||
|
@ -8872,7 +8886,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
|
|||
return SDValue();
|
||||
|
||||
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
|
||||
if (!isLegalNarrowLoad(LN0, ExtType, ExtVT, ShAmt))
|
||||
if (!isLegalNarrowLdSt(LN0, ExtType, ExtVT, ShAmt))
|
||||
return SDValue();
|
||||
|
||||
// For big endian targets, we need to adjust the offset to the pointer to
|
||||
|
|
Loading…
Reference in New Issue