Re: [PATCH] Small ccp optimization for x * x (PR tree-optimization/93156)

2020-01-07 Thread Richard Biener
On Tue, 7 Jan 2020, Jakub Jelinek wrote:

> Hi!
> 
> In x * x = ((x & -2) + (x & 1))^2 = ((x^2) & -4) + 2 * (x & -2) * (x & 1) + 
> (x & 1)^2
> the first two terms are divisible by 4 and the last one is 0 or 1, so
> (x * x) % 4U <= 1
> and thus bit ccp can assume he second least significant bit of any power of 
> two is
> 0.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2020-01-07  Jakub Jelinek  
> 
>   PR tree-optimization/93156
>   * tree-ssa-ccp.c (bit_value_binop): For x * x note that the second
>   least significant bit is always clear.
> 
>   * gcc.dg/tree-ssa/pr93156.c: New test.
> 
> --- gcc/tree-ssa-ccp.c.jj 2020-01-01 12:15:48.026609558 +0100
> +++ gcc/tree-ssa-ccp.c2020-01-06 15:39:16.807109578 +0100
> @@ -1650,6 +1650,17 @@ bit_value_binop (enum tree_code code, tr
>  TYPE_SIGN (TREE_TYPE (rhs2)), TYPE_PRECISION (TREE_TYPE 
> (rhs2)),
>  value_to_wide_int (r2val), r2val.mask);
>  
> +  /* (x * x) & 2 == 0.  */
> +  if (code == MULT_EXPR && rhs1 == rhs2 && TYPE_PRECISION (type) > 1)
> +{
> +  widest_int m = 2;
> +  if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
> + value = wi::bit_and_not (value, m);
> +  else
> + value = 0;
> +  mask = wi::bit_and_not (mask, m);
> +}
> +
>if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
>  {
>val.lattice_val = CONSTANT;
> --- gcc/testsuite/gcc.dg/tree-ssa/pr93156.c.jj2020-01-06 
> 15:26:57.750286597 +0100
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr93156.c   2020-01-06 15:40:32.987957791 
> +0100
> @@ -0,0 +1,23 @@
> +/* PR tree-optimization/93156 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "return 0;" 3 "optimized" } } */
> +
> +int
> +foo (int x)
> +{
> +  return (x * x) & 2;
> +}
> +
> +unsigned long long
> +bar (unsigned long long x)
> +{
> +  return (x * x) & 2;
> +}
> +
> +int
> +baz (int x)
> +{
> +  x &= -2;
> +  return (x * x) & 3;
> +}
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

[PATCH] Small ccp optimization for x * x (PR tree-optimization/93156)

2020-01-06 Thread Jakub Jelinek
Hi!

In x * x = ((x & -2) + (x & 1))^2 = ((x^2) & -4) + 2 * (x & -2) * (x & 1) + (x 
& 1)^2
the first two terms are divisible by 4 and the last one is 0 or 1, so
(x * x) % 4U <= 1
and thus bit ccp can assume he second least significant bit of any power of two 
is
0.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-01-07  Jakub Jelinek  

PR tree-optimization/93156
* tree-ssa-ccp.c (bit_value_binop): For x * x note that the second
least significant bit is always clear.

* gcc.dg/tree-ssa/pr93156.c: New test.

--- gcc/tree-ssa-ccp.c.jj   2020-01-01 12:15:48.026609558 +0100
+++ gcc/tree-ssa-ccp.c  2020-01-06 15:39:16.807109578 +0100
@@ -1650,6 +1650,17 @@ bit_value_binop (enum tree_code code, tr
   TYPE_SIGN (TREE_TYPE (rhs2)), TYPE_PRECISION (TREE_TYPE 
(rhs2)),
   value_to_wide_int (r2val), r2val.mask);
 
+  /* (x * x) & 2 == 0.  */
+  if (code == MULT_EXPR && rhs1 == rhs2 && TYPE_PRECISION (type) > 1)
+{
+  widest_int m = 2;
+  if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
+   value = wi::bit_and_not (value, m);
+  else
+   value = 0;
+  mask = wi::bit_and_not (mask, m);
+}
+
   if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
 {
   val.lattice_val = CONSTANT;
--- gcc/testsuite/gcc.dg/tree-ssa/pr93156.c.jj  2020-01-06 15:26:57.750286597 
+0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr93156.c 2020-01-06 15:40:32.987957791 
+0100
@@ -0,0 +1,23 @@
+/* PR tree-optimization/93156 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return 0;" 3 "optimized" } } */
+
+int
+foo (int x)
+{
+  return (x * x) & 2;
+}
+
+unsigned long long
+bar (unsigned long long x)
+{
+  return (x * x) & 2;
+}
+
+int
+baz (int x)
+{
+  x &= -2;
+  return (x * x) & 3;
+}

Jakub