Dear Jakub,

This is, of course, OK for trunk.  In fact, I would say that it verges
on obvious.

Thanks for taking care of it.

Paul

On Fri, Sep 23, 2011 at 4:44 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> I've noticed with the
> 2009-05-29  Eric Botcazou  <ebotca...@adacore.com>
>
>        * tree-ssa-loop-ivopts.c (strip_offset_1) <MULT_EXPR>: New case.
>        (force_expr_to_var_cost) <NEGATE_EXPR>: Likewise.
>        (ptr_difference_cost): Use affine combinations to compute it.
>        (difference_cost): Likewise.
>        (get_computation_cost_at): Compute more accurate cost for addresses
>        if the ratio is a multiplier allowed in addresses.
>        For non-addresses, consider that an additional offset or symbol is
>        added only once.
> patch backported to 4.4-RH branch an ICE on PowerPC, where difference_cost
> calls signed_type_for, which for a BOOLEAN_TYPE returns NULL, but
> difference_cost isn't prepared for it.  Can't reproduce it on 4.6 nor trunk,
> but most probably just because some other optimizations made the problem
> latent.  Looking at signed_type_for and the type_for_size langhook it uses
> (yeah, I know, it isn't very much desirable to use langhooks in the
> middle-end), the langhook is documented to return a signed resp. unsigned
> type that can hold AT LEAST the requested bits and most frontends implement
> it that way, with the exception of Fortran and Go.  And it seems lots of
> places all around the middle-end assume that for not excessively large types
> signed_type_for/unsigned_type_for will always succeed.
> This patch fixes up the Fortran FE, so that even if there is no exact match
> with a TYPE_PRECISION, if there is a wider type, the smallest of them will
> be used.  The type_for_mode langhook on the other side must return a type
> with the requested mode exactly, so if it uses gfc_type_for_size which now
> can return wider type, it needs to check whether the returned type's
> TYPE_MODE is the requested one.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2011-09-23  Jakub Jelinek  <ja...@redhat.com>
>
>        * trans-types.c (gfc_type_for_size): Return wider type
>        if no suitable narrower type has been found.
>        (gfc_type_for_mode): Return NULL_TREE if gfc_type_for_size
>        returned type doesn't have expected TYPE_MODE.
>
> --- gcc/fortran/trans-types.c.jj        2011-09-05 12:28:53.000000000 +0200
> +++ gcc/fortran/trans-types.c   2011-09-23 11:34:44.000000000 +0200
> @@ -2791,18 +2791,29 @@ gfc_type_for_size (unsigned bits, int un
>       if (bits == TYPE_PRECISION (intTI_type_node))
>        return intTI_type_node;
>  #endif
> +
> +      if (bits <= TYPE_PRECISION (intQI_type_node))
> +       return intQI_type_node;
> +      if (bits <= TYPE_PRECISION (intHI_type_node))
> +       return intHI_type_node;
> +      if (bits <= TYPE_PRECISION (intSI_type_node))
> +       return intSI_type_node;
> +      if (bits <= TYPE_PRECISION (intDI_type_node))
> +       return intDI_type_node;
> +      if (bits <= TYPE_PRECISION (intTI_type_node))
> +       return intTI_type_node;
>     }
>   else
>     {
> -      if (bits == TYPE_PRECISION (unsigned_intQI_type_node))
> +      if (bits <= TYPE_PRECISION (unsigned_intQI_type_node))
>         return unsigned_intQI_type_node;
> -      if (bits == TYPE_PRECISION (unsigned_intHI_type_node))
> +      if (bits <= TYPE_PRECISION (unsigned_intHI_type_node))
>        return unsigned_intHI_type_node;
> -      if (bits == TYPE_PRECISION (unsigned_intSI_type_node))
> +      if (bits <= TYPE_PRECISION (unsigned_intSI_type_node))
>        return unsigned_intSI_type_node;
> -      if (bits == TYPE_PRECISION (unsigned_intDI_type_node))
> +      if (bits <= TYPE_PRECISION (unsigned_intDI_type_node))
>        return unsigned_intDI_type_node;
> -      if (bits == TYPE_PRECISION (unsigned_intTI_type_node))
> +      if (bits <= TYPE_PRECISION (unsigned_intTI_type_node))
>        return unsigned_intTI_type_node;
>     }
>
> @@ -2823,7 +2834,10 @@ gfc_type_for_mode (enum machine_mode mod
>   else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
>     base = gfc_complex_types;
>   else if (SCALAR_INT_MODE_P (mode))
> -    return gfc_type_for_size (GET_MODE_PRECISION (mode), unsignedp);
> +    {
> +      tree type = gfc_type_for_size (GET_MODE_PRECISION (mode), unsignedp);
> +      return type != NULL_TREE && mode == TYPE_MODE (type) ? type : 
> NULL_TREE;
> +    }
>   else if (VECTOR_MODE_P (mode))
>     {
>       enum machine_mode inner_mode = GET_MODE_INNER (mode);
>
>        Jakub
>



-- 
The knack of flying is learning how to throw yourself at the ground and miss.
       --Hitchhikers Guide to the Galaxy

Reply via email to