summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-10-25 13:34:40 -0400
committerSanjay Patel <spatel@rotateright.com>2019-10-25 14:10:51 -0400
commite6c145e0548e3b3de6eab27e44e1504387cf6b53 (patch)
tree8ff26c2cb1af6be97bceb07b4bc7c4c169fa87d3 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parentc35b358b741b942aa89acb1fe0d22d4126287493 (diff)
downloadbcm5719-llvm-e6c145e0548e3b3de6eab27e44e1504387cf6b53.tar.gz
bcm5719-llvm-e6c145e0548e3b3de6eab27e44e1504387cf6b53.zip
[DAGCombiner] widen zext of popcount based on target support
zext (ctpop X) --> ctpop (zext X) 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 I'm not sure if any other targets are affected, but I found a missing fold for PPC, so added tests based on that. The reason we widen all the way to 64-bit in these tests is because the initial DAG looks something like this: t5: i8 = ctpop t4 t6: i32 = zero_extend t5 <-- created based on IR, but unused node? t7: i64 = zero_extend t5 Differential Revision: https://reviews.llvm.org/D69127
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cdf8395046c..f00e332de9c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9921,6 +9921,18 @@ 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);
+ }
+
return SDValue();
}
OpenPOWER on IntegriCloud