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