public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fixup fortran type_for_size langhook
@ 2011-09-23 16:27 Jakub Jelinek
  2011-09-27 19:21 ` Paul Richard Thomas
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2011-09-23 16:27 UTC (permalink / raw)
  To: gcc-patches, fortran

Hi!

I've noticed with the
2009-05-29  Eric Botcazou  <ebotcazou@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  <jakub@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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fixup fortran type_for_size langhook
  2011-09-23 16:27 [PATCH] Fixup fortran type_for_size langhook Jakub Jelinek
@ 2011-09-27 19:21 ` Paul Richard Thomas
  0 siblings, 0 replies; 2+ messages in thread
From: Paul Richard Thomas @ 2011-09-27 19:21 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran

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 <jakub@redhat.com> wrote:
> Hi!
>
> I've noticed with the
> 2009-05-29  Eric Botcazou  <ebotcazou@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  <jakub@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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-09-27 18:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-23 16:27 [PATCH] Fixup fortran type_for_size langhook Jakub Jelinek
2011-09-27 19:21 ` Paul Richard Thomas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).