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 <ja...@redhat.com> 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