Also add its counterpart:
"(A>>bool) != 0 -> (unsigned)A) > bool"
Changes from v2:
- gate the pattern with "#if GIMPLE"
- use 'single_use' in the rshift result
- add the NE variant
link: https://gcc.gnu.org/pipermail/gcc-patches/2026-April/712431.html
Bootstrap tested in x86, aarch64 and RISC-V.
Regression tested in x86 and aarch64.
PR tree-optimization/119420
gcc/ChangeLog
* match.pd(`(A>>bool) EQ 0 -> (unsigned)A LE bool`): New
pattern.
gcc/testsuite/ChangeLog
* gcc.dg/tree-ssa/pr119420.c: New test.
@0)))))
#endif
+#if GIMPLE
+/* PR119420: (A >> bool) == 0 -> (unsigned)a <= (unsigned)bool
+ and its variant:
+ (A >> bool) != 0 -> (unsigned)a > (unsigned)bool; */
+(for cmp (eq ne)
+ icmp (le gt)
+ (simplify
+ (cmp (rshift@2 @0 zero_one_valued_p@1) integer_zerop)
+ (if (single_use (@2))
+ (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+ (icmp (convert:utype @0) (convert:utype @1))))))
+#endif
+
/* Rewrite an LROTATE_EXPR by a constant into an
RROTATE_EXPR by a new constant. */
(simplify
--- /dev/null
+/* { dg-additional-options -O2 } */
+/* { dg-additional-options -fdump-tree-optimized } */
+
+int ll (signed a)
+{
+ int d = a >> 1;
+ return d == 0;
+}
+
+int ll1 (signed a)
+{
+ int d = a & ~1;
+ return d == 0;
+}
+
+int ll2 (signed a)
+{
+ unsigned aa = a;
+ return aa <= 1;
+}
+
+int ll3 (signed a)
+{
+ int d = a >> 1;
+ return d != 0;
+}
+
+int ll4 (signed a)
+{
+ int d = a & ~1;
+ return d != 0;
+}
+
+int ll5 (signed a)
+{
+ unsigned aa = a;
+ return aa > 1;
+}
+
+/* { dg-final { scan-tree-dump-times " >> " 0 optimized } } */
+/* { dg-final { scan-tree-dump-times " <= " 3 optimized } } */
+/* { dg-final { scan-tree-dump-times " > " 3 optimized } } */