irange: Compare nonzero bits in irange with widest_int [PR108639]
The problem here is we are trying to compare two ranges with different precisions and the == operator in wide_int is complaining. Interestingly, the problem is not the nonzero bits, but the fact that the entire ranges have different precisions. The reason we don't ICE when comparing the sub-ranges, is because the code in irange::operator== works on trees, and tree_int_cst_equal is promoting the comparison to a widest int: if (TREE_CODE (t1) == INTEGER_CST && TREE_CODE (t2) == INTEGER_CST && wi::to_widest (t1) == wi::to_widest (t2)) return 1; This is why we don't see the ICE until the nonzero bits comparison is done on wide ints. I think we should maintain the current equality behavior, and follow suit in the nonzero bit comparison. I have also fixed the legacy equality code, even though technically nonzero bits shouldn't appear in legacy. But better safe than sorry. PR tree-optimization/108639 gcc/ChangeLog: * value-range.cc (irange::legacy_equal_p): Compare nonzero bits as widest_int. (irange::operator==): Same.
This commit is contained in:
parent
10bd26d6ef
commit
e261fcefb7
3 changed files with 32 additions and 2 deletions
12
gcc/testsuite/gcc.c-torture/compile/pr108638.c
Normal file
12
gcc/testsuite/gcc.c-torture/compile/pr108638.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* PR tree-optimization/108638 */
|
||||
|
||||
long long a;
|
||||
int b;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
for (a = 0; a < __SIZEOF_LONG_LONG__ * __CHAR_BIT__; a++)
|
||||
if (b)
|
||||
b |= a << a;
|
||||
}
|
11
gcc/testsuite/gcc.c-torture/compile/pr108639.c
Normal file
11
gcc/testsuite/gcc.c-torture/compile/pr108639.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* PR tree-optimization/108639 */
|
||||
|
||||
long long a;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
a = a ? 0 || 0 % 0 : 0;
|
||||
a = a << a;
|
||||
return 0;
|
||||
}
|
|
@ -1259,7 +1259,10 @@ irange::legacy_equal_p (const irange &other) const
|
|||
other.tree_lower_bound (0))
|
||||
&& vrp_operand_equal_p (tree_upper_bound (0),
|
||||
other.tree_upper_bound (0))
|
||||
&& get_nonzero_bits () == other.get_nonzero_bits ());
|
||||
&& (widest_int::from (get_nonzero_bits (),
|
||||
TYPE_SIGN (type ()))
|
||||
== widest_int::from (other.get_nonzero_bits (),
|
||||
TYPE_SIGN (other.type ()))));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1294,7 +1297,11 @@ irange::operator== (const irange &other) const
|
|||
|| !operand_equal_p (ub, ub_other, 0))
|
||||
return false;
|
||||
}
|
||||
return get_nonzero_bits () == other.get_nonzero_bits ();
|
||||
widest_int nz1 = widest_int::from (get_nonzero_bits (),
|
||||
TYPE_SIGN (type ()));
|
||||
widest_int nz2 = widest_int::from (other.get_nonzero_bits (),
|
||||
TYPE_SIGN (other.type ()));
|
||||
return nz1 == nz2;
|
||||
}
|
||||
|
||||
/* Return TRUE if this is a symbolic range. */
|
||||
|
|
Loading…
Add table
Reference in a new issue