Howdy.
I'm looking at the ABS_EXPR code in extract_range_from_unary_expr() and
have noticed that by the time we get here:
/* If a VR_ANTI_RANGEs contains zero, then we have
~[-INF, min(MIN, MAX)]. */
if (vr0.type == VR_ANTI_RANGE)
...we have already handled VR_VARYING, VR_UNDEFINED, and symbolics.
Which means, we only have VR_RANGE of constants to deal with.
Furthermore, we have previously split a VR_ANTI_RANGE into its
constituents and handled them piecemeal:
/* Now canonicalize anti-ranges to ranges when they are not symbolic
and express op ~[] as (op []') U (op []''). */
if (vr0.type == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
Am I missing something, or is this entire block dead code?
/* If a VR_ANTI_RANGEs contains zero, then we have
~[-INF, min(MIN, MAX)]. */
if (vr0.type == VR_ANTI_RANGE)
{
if (range_includes_zero_p (vr0.min, vr0.max) == 1)
{
/* Take the lower of the two values. */
if (cmp != 1)
max = min;
/* Create ~[-INF, min (abs(MIN), abs(MAX))]
or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
flag_wrapv is set and the original anti-range doesn't include
TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE. */
if (TYPE_OVERFLOW_WRAPS (type))
{
tree type_min_value = TYPE_MIN_VALUE (type);
min = (vr0.min != type_min_value
? int_const_binop (PLUS_EXPR, type_min_value,
build_int_cst (TREE_TYPE
(type_min_value), 1))
: type_min_value);
}
else
min = TYPE_MIN_VALUE (type);
}
else
{
/* All else has failed, so create the range [0, INF], even for
flag_wrapv since TYPE_MIN_VALUE is in the original
anti-range. */
vr0.type = VR_RANGE;
min = build_int_cst (type, 0);
max = TYPE_MAX_VALUE (type);
}
}
I tried putting a gcc_unreachable() there, and it never gets triggered
in either a bootstrap or a full test run. I also tried exercising
programmatically extract_range_from_unary_expr() for the entire domain
of a signed char and unsigned char, with and without flag_wrapv (ranges
and anti-ranges), and I can't get the above code to trigger.
Thanks.
Aldy