Fix for PR97317.
gcc/ChangeLog: PR tree-optimization/97317 * range-op.cc (operator_cast::op1_range): Handle casts where the precision of the RHS is only 1 greater than the precision of the LHS. gcc/testsuite/ChangeLog: * gcc.dg/pr97317.c: New test.
This commit is contained in:
parent
a0e6e49dde
commit
1cde5d85be
@ -1849,14 +1849,25 @@ operator_cast::op1_range (irange &r, tree type,
|
||||
type,
|
||||
converted_lhs,
|
||||
lim_range);
|
||||
// And union this with the entire outer types negative range.
|
||||
int_range_max neg (type,
|
||||
wi::min_value (TYPE_PRECISION (type),
|
||||
SIGNED),
|
||||
lim - 1);
|
||||
neg.union_ (lhs_neg);
|
||||
// lhs_neg now has all the negative versions of the LHS.
|
||||
// Now union in all the values from SIGNED MIN (0x80000) to
|
||||
// lim-1 in order to fill in all the ranges with the upper
|
||||
// bits set.
|
||||
|
||||
// PR 97317. If the lhs has only 1 bit less precision than the rhs,
|
||||
// we don't need to create a range from min to lim-1
|
||||
// calculate neg range traps trying to create [lim, lim - 1].
|
||||
wide_int min_val = wi::min_value (TYPE_PRECISION (type), SIGNED);
|
||||
if (lim != min_val)
|
||||
{
|
||||
int_range_max neg (type,
|
||||
wi::min_value (TYPE_PRECISION (type),
|
||||
SIGNED),
|
||||
lim - 1);
|
||||
lhs_neg.union_ (neg);
|
||||
}
|
||||
// And finally, munge the signed and unsigned portions.
|
||||
r.union_ (neg);
|
||||
r.union_ (lhs_neg);
|
||||
}
|
||||
// And intersect with any known value passed in the extra operand.
|
||||
r.intersect (op2);
|
||||
|
11
gcc/testsuite/gcc.dg/pr97317.c
Normal file
11
gcc/testsuite/gcc.dg/pr97317.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
struct a {
|
||||
unsigned c : 17;
|
||||
};
|
||||
struct a b;
|
||||
int d(void) {
|
||||
short e = b.c;
|
||||
return e ? 0 : b.c;
|
||||
}
|
Loading…
Reference in New Issue
Block a user