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 endless loop in folding narrowing convert of MULT_EXPR (PR middle-end/38422)


On Sat, Dec 6, 2008 at 10:55 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As has been said many times, unsigned_type_for can return a type with
> wider TYPE_PRECISION than the one passed in.  In the
> (T) (x * y) -> (T)x * (T)y optimization if the TYPE_PRECISION is
> not narrower than the multiplication's precision, then the optimization
> is worthless and, what's worse, results in endless recursion, as the type
> is the same.  I think using unsigned_type_for here is right, performing
> the multiplication in a type with nonstandard precision doesn't buy
> us anything, but we need to add a check to avoid this recursion.
>
> Ok for trunk if bootstrap/regtest passes?

Ok.

Thanks,
Richard.

> 2008-12-06  Jakub Jelinek  <jakub@redhat.com>
>
>        PR middle-end/38422
>        * fold-const.c (fold_unary) <CASE_CONVERT>: Don't convert MULT_EXPR
>        operands to mult_type if it isn't narrower than op0's type.
>
>        * gcc.c-torture/execute/pr38422.c: New test.
>
> --- gcc/fold-const.c.jj 2008-12-06 09:09:50.000000000 +0100
> +++ gcc/fold-const.c    2008-12-06 10:07:20.000000000 +0100
> @@ -8351,11 +8351,16 @@ fold_unary (enum tree_code code, tree ty
>            mult_type = type;
>          else
>            mult_type = unsigned_type_for (type);
> -
> -         tem = fold_build2 (MULT_EXPR, mult_type,
> -                            fold_convert (mult_type, TREE_OPERAND (op0, 0)),
> -                            fold_convert (mult_type, TREE_OPERAND (op0, 1)));
> -         return fold_convert (type, tem);
> +
> +         if (TYPE_PRECISION (mult_type) < TYPE_PRECISION (TREE_TYPE (op0)))
> +           {
> +             tem = fold_build2 (MULT_EXPR, mult_type,
> +                                fold_convert (mult_type,
> +                                              TREE_OPERAND (op0, 0)),
> +                                fold_convert (mult_type,
> +                                              TREE_OPERAND (op0, 1)));
> +             return fold_convert (type, tem);
> +           }
>        }
>
>       tem = fold_convert_const (code, type, op0);
> --- gcc/testsuite/gcc.c-torture/execute/pr38422.c.jj    2008-12-06 10:28:52.000000000 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr38422.c       2008-12-06 10:28:12.000000000 +0100
> @@ -0,0 +1,24 @@
> +/* PR middle-end/38422 */
> +
> +extern void abort (void);
> +
> +struct S
> +{
> +  int s : (sizeof (int) * __CHAR_BIT__ - 2);
> +} s;
> +
> +void
> +foo (void)
> +{
> +  s.s *= 2;
> +}
> +
> +int
> +main ()
> +{
> +  s.s = 24;
> +  foo ();
> +  if (s.s != 48)
> +    abort ();
> +  return 0;
> +}
>
>        Jakub
>


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