]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match.pd: Fix popcount (X) + popcount (Y) simplification [PR112719]
authorJakub Jelinek <jakub@redhat.com>
Tue, 28 Nov 2023 09:14:55 +0000 (10:14 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 28 Nov 2023 09:14:55 +0000 (10:14 +0100)
Since my PR112566 r14-5557 changes the following testcase ICEs, because
.POPCOUNT (x) + .POPCOUNT (y) has a simplification attempted even when
x and y have incompatible types (different precisions).
Note, with _BitInt it can ICE already starting with r14-5435 and
I think as a latent problem it exists for years, because IFN_POPCOUNT
calls inherently can have different argument types and return type
is always the same.
The following patch fixes it by using widest_int during the analysis
(which is where it was ICEing) and if it is optimizable, casting to
the wider type so that bit_ior has matching argument types.

2023-11-28  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/112719
* match.pd (popcount (X) + popcount (Y) -> POPCOUNT (X | Y)): Deal
with argument types with different precisions.

gcc/match.pd
gcc/testsuite/gcc.dg/pr112719.c [new file with mode: 0644]

index 95225e4ca5f6ad651226d8d88fc112092516ec7f..0382fd53256a905f26be03fd7ecbfeba8a0f8c61 100644 (file)
@@ -8732,8 +8732,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (simplify
   (plus (POPCOUNT:s @0) (POPCOUNT:s @1))
   (if (INTEGRAL_TYPE_P (type)
-       && wi::bit_and (tree_nonzero_bits (@0), tree_nonzero_bits (@1)) == 0)
-    (POPCOUNT (bit_ior @0 @1))))
+       && (wi::bit_and (widest_int::from (tree_nonzero_bits (@0), UNSIGNED),
+                       widest_int::from (tree_nonzero_bits (@1), UNSIGNED))
+          == 0))
+   (with { tree utype = TREE_TYPE (@0);
+          if (TYPE_PRECISION (utype) < TYPE_PRECISION (TREE_TYPE (@1)))
+            utype = TREE_TYPE (@1); }
+    (POPCOUNT (bit_ior (convert:utype @0) (convert:utype @1))))))
 
 /* popcount(X) == 0 is X == 0, and related (in)equalities.  */
 (for popcount (POPCOUNT)
diff --git a/gcc/testsuite/gcc.dg/pr112719.c b/gcc/testsuite/gcc.dg/pr112719.c
new file mode 100644 (file)
index 0000000..c69a7c1
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR tree-optimization/112719 */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-additional-options "-msse4" { target i?86-*-* x86_64-*-* } } */
+
+int
+foo (unsigned int a, unsigned short b)
+{
+  return __builtin_popcountl (a) + __builtin_popcountl (b);
+}
+
+int
+bar (unsigned int a, unsigned short b)
+{
+  a &= 0xaaaaaaaaUL;
+  b &= 0x5555;
+  return __builtin_popcountll (a) + __builtin_popcountll (b);
+}