--- /dev/null
+/* { 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" } } */
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 ());
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];
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);