>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