Jeffrey A Law wrote: > On Fri, 2006-02-24 at 19:47 +0100, Sebastian Pop wrote: > > Jeffrey A Law wrote: > > > Another possibility is to simply not allow conversions between a > > > subtype and basetype. > > > > Such a patch also solves the problem. But I'm not sure to understand > > the impact on other codes. Is this kind of conversion between a type > > and its basetype specific to Ada? > My suspicions appear to be correct. This never triggers except for > Ada code and it's relatively common in Ada code. No surprise since > I don't think any other front-end abuses TYPE_MAX_VALUE in the way > the Ada front-end does. This wouldn't be the first time we've had > to hack up something in the generic optimizers to deal with the > broken TYPE_MAX_VALUE. >
This is good to know, thanks. I was testing on amd64 this patch that was suggested by Zdenek, it passed bootstrap, but is still not finished the test. As you said, this is a little bit more computation inefficient, so probably the other patch is preferable instead. Index: tree-chrec.c =================================================================== --- tree-chrec.c (revision 111416) +++ tree-chrec.c (working copy) @@ -1210,6 +1210,22 @@ chrec_convert_aggressive (tree type, tre if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type)) return NULL_TREE; + /* In Ada, casts to subtypes are important, as the operations are + performed on the base type and then casted back to the subtype. + We have to preserve these types unless we can prove that the + sequence does not wrap. Subtypes are recognized as the types + whose TYPE_{MIN,MAX}_VALUE are different than the min and max + values computed for that precision. Avoid the aggressive + conversion of these types. */ + if (!POINTER_TYPE_P (type) && !POINTER_TYPE_P (inner_type) + && (integer_zerop (fold_build2 (EQ_EXPR, boolean_type_node, + lower_bound_in_type (type, inner_type), + TYPE_MIN_VALUE (inner_type))) + || integer_zerop (fold_build2 (EQ_EXPR, boolean_type_node, + upper_bound_in_type (type, inner_type), + TYPE_MAX_VALUE (inner_type))))) + return NULL_TREE; + left = CHREC_LEFT (chrec); right = CHREC_RIGHT (chrec); lc = chrec_convert_aggressive (type, left);