// Test 1-bit signed integer union.
// [-1,-1] U [0,0] = VARYING.
tree one_bit_type = build_nonstandard_integer_type (1, 0);
+ tree one_bit_min = vrp_val_min (one_bit_type);
+ tree one_bit_max = vrp_val_max (one_bit_type);
{
- tree one_bit_min = vrp_val_min (one_bit_type);
- tree one_bit_max = vrp_val_max (one_bit_type);
int_range<2> min (one_bit_min, one_bit_min);
int_range<2> max (one_bit_max, one_bit_max);
max.union_ (min);
ASSERT_TRUE (max.varying_p ());
}
+ // Test inversion of 1-bit signed integers.
+ {
+ int_range<2> min (one_bit_min, one_bit_min);
+ int_range<2> max (one_bit_max, one_bit_max);
+ int_range<2> t;
+ t = min;
+ t.invert ();
+ ASSERT_TRUE (t == max);
+ t = max;
+ t.invert ();
+ ASSERT_TRUE (t == min);
+ }
+
// Test that NOT(255) is [0..254] in 8-bit land.
int_range<1> not_255 (UCHAR (255), UCHAR (255), VR_ANTI_RANGE);
ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254)));
verify_range ();
}
+// Signed 1-bits are strange. You can't subtract 1, because you can't
+// represent the number 1. This works around that for the invert routine.
+
static wide_int inline
subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow)
{
- // A signed 1-bit bit-field, has a range of [-1,0] so subtracting +1
- // overflows, since +1 is unrepresentable. This is why we have an
- // addition of -1 here.
if (TYPE_SIGN (type) == SIGNED)
- return wi::add (x, -1 , SIGNED, &overflow);
+ return wi::add (x, -1, SIGNED, &overflow);
else
return wi::sub (x, 1, UNSIGNED, &overflow);
}
-/* Return the inverse of a range. */
+// The analogous function for adding 1.
+
+static wide_int inline
+add_one (const wide_int &x, tree type, wi::overflow_type &overflow)
+{
+ if (TYPE_SIGN (type) == SIGNED)
+ return wi::sub (x, -1, SIGNED, &overflow);
+ else
+ return wi::add (x, 1, UNSIGNED, &overflow);
+}
+
+// Return the inverse of a range.
void
irange::invert ()
// set the overflow bit.
if (type_max != wi::to_wide (orig_range.m_base[i]))
{
- tmp = wi::add (wi::to_wide (orig_range.m_base[i]), 1, sign, &ovf);
+ tmp = add_one (wi::to_wide (orig_range.m_base[i]), ttype, ovf);
m_base[nitems++] = wide_int_to_tree (ttype, tmp);
m_base[nitems++] = wide_int_to_tree (ttype, type_max);
if (ovf)