summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-10-28 10:04:30 -0400
committerSanjay Patel <spatel@rotateright.com>2019-10-28 10:07:12 -0400
commit1ebd4a2e3ad0e95ee915ed5a99aab53f8fe7da95 (patch)
tree742519bc1db5779b4c51c937f09ee413ed7bab12 /llvm/lib
parent35cb3ee4ca477095bb3dd74f60ab932e185be63f (diff)
downloadbcm5719-llvm-1ebd4a2e3ad0e95ee915ed5a99aab53f8fe7da95.tar.gz
bcm5719-llvm-1ebd4a2e3ad0e95ee915ed5a99aab53f8fe7da95.zip
[DAGCombiner] widen any_ext of popcount based on target support
This enhances D69127 (rGe6c145e0548e3b3de6eab27e44e1504387cf6b53) to handle the looser "any_extend" cast in addition to zext. This is a prerequisite step for canonicalizing in the other direction (narrow the popcount) in IR - PR43688: https://bugs.llvm.org/show_bug.cgi?id=43688
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp39
1 files changed, 28 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 6b30ebecbea..5003c8f0536 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9673,6 +9673,29 @@ static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op,
return (Known.Zero | 1).isAllOnesValue();
}
+/// Given an extending node with a pop-count operand, if the target does not
+/// support a pop-count in the narrow source type but does support it in the
+/// destination type, widen the pop-count to the destination type.
+static SDValue widenCtPop(SDNode *Extend, SelectionDAG &DAG) {
+ assert((Extend->getOpcode() == ISD::ZERO_EXTEND ||
+ Extend->getOpcode() == ISD::ANY_EXTEND) && "Expected extend op");
+
+ SDValue CtPop = Extend->getOperand(0);
+ if (CtPop.getOpcode() != ISD::CTPOP || !CtPop.hasOneUse())
+ return SDValue();
+
+ EVT VT = Extend->getValueType(0);
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLI.isOperationLegalOrCustom(ISD::CTPOP, CtPop.getValueType()) ||
+ !TLI.isOperationLegalOrCustom(ISD::CTPOP, VT))
+ return SDValue();
+
+ // zext (ctpop X) --> ctpop (zext X)
+ SDLoc DL(Extend);
+ SDValue NewZext = DAG.getZExtOrTrunc(CtPop.getOperand(0), DL, VT);
+ return DAG.getNode(ISD::CTPOP, DL, VT, NewZext);
+}
+
SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
@@ -9923,17 +9946,8 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
if (SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
return NewVSel;
- // If the target does not support a pop-count in the narrow source type but
- // does support it in the destination type, widen the pop-count to this type:
- // zext (ctpop X) --> ctpop (zext X)
- // TODO: Generalize this to handle starting from anyext.
- if (N0.getOpcode() == ISD::CTPOP && N0.hasOneUse() &&
- !TLI.isOperationLegalOrCustom(ISD::CTPOP, N0.getValueType()) &&
- TLI.isOperationLegalOrCustom(ISD::CTPOP, VT)) {
- SDLoc DL(N);
- SDValue NewZext = DAG.getZExtOrTrunc(N0.getOperand(0), DL, VT);
- return DAG.getNode(ISD::CTPOP, DL, VT, NewZext);
- }
+ if (SDValue NewCtPop = widenCtPop(N, DAG))
+ return NewCtPop;
return SDValue();
}
@@ -10081,6 +10095,9 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
return SCC;
}
+ if (SDValue NewCtPop = widenCtPop(N, DAG))
+ return NewCtPop;
+
return SDValue();
}
OpenPOWER on IntegriCloud