https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87009
--- Comment #1 from MCCCS <mcccs at gmx dot com> --- Proposed patch: Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 263646) +++ gcc/match.pd (working copy) @@ -776,6 +776,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_not (bit_and:cs (bit_not @0) @1)) (bit_ior @0 (bit_not @1))) +/* ~(~a | b) --> a & ~b */ +(simplify + (bit_not (bit_ior:cs (bit_not @0) @1)) + (bit_and @0 (bit_not @1))) + /* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */ #if GIMPLE (simplify Index: gcc/testsuite/g++.dg/pr87009.C =================================================================== --- gcc/testsuite/g++.dg/pr87009.C (nonexistent) +++ gcc/testsuite/g++.dg/pr87009.C (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ +/* { dg-final { scan-tree-dump-times " ^ " 3 "original" } */ + +int f1 (int x, int s) +{ + return ~(~(x|s)|x)|~(~(x|s)|s); +} + +int f2 (int x, int s) +{ + return ~(~(~x&s)&~(x&~s)); +} + +int f3 (int x, int s) +{ + return ~((x|~s)&(~x|s)); +}