[llvm] e6c145e - [DAGCombiner] widen zext of popcount based on target support

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 25 11:11:07 PDT 2019


Author: Sanjay Patel
Date: 2019-10-25T14:10:51-04:00
New Revision: e6c145e0548e3b3de6eab27e44e1504387cf6b53

URL: https://github.com/llvm/llvm-project/commit/e6c145e0548e3b3de6eab27e44e1504387cf6b53
DIFF: https://github.com/llvm/llvm-project/commit/e6c145e0548e3b3de6eab27e44e1504387cf6b53.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/test/CodeGen/PowerPC/popcnt-zext.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cdf8395046cf..f00e332de9c0 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();
 }
 

diff  --git a/llvm/test/CodeGen/PowerPC/popcnt-zext.ll b/llvm/test/CodeGen/PowerPC/popcnt-zext.ll
index ecad0c77d71e..789e70b2c5b6 100644
--- a/llvm/test/CodeGen/PowerPC/popcnt-zext.ll
+++ b/llvm/test/CodeGen/PowerPC/popcnt-zext.ll
@@ -41,9 +41,8 @@ define i16 @zpop_i8_i16(i8 %x) {
 define i16 @popz_i8_i16(i8 %x) {
 ; FAST-LABEL: popz_i8_i16:
 ; FAST:       # %bb.0:
-; FAST-NEXT:    rlwinm 3, 3, 0, 24, 31
-; FAST-NEXT:    popcntw 3, 3
-; FAST-NEXT:    clrldi 3, 3, 32
+; FAST-NEXT:    clrldi 3, 3, 56
+; FAST-NEXT:    popcntd 3, 3
 ; FAST-NEXT:    blr
 ;
 ; SLOW-LABEL: popz_i8_i16:
@@ -114,9 +113,8 @@ define i32 @zpop_i8_i32(i8 %x) {
 define i32 @popz_i8_32(i8 %x) {
 ; FAST-LABEL: popz_i8_32:
 ; FAST:       # %bb.0:
-; FAST-NEXT:    rlwinm 3, 3, 0, 24, 31
-; FAST-NEXT:    popcntw 3, 3
-; FAST-NEXT:    clrldi 3, 3, 32
+; FAST-NEXT:    clrldi 3, 3, 56
+; FAST-NEXT:    popcntd 3, 3
 ; FAST-NEXT:    blr
 ;
 ; SLOW-LABEL: popz_i8_32:
@@ -187,9 +185,8 @@ define i32 @zpop_i16_i32(i16 %x) {
 define i32 @popz_i16_32(i16 %x) {
 ; FAST-LABEL: popz_i16_32:
 ; FAST:       # %bb.0:
-; FAST-NEXT:    rlwinm 3, 3, 0, 16, 31
-; FAST-NEXT:    popcntw 3, 3
-; FAST-NEXT:    clrldi 3, 3, 32
+; FAST-NEXT:    clrldi 3, 3, 48
+; FAST-NEXT:    popcntd 3, 3
 ; FAST-NEXT:    blr
 ;
 ; SLOW-LABEL: popz_i16_32:


        


More information about the llvm-commits mailing list