]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Recognize popcount also when a double width operation is needed.
authorJoern Rennecke <joern.rennecke@riscy-ip.com>
Fri, 28 May 2021 08:34:07 +0000 (09:34 +0100)
committerJoern Rennecke <joern.rennecke@riscy-ip.com>
Fri, 28 May 2021 08:40:41 +0000 (09:40 +0100)
2021-05-28  Joern Rennecke  <joern.rennecke@riscy-ip.com>
gcc/
* match.pd <popcount & / + pattern matching>:
When generating popcount directly fails, try doing it in two halves.
gcc/testsuite/
* gcc.dg/tree-ssa/popcount4ll.c: Remove lp64 condition.
Adjust scanning pattern for !lp64.
* gcc.dg/tree-ssa/popcount5ll.c: Likewise.
* gcc.dg/tree-ssa/popcount4l.c: Adjust scanning pattern
for ! int32plus.

Co-Authored-By: Richard Biener <rguenther@suse.de>
gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c
gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c
gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c

index b60e2703f60a9dbb32225204cf572db461a24100..d06ff170684abb65e30196899774fb85b53ae295 100644 (file)
@@ -6642,10 +6642,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && tree_to_uhwi (@3) == c2
        && tree_to_uhwi (@9) == c3
        && tree_to_uhwi (@7) == c3
-       && tree_to_uhwi (@11) == c4
-       && direct_internal_fn_supported_p (IFN_POPCOUNT, type,
-                                          OPTIMIZE_FOR_BOTH))
-    (convert (IFN_POPCOUNT:type @0)))))
+       && tree_to_uhwi (@11) == c4)
+    (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type,
+                                        OPTIMIZE_FOR_BOTH))
+     (convert (IFN_POPCOUNT:type @0))
+     /* Try to do popcount in two halves.  PREC must be at least
+       five bits for this to work without extension before adding.  */
+     (with {
+       tree half_type = NULL_TREE;
+       opt_machine_mode m = mode_for_size ((prec + 1) / 2, MODE_INT, 1);
+       int half_prec = 8;
+       if (m.exists ()
+          && m.require () != TYPE_MODE (type))
+        {
+          half_prec = GET_MODE_PRECISION (as_a <scalar_int_mode> (m));
+          half_type = build_nonstandard_integer_type (half_prec, 1);
+        }
+       gcc_assert (half_prec > 2);
+      }
+      (if (half_type != NULL_TREE
+          && direct_internal_fn_supported_p (IFN_POPCOUNT, half_type,
+                                             OPTIMIZE_FOR_BOTH))
+       (convert (plus
+        (IFN_POPCOUNT:half_type (convert @0))
+        (IFN_POPCOUNT:half_type (convert (rshift @0
+           { build_int_cst (integer_type_node, half_prec); } )))))))))))
 
 /* __builtin_ffs needs to deal on many targets with the possible zero
    argument.  If we know the argument is always non-zero, __builtin_ctz + 1
index 69fb2d1134d3103d250b94139bd1d69ae915cce1..269e56e90f92ce23559431d79c21d533342ffa43 100644 (file)
@@ -25,6 +25,7 @@ int popcount64c(unsigned long x)
     return (x * h01) >> shift;
 }
 
-/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target int32plus } } } */
+/* { dg-final { scan-tree-dump "\.POPCOUNT" "optimized" { target { ! int32plus } } } } */
 
 
index c1588be68e4975a0524438adaebd8deb7c0ee440..7abadf6df04fcc47405a4a611a1f9139f25cfc4b 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { lp64 } } } */
+/* { dg-do compile } */
 /* { dg-require-effective-target popcountll } */
 /* { dg-options "-O2 -fdump-tree-optimized" } */
 
@@ -16,4 +16,5 @@ int popcount64c(unsigned long long x)
     return (x * h01) >> shift;
 }
 
-/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */
+/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */
index edb191bf8941690a8da800d68feb249e9d67c382..2afe08124feedfdb87541c6ee50f5838a2bb438e 100644 (file)
@@ -1,5 +1,5 @@
 /* PR tree-optimization/94800 */
-/* { dg-do compile { target { lp64 } } } */
+/* { dg-do compile } */
 /* { dg-require-effective-target popcountll } */
 /* { dg-options "-O2 -fdump-tree-optimized" } */
 
@@ -19,4 +19,5 @@ int popcount64c(unsigned long long x)
     return x >> shift;
 }
 
-/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */
+/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */