https://gcc.gnu.org/g:13f5a627dcab882fdf9183f96a8270c7f5229f95

commit r16-4253-g13f5a627dcab882fdf9183f96a8270c7f5229f95
Author: Andrew MacLeod <[email protected]>
Date:   Thu Oct 2 11:51:01 2025 -0400

    If a range's bitmask changes, reflect it in the bounds.
    
    Rather than trying to be smart, if the bitmask changes, adjust all range
    bounds to satisfy the bitmask requirements.
    
            PR tree-optimization/121206
            gcc/
            * value-range.cc (irange::intersect_bitmask): Always call
            set_range_from_bitmask if the bitmask changes.
    
            gcc/testsuite
            * gcc.dg/pr121987.c: New.

Diff:
---
 gcc/testsuite/gcc.dg/pr121987.c | 16 ++++++++++++++++
 gcc/value-range.cc              | 11 ++++-------
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr121987.c b/gcc/testsuite/gcc.dg/pr121987.c
new file mode 100644
index 000000000000..04845a4d8caa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr121987.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+int a, b, c, d;
+int main() {
+  unsigned long e = 10000000000;
+  unsigned f;
+  int g;
+  while (a) {
+    c = 1;
+    d = f;
+    f = ~(~(~(b && g) % a * ~e) << c);
+    b = e && f % e + ~f;
+    g = a;
+  }
+  return 0;
+}
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index dc6909e77c54..d34a2623db44 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -2552,22 +2552,19 @@ irange::intersect_bitmask (const irange &r)
 {
   gcc_checking_assert (!undefined_p () && !r.undefined_p ());
 
+  // If the bitmasks are the same, do nothing.
   if (m_bitmask == r.m_bitmask)
     return false;
 
   irange_bitmask bm = get_bitmask ();
   irange_bitmask save = bm;
   bm.intersect (r.get_bitmask ());
-  // Use ths opportunity to make sure mask always reflects the
-  // best mask we have.
-  m_bitmask = bm;
 
-  // Updating m_bitmask may still yield a semantic bitmask (as
-  // returned by get_bitmask) which is functionally equivalent to what
-  // we originally had.  In which case, there's still no change.
-  if (save == bm || save == get_bitmask ())
+  // If the new mask is the same, there is no change.
+  if (m_bitmask == bm)
     return false;
 
+  m_bitmask = bm;
   if (!set_range_from_bitmask ())
     normalize_kind ();
   if (flag_checking)

Reply via email to