On Wed, 9 Dec 2020, Jakub Jelinek wrote:

> On Wed, Dec 09, 2020 at 09:03:36AM +0100, Richard Biener wrote:
> > > For Ada with LTO, boolean_{false,true}_node can be 1-bit precision 
> > > boolean,
> > > while TREE_TYPE (lhs) can be 8-bit precision boolean and thus we can end 
> > > up
> > > with wide_int mismatches.
> > > 
> > > The following patch fixes it by using TYPE_{MIN,MAX}_VALUE instead.
> > 
> > Are you sure the Ada boolean types have 1/0 as MIN/MAX value?  ISTR
> > that's not the case as the middle-end has to support out-of-bound
> > values.  Now, this might mean using MIN/MAX value is even required
> > since the transform cannot assume 0/[-]1 here?
> > 
> > So maybe do
> > 
> > >    if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
> >          && TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
> > 
> > and thus rely on get_range_info for Ada?
> 
> I'm sure:
>   /* In Ada, we use an unsigned 8-bit type for the default boolean type.  */
>   boolean_type_node = make_unsigned_type (8);
>   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
>   SET_TYPE_RM_MAX_VALUE (boolean_type_node,
>                          build_int_cst (boolean_type_node, 1));
>                                                          ^^^ Here

But

/* For numerical types, this is the RM upper bound of the type.  There is
   again a discrepancy between this upper bound and the GCC upper bound,
   again because of the need to support invalid values.

   These values can be outside the range of values allowed by the RM upper
   bound but they must nevertheless be valid in the GCC type system, 
otherwise
   the optimizer can pretend that they simply don't exist.  Therefore they
   must be within the range of values allowed by the upper bound in the 
GCC
   sense, hence the GCC upper bound be set to that of the base type.

   This upper bound is translated directly without the adjustments that 
may
   be required for type compatibility, so it will generally be necessary 
to
   convert it to the base type of the numerical type before using it.  */
#define TYPE_RM_MAX_VALUE(NODE) TYPE_RM_VALUE ((NODE), 2)
#define SET_TYPE_RM_MAX_VALUE(NODE, X) SET_TYPE_RM_VALUE ((NODE), 2, (X))

and

#define SET_TYPE_RM_VALUE(NODE, N, X)              \
do {                                               \
  tree tmp = (X);                                  \
  if (!TYPE_RM_VALUES (NODE))                      \
    TYPE_RM_VALUES (NODE) = make_tree_vec (3);     \
  /* ??? The field is not visited by the generic   \
     code so we need to mark it manually.  */      \
  MARK_VISITED (tmp);                              \
  TREE_VEC_ELT (TYPE_RM_VALUES (NODE), (N)) = tmp; \
} while (0)


>   SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
>   boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
>   boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
> 
> The build_nonstandard_boolean_type that is not the case and
> TYPE_MAX_VALUE is -1 rather than 0, but I've checked all uses
> of that function and it always just creates an element type
> for VECTOR_TYPEs, so I think it shouldn't affect code that
> looks at BOOLEAN_TYPE non-VECTOR_TYPEs.
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to