This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix endless loop in folding narrowing convert of MULT_EXPR (PR middle-end/38422)
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Jakub Jelinek" <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 6 Dec 2008 12:03:16 +0100
- Subject: Re: [PATCH] Fix endless loop in folding narrowing convert of MULT_EXPR (PR middle-end/38422)
- References: <20081206095538.GC17496@tyan-ft48-01.lab.bos.redhat.com>
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
>