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