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:
Andrew MacLeod 2020-10-09 10:46:50 +02:00 committed by Aldy Hernandez
parent a0e6e49dde
commit 1cde5d85be
2 changed files with 29 additions and 7 deletions

View File

@ -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);

View 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;
}