https://gcc.gnu.org/g:9560cd83671a32ee2253f307112ac39b40aa712c

commit r16-1562-g9560cd83671a32ee2253f307112ac39b40aa712c
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Wed May 28 16:27:16 2025 -0400

    Improve contains_p and intersect with bitmasks.
    
    Improve the way contains_p (wide_int) and intersect behave wioth
    singletons and bitmasks.  Also fix a buglet in bitmask_intersect when the
    result is a singleton which is not in the current range.
    
            PR tree-optimization/119039
            gcc/
            * value-range.cc (irange::contains_p): Call wide_int version of
            contains_p for singleton ranges.
            (irange::intersect): If either range is a singleton, use
            contains_p.
    
            gcc/testsuite/
            * gcc.dg/pr119039-2.c: New.

Diff:
---
 gcc/testsuite/gcc.dg/pr119039-2.c | 60 +++++++++++++++++++++++++++++++++++++++
 gcc/value-range.cc                | 23 +++++++++++----
 2 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr119039-2.c 
b/gcc/testsuite/gcc.dg/pr119039-2.c
new file mode 100644
index 000000000000..634b40028209
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119039-2.c
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void good (void);
+extern void bad (void);
+
+/* Switch simplification should remove 'case 2:' because 'i' will always
+ * have its 0th bit set (odd). */
+
+void bitmask_elimination_1(int i)
+{
+  i = i | 1;
+
+  switch (i)
+    {
+    case 1:
+      good ();
+      break;
+
+    // This case should be removed;
+    case 2:
+      bad ();
+      break;
+
+    case 3:
+      good ();
+      break;
+
+    default:
+      break;
+    }
+}
+
+/* Switch simplification should remove 'case 20-28:' because 'i' will always
+ * be a multiple of 16.  */
+void bitmask_elimination_2 (int i)
+{
+  int masked_val = i & 0xF0; // This zeroes out the lower 4 bits of 'i'
+
+  switch (masked_val)
+  {
+    case 0:
+      good (); // Reachable.
+      break;
+
+    // This entire cased should be removed;
+    case 20 ... 28:
+      bad ();
+      break;
+
+    case 32:
+      good (); // Reachable.
+      break;
+
+    default:
+      good ();
+      break;
+  }
+}
+/* { dg-final { scan-tree-dump-not "bad" "evrp" } } */
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 5e97fdb76919..348c68ec902e 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1628,10 +1628,8 @@ irange::contains_p (const wide_int &cst) const
   if (undefined_p ())
     return false;
 
-  // See if we can exclude CST based on the known 0 bits.
-  if (!m_bitmask.unknown_p ()
-      && cst != 0
-      && wi::bit_and (m_bitmask.get_nonzero_bits (), cst) == 0)
+  // Check is the known bits in bitmask exclude CST.
+  if (!m_bitmask.member_p (cst))
     return false;
 
   signop sign = TYPE_SIGN (type ());
@@ -1899,12 +1897,17 @@ irange::irange_contains_p (const irange &r) const
   gcc_checking_assert (!undefined_p () && !varying_p ());
   gcc_checking_assert (!r.undefined_p () && !varying_p ());
 
+  // Check singletons directly which will include any bitmasks.
+  wide_int rl;
+  if (r.singleton_p (rl))
+    return contains_p (rl);
+
   // In order for THIS to fully contain R, all of the pairs within R must
   // be fully contained by the pairs in this object.
   signop sign = TYPE_SIGN (m_type);
   unsigned ri = 0;
   unsigned i = 0;
-  wide_int rl = r.m_base[0];
+  rl = r.m_base[0];
   wide_int ru = r.m_base[1];
   wide_int l = m_base[0];
   wide_int u = m_base[1];
@@ -1973,6 +1976,16 @@ irange::intersect (const vrange &v)
       return res;
     }
 
+  // If either range is a singleton and the other range does not contain
+  // it, the result is undefined.
+  wide_int val;
+  if ((singleton_p (val) && !r.contains_p (val))
+      || (r.singleton_p (val) && !contains_p (val)))
+    {
+      set_undefined ();
+      return true;
+    }
+
   // If R fully contains this, then intersection will change nothing.
   if (r.irange_contains_p (*this))
     return intersect_bitmask (r);

Reply via email to