]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match: Optimize (~a) >> a to -1 for signed a [PR125707]
authorKael Andrew Alonzo Franco <kaelfandrew@gmail.com>
Fri, 12 Jun 2026 09:55:56 +0000 (05:55 -0400)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Sat, 13 Jun 2026 03:03:53 +0000 (20:03 -0700)
For signed a, (~a) >> a is the same as ~(a>>a) which is ~0 aka -1.

Bootstrapped and tested on x86_64-pc-linux-gnu

PR tree-optimization/125707

gcc/ChangeLog:

PR tree-optimization/125707
* match.pd: Add (~a) >> a to -1 for signed a.

gcc/testsuite/ChangeLog:

PR tree-optimization/125707
* gcc.dg/pr125707.c: New test.

Signed-off-by: Kael Franco <kaelfandrew@gmail.com>
gcc/match.pd
gcc/testsuite/gcc.dg/pr125707.c [new file with mode: 0644]

index e0d7ef80e14dbb8fd442a255358f2e03318cff56..ea4a447f0814770dce428559a003b697d50bd014 100644 (file)
@@ -1831,6 +1831,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && wi::to_wide (@1) != wi::min_value (TYPE_PRECISION (type),
                                              SIGNED))
     (minus (plus @1 { build_minus_one_cst (type); }) @0))))
+
+/* (~X) >> X -> -1 for signed X.  */
+(simplify
+ (rshift (bit_not @0) (convert? @0))
+ (if (INTEGRAL_TYPE_P (type)
+      && !TYPE_UNSIGNED (type))
+  { build_minus_one_cst (type); }))
 #endif
 
 /* ~(X >> Y) -> ~X >> Y if ~X can be simplified.  */
diff --git a/gcc/testsuite/gcc.dg/pr125707.c b/gcc/testsuite/gcc.dg/pr125707.c
new file mode 100644 (file)
index 0000000..7c1de12
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+rshift_bit_not_int_x_x (int x)
+{
+  return (~x) >> x;
+}
+
+long
+rshift_bit_not_long_x_x (long x)
+{
+  return (~x) >> x;
+}
+
+/* { dg-final { scan-tree-dump-times "return -1;" 2 "optimized" } } */