[PATCH] Fix a couple of problems in fold's range code
Eric Botcazou
ebotcazou@adacore.com
Wed Mar 8 21:51:00 GMT 2006
The first problem is responsible for the ACATS cxa4025, cxa4028 and cxa4033
failures. When build_range_check applies the transformation:
Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low)
it doesn't always care about whether it can really do it in the original type,
in particular for ENUMERAL_TYPEs in this case.
The patch is more of an overhaul than a simple fix because
http://gcc.gnu.org/ml/gcc-patches/2005-07/msg00879.html
has seriously modified the behaviour of the code.
The second problem is in merge_ranges. I don't have a testcase for the FSF
compiler although I have one for our compiler at AdaCore. The problem boils
down to merge_ranges returning
+ [0, -]
on the couple of ranges (- [-, TYPE_MAX_VALUE], + [0, -] ), while the correct
result is - [-, -] if I'm not mistaken. The problematic code is:
else if (! in0_p && in1_p)
{
/* If they don't overlap, the result is the second range. If the second
is a subset of the first, the result is false. Otherwise,
the range starts just after the first range and ends at the
end of the second. */
if (no_overlap)
in_p = 1, low = low1, high = high1;
else if (subset || highequal)
in_p = 0, low = high = 0;
else
{
in_p = 1, high = high1;
low = range_binop (PLUS_EXPR, NULL_TREE, high0, 1,
integer_one_node, 0);
}
}
If 'high0' is equal to TYPE_MAX_VALUE, the addition wraps around and 'low'
ends up being 0 (if the type is unsigned).
The proposed fix is to introduce a couple of functions, range_predecessor and
range_successor, and using them throughout merge_ranges.
The whole thing has been bootstrapped/regtested on x86_64-suse-linux with
=== acats tests ===
FAIL: c34004a
FAIL: c46033a
FAIL: cdd2a02
FAIL: cxg2024
=== acats Summary ===
# of expected passes 2313
# of unexpected failures 4
which means PR middle-end/26561 is the only remaining hurdle.
2006-03-08 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (build_range_check): Make sure to use a valid type to
apply the "(c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low)"
transformation.
(range_predecessor): New static function.
(range_successor): Likewise.
(merge_ranges): Use them to compute predecessors and successors of
range bounds.
--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: f303-013-3.diff
Type: text/x-diff
Size: 7105 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060308/38db6161/attachment.bin>
More information about the Gcc-patches
mailing list