This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix build_range_check on 1 .. signed_max ranges (PR middle-end/37882)


On Wed, Oct 22, 2008 at 12:29 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> signed_type_for may return a type with bigger precision than the precision
> of the passed type, e.g. type_for_size langhook's comment says:
>  /* Given PRECISION and UNSIGNEDP, return a suitable type-tree for an
>     integer type with at least that precision.  */
> In the
> /* Optimize (c>=1) && (c<=127) into (signed char)c > 0.  */
> optimization, precision at least as wide as c's isn't good enough,
> we need exactly the same precision.
> The following patch fixes it.  We could call build_nonstandard_integer_type
> unconditionally, but that would in the common case where precision is sane
> unnecessarily create a new type and as fold is used also in the FEs, I think
> it is better to use the standard types if possible.
>
> Ok for trunk/4.3 if bootstrap/regtest passes?

Ok.  In future (4.5) we may want to "optimize" {un,}signed_type_for to always
return an integer type of the requested precision and keep a cache on its own
(after all we don't want a langhook here for LTO reasons).

Thanks,
Richard.

> 2008-10-22  Jakub Jelinek  <jakub@redhat.com>
>
>        PR middle-end/37882
>        * fold-const.c (build_range_type): For 1 .. signed_max
>        range call build_nonstandard_inter_type if signed_type_for
>        returned a type with bigger precision.
>
>        * gcc.c-torture/execute/pr37882.c: New test.
>
> --- gcc/fold-const.c.jj 2008-10-20 12:36:10.000000000 +0200
> +++ gcc/fold-const.c    2008-10-22 12:11:13.000000000 +0200
> @@ -4503,7 +4503,12 @@ build_range_check (tree type, tree exp,
>        {
>          if (TYPE_UNSIGNED (etype))
>            {
> -             etype = signed_type_for (etype);
> +             tree signed_etype = signed_type_for (etype);
> +             if (TYPE_PRECISION (signed_etype) != TYPE_PRECISION (etype))
> +               etype
> +                 = build_nonstandard_integer_type (TYPE_PRECISION (etype), 0);
> +             else
> +               etype = signed_etype;
>              exp = fold_convert (etype, exp);
>            }
>          return fold_build2 (GT_EXPR, type, exp,
> --- gcc/testsuite/gcc.c-torture/execute/pr37882.c.jj    2008-10-22 12:14:42.000000000 +0200
> +++ gcc/testsuite/gcc.c-torture/execute/pr37882.c       2008-10-22 12:14:25.000000000 +0200
> @@ -0,0 +1,16 @@
> +/* PR middle-end/37882 */
> +
> +struct S
> +{
> +  int a : 21;
> +  unsigned char b : 3;
> +} s;
> +
> +int
> +main ()
> +{
> +  s.b = 4;
> +  if (s.b > 0 && s.b < 4)
> +    __builtin_abort ();
> +  return 0;
> +}
>
>        Jakub
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]