>From 05879b4239bcb970acfb5c5afe22ef7ebd5cf084 Mon Sep 17 00:00:00 2001
From: Kael Andrew Alonzo Franco <[email protected]>
Date: Wed, 1 Jul 2026 07:10:38 -0400
Subject: [PATCH] match: If a in (0,1), `1 << a` to `a + 1` and `2 >>
a` to `2 - a`. [PR126029]

a + 1 is more common than 1 << a.
2 - a allows more reassoc optimizations like (2 >> a) - 1 to a == 0.

Bootstrapped and tested on x86_64-pc-linux-gnu.

        PR tree-optimization/126029

gcc/ChangeLog:

        PR tree-optimization/126029
        * match.pd: If a in (0,1), `1 << a` to `a + 1` and `2 >> a` to `2 - a`.

gcc/testsuite/ChangeLog:

        PR tree-optimization/126029
        * gcc.dg/pr126029-1.c: New test.

Signed-off-by: Kael Franco <[email protected]>
---
 gcc/match.pd                      | 13 +++++++++++++
 gcc/testsuite/gcc.dg/pr126029-1.c | 16 ++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr126029-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ddf3b61638c..4e8b3044594 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5137,12 +5137,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (rresult @0 { build_int_cst (type, bitop == BIT_IOR_EXPR ? -1 : 0); }))))
 #endif

+/* Fold `2 >> a` into 2 - a for scalar integral types if a is in (0,1).  */
+(simplify
+ (rshift INTEGER_CST@1 zero_one_valued_p@0)
+ (if (INTEGRAL_TYPE_P (type)
+      && wi::eq_p (wi::to_wide (@1), 2))
+  (minus { build_int_cst (type, 2); } (convert:type @0))))
+
 /* Fold `1 >> a` into `a == 0` for scalar integral types. */
 (simplify
  (rshift integer_onep @2)
  (if (INTEGRAL_TYPE_P (type))
   (convert (eq:boolean_type_node @2 { build_zero_cst (TREE_TYPE (@2)); }))))

+/* Fold `1 << a` into `a + 1` for scalar integral types if a is in (0,1).  */
+(simplify
+ (lshift integer_onep zero_one_valued_p@2)
+ (if (INTEGRAL_TYPE_P (type))
+  (plus (convert:type @2) { build_one_cst (type); })))
+
 /* Simplify (CST << x) & 1 to 0 if CST is even or to x == 0 if it is odd.  */
 (simplify
  (bit_and (lshift INTEGER_CST@1 @0) integer_onep)
diff --git a/gcc/testsuite/gcc.dg/pr126029-1.c
b/gcc/testsuite/gcc.dg/pr126029-1.c
new file mode 100644
index 00000000000..354220adebc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126029-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+one_lshift_a (_Bool a)
+{
+  return (1 << a) == (a + 1);
+}
+
+int
+two_rshift_a (_Bool a)
+{
+  return (2 >> a) == (2 - a);
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
-- 
2.54.0

Reply via email to