https://gcc.gnu.org/g:8b9cd6490ce507a8e3612044137bd2024e8658c4

commit r16-4604-g8b9cd6490ce507a8e3612044137bd2024e8658c4
Author: Andrew MacLeod <[email protected]>
Date:   Thu Oct 23 17:19:02 2025 -0400

    Split signed bitwise AND operations.
    
    The algorithm for bitwise AND struggles with complex signed operations
    which cross the signed/unsigned barrier.  When this happens, process it
    as 2 seperate ranges [LB, -1] and [0, UB], and combine the results.
    
            PR tree-optimization/114725.c
            gcc/
            * range-op.cc (operator_bitwise_and::wi_fold): Split signed
            operations crossing zero into 2 operations.
    
            gcc/testsuite/
            * gcc.dg/pr114725.c: New.

Diff:
---
 gcc/range-op.cc                 | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/pr114725.c | 15 +++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 762fd349e5f7..6b6bf78cb2f1 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3522,6 +3522,22 @@ operator_bitwise_and::wi_fold (irange &r, tree type,
                               const wide_int &rh_lb,
                               const wide_int &rh_ub) const
 {
+  // The AND algorithm does not handle complex signed operations well.
+  // If a signed range crosses the boundry between signed and unsigned
+  // proces sit as 2 ranges and union the results.
+  if (TYPE_SIGN (type) == SIGNED
+      && wi::neg_p (lh_lb, SIGNED) != wi::neg_p (lh_ub, SIGNED))
+    {
+      int prec = TYPE_PRECISION (type);
+      int_range_max tmp;
+      // Process [lh_lb, -1]
+      wi_fold (tmp, type, lh_lb, wi::minus_one (prec), rh_lb, rh_ub);
+      // Now Process [0, rh_ub]
+      wi_fold (r, type, wi::zero (prec), lh_ub, rh_lb, rh_ub);
+      r.union_ (tmp);
+      return;
+    }
+
   if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
     return;
 
diff --git a/gcc/testsuite/gcc.dg/pr114725.c b/gcc/testsuite/gcc.dg/pr114725.c
new file mode 100644
index 000000000000..01c31399ba86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114725.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+//* This should fold to return 0
+bool
+src(int offset)
+{
+  if (offset > 128)
+    return 0;
+  else
+    return (offset & -9) == 258;
+}
+
+/* { dg-final { scan-tree-dump "return 0"  "optimized" } } */
+/* { dg-final { scan-tree-dump-not "PHI"  "optimized" } } */

Reply via email to