This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix reassoc with -frounding-math or IBM long double (PR tree-optimization/84841)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 16 Mar 2018 08:56:16 +0100 (CET)
- Subject: Re: [PATCH] Fix reassoc with -frounding-math or IBM long double (PR tree-optimization/84841)
- References: <20180315193236.GX8577@tucnak>
On Thu, 15 Mar 2018, Jakub Jelinek wrote:
> Hi!
>
> If any argument of * is negated, reassoc adds an artificial -1.0 multiplier.
> The code then relies on folding at least all those artificial multipliers
> through const_binop. That function can fail if the result is inexact for
> -frounding-math or for composite modes, and we only try to recursively fold
> the last constant with previous one.
>
> The following patch fixes it by sorting the constants that never cause
> inexact results (-1.0 and 1.0) last, so we fold at least all those together
> and at least with one other constant. As I said in the PR, we could also
> try up to O(n^2) attempts folding each constant with each other if there
> were any failures in the folding, perhaps bound by some constant.
>
> The comment above constant_type says we want to sort the integral constants
> last, but we actually among all constants sort them first, so the patch
> fixes that too. As constant_type returns something (at least before this
> patch) only based on type, I fail to see when constants in the same ops
> vector could have different kinds.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok.
Richard.
> 2018-03-15 Jakub Jelinek <jakub@redhat.com>
>
> PR tree-optimization/84841
> * tree-ssa-reassoc.c (INTEGER_CONST_TYPE): Change to 1 << 4 from
> 1 << 3.
> (FLOAT_ONE_CONST_TYPE): Define.
> (constant_type): Return FLOAT_ONE_CONST_TYPE for -1.0 and 1.0.
> (sort_by_operand_rank): Put entries with higher constant_type last
> rather than first to match comments.
>
> * gcc.dg/pr84841.c: New test.
>
> --- gcc/tree-ssa-reassoc.c.jj 2018-01-03 10:19:53.804533730 +0100
> +++ gcc/tree-ssa-reassoc.c 2018-03-15 17:46:08.871748372 +0100
> @@ -470,7 +470,8 @@ get_rank (tree e)
>
> /* We want integer ones to end up last no matter what, since they are
> the ones we can do the most with. */
> -#define INTEGER_CONST_TYPE 1 << 3
> +#define INTEGER_CONST_TYPE 1 << 4
> +#define FLOAT_ONE_CONST_TYPE 1 << 3
> #define FLOAT_CONST_TYPE 1 << 2
> #define OTHER_CONST_TYPE 1 << 1
>
> @@ -482,7 +483,14 @@ constant_type (tree t)
> if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
> return INTEGER_CONST_TYPE;
> else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (t)))
> - return FLOAT_CONST_TYPE;
> + {
> + /* Sort -1.0 and 1.0 constants last, while in some cases
> + const_binop can't optimize some inexact operations, multiplication
> + by -1.0 or 1.0 can be always merged with others. */
> + if (real_onep (t) || real_minus_onep (t))
> + return FLOAT_ONE_CONST_TYPE;
> + return FLOAT_CONST_TYPE;
> + }
> else
> return OTHER_CONST_TYPE;
> }
> @@ -504,7 +512,7 @@ sort_by_operand_rank (const void *pa, co
> if (oea->rank == 0)
> {
> if (constant_type (oeb->op) != constant_type (oea->op))
> - return constant_type (oeb->op) - constant_type (oea->op);
> + return constant_type (oea->op) - constant_type (oeb->op);
> else
> /* To make sorting result stable, we use unique IDs to determine
> order. */
> --- gcc/testsuite/gcc.dg/pr84841.c.jj 2018-03-15 17:46:40.142765079 +0100
> +++ gcc/testsuite/gcc.dg/pr84841.c 2018-03-15 17:25:05.032150810 +0100
> @@ -0,0 +1,9 @@
> +/* PR tree-optimization/84841 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fassociative-math -frounding-math -fno-signed-zeros -fno-trapping-math -fno-tree-forwprop" } */
> +
> +double
> +foo (double x)
> +{
> + return -x * 0.1 * 0.1;
> +}
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)