mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[DAGCombiner] Factor out duplicated logic for an extload combine, NFC (5/N)
Part of the logic for combining (zext (load ...)) and (sext (load ...)) is duplicated. This creates problems because bugs in one version have to be fixed again in the other version. To address this, as a first step, I've extracted the duplicate logic into a helper. I'll fix the debug location bug in the helper and eliminate the copy of its logic in a followup. Part of: llvm.org/PR37262 Differential Revision: https://reviews.llvm.org/D46157 llvm-svn: 332117
This commit is contained in:
parent
c499ebbb98
commit
95b78428ff
@ -268,11 +268,6 @@ namespace {
|
||||
SDValue PromoteExtend(SDValue Op);
|
||||
bool PromoteLoad(SDValue Op);
|
||||
|
||||
void ExtendSetCCUses(const SmallVectorImpl<SDNode *> &SetCCs,
|
||||
SDValue OrigLoad, SDValue ExtLoad,
|
||||
const SDLoc &DL,
|
||||
ISD::NodeType ExtType);
|
||||
|
||||
/// Call the node-specific routine that knows how to fold each
|
||||
/// particular type of node. If that doesn't do anything, try the
|
||||
/// target-specific DAG combines.
|
||||
@ -593,6 +588,11 @@ namespace {
|
||||
EVT getSetCCResultType(EVT VT) const {
|
||||
return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
|
||||
}
|
||||
|
||||
void ExtendSetCCUses(const SmallVectorImpl<SDNode *> &SetCCs,
|
||||
SDValue OrigLoad, SDValue ExtLoad,
|
||||
const SDLoc &DL,
|
||||
ISD::NodeType ExtType);
|
||||
};
|
||||
|
||||
/// This class is a DAGUpdateListener that removes any deleted
|
||||
@ -7757,6 +7757,48 @@ static SDValue tryToFoldExtOfExtload(SelectionDAG &DAG, DAGCombiner &Combiner,
|
||||
return SDValue(N, 0); // Return N so it doesn't get rechecked!
|
||||
}
|
||||
|
||||
// fold ([s|z]ext (load x)) -> ([s|z]ext (truncate ([s|z]extload x)))
|
||||
// Only generate vector extloads when 1) they're legal, and 2) they are
|
||||
// deemed desirable by the target.
|
||||
static SDValue tryToFoldExtOfLoad(SelectionDAG &DAG, DAGCombiner &Combiner,
|
||||
const TargetLowering &TLI, EVT VT,
|
||||
bool LegalOperations, SDNode *N, SDValue N0,
|
||||
SDLoc DL, ISD::LoadExtType ExtLoadType,
|
||||
ISD::NodeType ExtOpc) {
|
||||
if (!ISD::isNON_EXTLoad(N0.getNode()) ||
|
||||
!ISD::isUNINDEXEDLoad(N0.getNode()) ||
|
||||
((LegalOperations || VT.isVector() ||
|
||||
cast<LoadSDNode>(N0)->isVolatile()) &&
|
||||
!TLI.isLoadExtLegal(ExtLoadType, VT, N0.getValueType())))
|
||||
return {};
|
||||
|
||||
bool DoXform = true;
|
||||
SmallVector<SDNode *, 4> SetCCs;
|
||||
if (!N0.hasOneUse())
|
||||
DoXform = ExtendUsesToFormExtLoad(VT, N, N0, ExtOpc, SetCCs, TLI);
|
||||
if (VT.isVector())
|
||||
DoXform &= TLI.isVectorLoadExtDesirable(SDValue(N, 0));
|
||||
if (!DoXform)
|
||||
return {};
|
||||
|
||||
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
|
||||
SDValue ExtLoad =
|
||||
DAG.getExtLoad(ExtLoadType, DL, VT, LN0->getChain(), LN0->getBasePtr(),
|
||||
N0.getValueType(), LN0->getMemOperand());
|
||||
Combiner.ExtendSetCCUses(SetCCs, N0, ExtLoad, DL, ExtOpc);
|
||||
// If the load value is used only by N, replace it via CombineTo N.
|
||||
bool NoReplaceTrunc = SDValue(LN0, 0).hasOneUse();
|
||||
Combiner.CombineTo(N, ExtLoad);
|
||||
if (NoReplaceTrunc) {
|
||||
DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 1), ExtLoad.getValue(1));
|
||||
} else {
|
||||
SDValue Trunc =
|
||||
DAG.getNode(ISD::TRUNCATE, SDLoc(N0), N0.getValueType(), ExtLoad);
|
||||
Combiner.CombineTo(LN0, Trunc, ExtLoad.getValue(1));
|
||||
}
|
||||
return SDValue(N, 0); // Return N so it doesn't get rechecked!
|
||||
}
|
||||
|
||||
SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
|
||||
SDValue N0 = N->getOperand(0);
|
||||
EVT VT = N->getValueType(0);
|
||||
@ -7821,39 +7863,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
|
||||
}
|
||||
}
|
||||
|
||||
// fold (sext (load x)) -> (sext (truncate (sextload x)))
|
||||
// Only generate vector extloads when 1) they're legal, and 2) they are
|
||||
// deemed desirable by the target.
|
||||
if (ISD::isNON_EXTLoad(N0.getNode()) && ISD::isUNINDEXEDLoad(N0.getNode()) &&
|
||||
((!LegalOperations && !VT.isVector() &&
|
||||
!cast<LoadSDNode>(N0)->isVolatile()) ||
|
||||
TLI.isLoadExtLegal(ISD::SEXTLOAD, VT, N0.getValueType()))) {
|
||||
bool DoXform = true;
|
||||
SmallVector<SDNode*, 4> SetCCs;
|
||||
if (!N0.hasOneUse())
|
||||
DoXform = ExtendUsesToFormExtLoad(VT, N, N0, ISD::SIGN_EXTEND, SetCCs,
|
||||
TLI);
|
||||
if (VT.isVector())
|
||||
DoXform &= TLI.isVectorLoadExtDesirable(SDValue(N, 0));
|
||||
if (DoXform) {
|
||||
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
|
||||
SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, DL, VT, LN0->getChain(),
|
||||
LN0->getBasePtr(), N0.getValueType(),
|
||||
LN0->getMemOperand());
|
||||
ExtendSetCCUses(SetCCs, N0, ExtLoad, DL, ISD::SIGN_EXTEND);
|
||||
// If the load value is used only by N, replace it via CombineTo N.
|
||||
bool NoReplaceTrunc = SDValue(LN0, 0).hasOneUse();
|
||||
CombineTo(N, ExtLoad);
|
||||
if (NoReplaceTrunc) {
|
||||
DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 1), ExtLoad.getValue(1));
|
||||
} else {
|
||||
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SDLoc(N0),
|
||||
N0.getValueType(), ExtLoad);
|
||||
CombineTo(LN0, Trunc, ExtLoad.getValue(1));
|
||||
}
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
}
|
||||
// Try to fold (sext (load x)) to a smaller sextload.
|
||||
if (SDValue foldedExt =
|
||||
tryToFoldExtOfLoad(DAG, *this, TLI, VT, LegalOperations, N, N0, DL,
|
||||
ISD::SEXTLOAD, ISD::SIGN_EXTEND))
|
||||
return foldedExt;
|
||||
|
||||
// fold (sext (load x)) to multiple smaller sextloads.
|
||||
// Only on illegal but splittable vectors.
|
||||
|
Loading…
Reference in New Issue
Block a user