summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2018-05-11 18:40:02 +0000
committerVedant Kumar <vsk@apple.com>2018-05-11 18:40:02 +0000
commitf0e5f7c45e940c80623c60b89b28b8806a899841 (patch)
tree6a177fc510cb9558d29c345993c9a32857111469 /llvm/lib
parentd1386a88dd1654f79544e93b03985b8700a3dbea (diff)
downloadbcm5719-llvm-f0e5f7c45e940c80623c60b89b28b8806a899841.tar.gz
bcm5719-llvm-f0e5f7c45e940c80623c60b89b28b8806a899841.zip
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp90
1 files changed, 52 insertions, 38 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 22c31a0e78c..3a49cce59c7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -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.
OpenPOWER on IntegriCloud