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

Reply via email to