Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)

2017-10-13 Thread Laurent Thevenoux
Hi Richard,

I will investigate it further, but thanks again for your review!

Laurent

- Mail original -
> De: "Richard Biener" 
> À: "Laurent Thevenoux" 
> Cc: "GCC Patches" 
> Envoyé: Lundi 9 Octobre 2017 15:57:38
> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)
> 
> On Mon, Oct 9, 2017 at 3:30 PM, Laurent Thevenoux
>  wrote:
> >
> >
> > - Mail original -
> >> De: "Richard Biener" 
> >> À: "Laurent Thevenoux" 
> >> Cc: "GCC Patches" 
> >> Envoyé: Lundi 9 Octobre 2017 14:04:49
> >> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug
> >> fix)
> >>
> >> On Fri, Oct 6, 2017 at 8:58 PM, Laurent Thevenoux
> >>  wrote:
> >> > Hi Richard, thanks for your quick reply.
> >> >
> >> > - Mail original -
> >> >> De: "Richard Biener" 
> >> >> À: "Laurent Thevenoux" 
> >> >> Cc: "GCC Patches" 
> >> >> Envoyé: Vendredi 6 Octobre 2017 13:42:57
> >> >> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug
> >> >> fix)
> >> >>
> >> >> On Thu, Oct 5, 2017 at 4:41 PM, Laurent Thevenoux
> >> >>  wrote:
> >> >> > Hello,
> >> >> >
> >> >> > This patch improves the some_nonzerop(tree t) function from
> >> >> > tree-complex.c
> >> >> > file (the function is only used there).
> >> >> >
> >> >> > This function returns true if a tree as a parameter is not the
> >> >> > constant
> >> >> > 0
> >> >> > (or +0.0 only for reals when !flag_signed_zeros ). The former result
> >> >> > is
> >> >> > then used to determine if some simplifications are possible for
> >> >> > complex
> >> >> > expansions (addition, multiplication, and division).
> >> >> >
> >> >> > Unfortunately, if the tree is a real constant, the function always
> >> >> > return
> >> >> > true, even for +0.0 because of the explicit test on flag_signed_zeros
> >> >> > (so
> >> >> > if your system enables signed zeros you cannot benefit from those
> >> >> > simplifications). To avoid this behavior and allow complex expansion
> >> >> > simplifications, I propose the following patch, which test for the
> >> >> > sign
> >> >> > of
> >> >> > the real constant 0.0 instead of checking the flag.
> >> >>
> >> >> But
> >> >>
> >> >> +  if (TREE_CODE (t) == REAL_CST)
> >> >> +{
> >> >> +  if (real_identical (&TREE_REAL_CST (t), &dconst0))
> >> >> +   zerop = !real_isneg (&TREE_REAL_CST (t));
> >> >> +}
> >> >>
> >> >> shouldn't you do
> >> >>
> >> >>zerop = !flag_signed_zeros || !real_isneg (&TREE_REAL_CST (t));
> >> >>
> >> >> ?
> >> >
> >> > I’m not so sure. If I understand your proposition (tables below gives
> >> > values of zerop following the values of t and flag_signed_zeros):
> >> >
> >> >|   zerop
> >> >  t | !flag_signed_zeros is false | !flag_signed_zeros is true
> >> > -
> >> > +n | true*   | true*
> >> > -n | false   | true*
> >> >  0 | true| true
> >> > -0 | false   | unreachable
> >> >
> >> > But here, results with a * don't return the good value. The existing
> >> > code
> >> > is also wrong, it always returns false if flag_signed_zeros is true,
> >> > else
> >> > the code is correct:
> >> >
> >> >|   zerop
> >> >  t | !flag_signed_zeros is false | !flag_signed_zeros is true
> >> > -
> >> > +n | false   | false
> >> > -n | false   | false
> >> >  0 | true| false*
> >> > -0 | false   

Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)

2017-10-09 Thread Laurent Thevenoux


- Mail original -
> De: "Richard Biener" 
> À: "Laurent Thevenoux" 
> Cc: "GCC Patches" 
> Envoyé: Lundi 9 Octobre 2017 14:04:49
> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)
> 
> On Fri, Oct 6, 2017 at 8:58 PM, Laurent Thevenoux
>  wrote:
> > Hi Richard, thanks for your quick reply.
> >
> > - Mail original -
> >> De: "Richard Biener" 
> >> À: "Laurent Thevenoux" 
> >> Cc: "GCC Patches" 
> >> Envoyé: Vendredi 6 Octobre 2017 13:42:57
> >> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug
> >> fix)
> >>
> >> On Thu, Oct 5, 2017 at 4:41 PM, Laurent Thevenoux
> >>  wrote:
> >> > Hello,
> >> >
> >> > This patch improves the some_nonzerop(tree t) function from
> >> > tree-complex.c
> >> > file (the function is only used there).
> >> >
> >> > This function returns true if a tree as a parameter is not the constant
> >> > 0
> >> > (or +0.0 only for reals when !flag_signed_zeros ). The former result is
> >> > then used to determine if some simplifications are possible for complex
> >> > expansions (addition, multiplication, and division).
> >> >
> >> > Unfortunately, if the tree is a real constant, the function always
> >> > return
> >> > true, even for +0.0 because of the explicit test on flag_signed_zeros
> >> > (so
> >> > if your system enables signed zeros you cannot benefit from those
> >> > simplifications). To avoid this behavior and allow complex expansion
> >> > simplifications, I propose the following patch, which test for the sign
> >> > of
> >> > the real constant 0.0 instead of checking the flag.
> >>
> >> But
> >>
> >> +  if (TREE_CODE (t) == REAL_CST)
> >> +{
> >> +  if (real_identical (&TREE_REAL_CST (t), &dconst0))
> >> +   zerop = !real_isneg (&TREE_REAL_CST (t));
> >> +}
> >>
> >> shouldn't you do
> >>
> >>zerop = !flag_signed_zeros || !real_isneg (&TREE_REAL_CST (t));
> >>
> >> ?
> >
> > I’m not so sure. If I understand your proposition (tables below gives
> > values of zerop following the values of t and flag_signed_zeros):
> >
> >|   zerop
> >  t | !flag_signed_zeros is false | !flag_signed_zeros is true
> > -
> > +n | true*   | true*
> > -n | false   | true*
> >  0 | true| true
> > -0 | false   | unreachable
> >
> > But here, results with a * don't return the good value. The existing code
> > is also wrong, it always returns false if flag_signed_zeros is true, else
> > the code is correct:
> >
> >|   zerop
> >  t | !flag_signed_zeros is false | !flag_signed_zeros is true
> > -
> > +n | false   | false
> > -n | false   | false
> >  0 | true| false*
> > -0 | false   | unreachable
> >
> > With the code I propose, we obtain the right results:
> >
> >  t | zerop
> > --
> > +n | false
> > -n | false
> >  0 | true
> > -0 | false
> >
> > Do I really miss something (I'm sorry if I'm wrong)?
> >
> >>
> >> Also doesn't this miscalculate A - B for {ar, 0.} - {br, 0.} given the
> >> simplification simply
> >> returns bi?
> >
> > Here we are in case PAIR (ONLY_REAL, ONLY_REAL), which gives ri = 0. (ai)
> > even with signed zeros. So everything is OK.
> >
> >>
> >> So I'm not convinced this handling is correct.
> >>
> >> > This first fix reveals a bug (thanks to
> >> > c-c++-common/torture/complex-sign-add.c ) in the simplification section
> >> > of
> >> > expand_complex_addition (also fixed in the patch).
> >>
> >> Your patch looks backward and the existing code looks ok.
> >>
> >> @@ -937,7 +940,7 @@ expand_complex_addition (gimple_stmt_iterator
> >> *gsi, tree inner_type,
> >>
> >>  case PAIR (VARYING, ONLY_REAL):
> >>rr = gimplify_build2 (gsi, code

Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)

2017-10-06 Thread Laurent Thevenoux
Hi Richard, thanks for your quick reply.

- Mail original -
> De: "Richard Biener" 
> À: "Laurent Thevenoux" 
> Cc: "GCC Patches" 
> Envoyé: Vendredi 6 Octobre 2017 13:42:57
> Objet: Re: tree-complex.c: fix some_nonzerop test over reals (and a bug fix)
> 
> On Thu, Oct 5, 2017 at 4:41 PM, Laurent Thevenoux
>  wrote:
> > Hello,
> >
> > This patch improves the some_nonzerop(tree t) function from tree-complex.c
> > file (the function is only used there).
> >
> > This function returns true if a tree as a parameter is not the constant 0
> > (or +0.0 only for reals when !flag_signed_zeros ). The former result is
> > then used to determine if some simplifications are possible for complex
> > expansions (addition, multiplication, and division).
> >
> > Unfortunately, if the tree is a real constant, the function always return
> > true, even for +0.0 because of the explicit test on flag_signed_zeros (so
> > if your system enables signed zeros you cannot benefit from those
> > simplifications). To avoid this behavior and allow complex expansion
> > simplifications, I propose the following patch, which test for the sign of
> > the real constant 0.0 instead of checking the flag.
> 
> But
> 
> +  if (TREE_CODE (t) == REAL_CST)
> +{
> +  if (real_identical (&TREE_REAL_CST (t), &dconst0))
> +   zerop = !real_isneg (&TREE_REAL_CST (t));
> +}
> 
> shouldn't you do
> 
>zerop = !flag_signed_zeros || !real_isneg (&TREE_REAL_CST (t));
> 
> ?

I’m not so sure. If I understand your proposition (tables below gives values of 
zerop following the values of t and flag_signed_zeros):

   |   zerop
 t | !flag_signed_zeros is false | !flag_signed_zeros is true 
-
+n | true*   | true* 
-n | false   | true* 
 0 | true| true 
-0 | false   | unreachable 

But here, results with a * don't return the good value. The existing code is 
also wrong, it always returns false if flag_signed_zeros is true, else the code 
is correct:

   |   zerop
 t | !flag_signed_zeros is false | !flag_signed_zeros is true 
-
+n | false   | false 
-n | false   | false 
 0 | true| false*
-0 | false   | unreachable 

With the code I propose, we obtain the right results: 

 t | zerop 
--
+n | false 
-n | false 
 0 | true 
-0 | false

Do I really miss something (I'm sorry if I'm wrong)?

> 
> Also doesn't this miscalculate A - B for {ar, 0.} - {br, 0.} given the
> simplification simply
> returns bi?

Here we are in case PAIR (ONLY_REAL, ONLY_REAL), which gives ri = 0. (ai) even 
with signed zeros. So everything is OK.

> 
> So I'm not convinced this handling is correct.
> 
> > This first fix reveals a bug (thanks to
> > c-c++-common/torture/complex-sign-add.c ) in the simplification section of
> > expand_complex_addition (also fixed in the patch).
> 
> Your patch looks backward and the existing code looks ok.
> 
> @@ -937,7 +940,7 @@ expand_complex_addition (gimple_stmt_iterator
> *gsi, tree inner_type,
> 
>  case PAIR (VARYING, ONLY_REAL):
>rr = gimplify_build2 (gsi, code, inner_type, ar, br);
> -  ri = ai;
> +  ri = bi;
>break;

With the existing code we don’t perform the simplification step at all since it 
always returns (VARYING, VARYING) when flag_signed_zeros is true. 

For instance, with {ar, -0.} + {br, 0.}, if simplification really occurs, its 
in case PAIR (VARIYNG, ONLY_REAL) (because we consider -0. as a non_zero), and 
it returns -0. if we return ai (instead of -0. + 0. -> 0.). But I understand 
now that returning bi in this case is meaningless since {br, bi} is a ONLY_REAL 
complex. 

Nevertheless, for instance, {ar, -0.} + {br, 0.} -> {ar + br, -0.} is still 
buggy.

A solution could be:

case PAIR (VARYING, ONLY_REAL):
  rr = gimplify_build2 (gsi, code, inner_type, ar, br);
+ if (TREE_CODE (ai) == REAL_CST
+  && code = PLUS_EXPR
+  && real_identical (&TREE_REAL_CST (ai), &dconst0)
+  && real_isneg (&TREE_REAL_CST (ai)))
+   ri = bi;
+ else 
ri = ai;
  break;

Laurent 

> 
> down we have
> 
> case PAIR (ONLY_REAL, VARYING):
>   if (code == MINUS_EXPR)
> goto general;
>   rr = gimplify_build2 (gsi, code, inner_type, ar, br);
>   ri = bi;
>   break;
> 
> which for sure would need to change as well then.  But for your
> changed code we know
> bi is zero (but ai may not).
> 
> Richard.
> 
> > The patch has passed bootstrap and testing on x86_64-pc-linux-gnu .
> >
> > Best regards,
> > Laurent Thévenoux
>


tree-complex.c: fix some_nonzerop test over reals (and a bug fix)

2017-10-05 Thread Laurent Thevenoux
Hello, 

This patch improves the some_nonzerop(tree t) function from tree-complex.c file 
(the function is only used there). 

This function returns true if a tree as a parameter is not the constant 0 (or 
+0.0 only for reals when !flag_signed_zeros ). The former result is then used 
to determine if some simplifications are possible for complex expansions 
(addition, multiplication, and division). 

Unfortunately, if the tree is a real constant, the function always return true, 
even for +0.0 because of the explicit test on flag_signed_zeros (so if your 
system enables signed zeros you cannot benefit from those simplifications). To 
avoid this behavior and allow complex expansion simplifications, I propose the 
following patch, which test for the sign of the real constant 0.0 instead of 
checking the flag. 

This first fix reveals a bug (thanks to c-c++-common/torture/complex-sign-add.c 
) in the simplification section of expand_complex_addition (also fixed in the 
patch). 

The patch has passed bootstrap and testing on x86_64-pc-linux-gnu . 

Best regards, 
Laurent Thévenoux 
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2191d62..a6124ce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2017-10-05  Laurent Thévenoux  
+
+	* tree-complex.c (some_nonzerop): Adjust the way of testing real
+	constants. Allows existing simplifications of complex expansions
+	to be well done.
+	* tree-complex.c (expand_complex_addition): Bug fixing for complex
+	addition expansion simplification.
+
 2017-10-02  Bill Schmidt  
 
 	Backport from mainline
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index e0dd3d9..413b601 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -110,8 +110,11 @@ some_nonzerop (tree t)
   /* Operations with real or imaginary part of a complex number zero
  cannot be treated the same as operations with a real or imaginary
  operand if we care about the signs of zeros in the result.  */
-  if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
-zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
+  if (TREE_CODE (t) == REAL_CST)
+{
+  if (real_identical (&TREE_REAL_CST (t), &dconst0))
+	zerop = !real_isneg (&TREE_REAL_CST (t));
+}
   else if (TREE_CODE (t) == FIXED_CST)
 zerop = fixed_zerop (t);
   else if (TREE_CODE (t) == INTEGER_CST)
@@ -937,7 +940,7 @@ expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
 
 case PAIR (VARYING, ONLY_REAL):
   rr = gimplify_build2 (gsi, code, inner_type, ar, br);
-  ri = ai;
+  ri = bi;
   break;
 
 case PAIR (VARYING, ONLY_IMAG):