On Sun, May 10, 2026 at 10:58 AM Shivam Gupta <[email protected]> wrote:
>
> This adds the simplification of:
> _1 = ~x_4(D);
> _2 = _1 & y_5(D);
> _3 = x_4(D) | y_5(D);
> _6 = _2 ^ _3;
> return _6;
>
> to:
> return x_1(D);
>
> also for ((~x) | y) ^ (x & y) version
> _1 = ~x_4(D);
> _2 = _1 | y_5(D);
> _3 = x_4(D) & y_5(D);
> _6 = _2 ^ _3;
> return _6;
>
> to:
> int _2;
> _2 = ~x_1(D);
> return _2;
>
> Bootstrapped and tested on aarch64-linux-gnu with
> RUNTESTFLAGS="tree-ssa.exp".
>
> PR tree-optimization/112095
>
> gcc/ChangeLog:
>
> * match.pd: Simplify ((~x) & y) ^ (x | y)
> to x and ((~x) | y) ^ (x & y) to ~x.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/pr112095.c: New test.
>
> Signed-off-by: Shivam Gupta <[email protected]>
> ---
> gcc/match.pd | 9 +++++++++
> gcc/testsuite/gcc.dg/tree-ssa/pr112095.c | 19 +++++++++++++++++++
> 2 files changed, 28 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7b652afb43d..08df727ea9d 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2627,6 +2627,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (negate (nop_convert? (bit_not @0)))
> (plus (view_convert @0) { build_each_one_cst (type); }))
>
> +/* ((~a) & b) ^ (a | b) -> a */
> +/* ((~a) | b) ^ (a & b) -> ~a */
> +(simplify
> + (bit_xor:c (bit_ior:c @0 @1) (bit_and:c @2 @1))
> + (with { bool wascmp; }
> + (if (bitwise_inverted_equal_p (@0, @2, wascmp)
> + && (!wascmp || element_precision (type) == 1))
> + @0)))
> +
I think this belongs to the section of patterns
around line 1600, the pattern(s) below should
probably be moved as well.
> /* (a & b) ^ (a == b) -> !(a | b) */
> /* (a & b) == (a ^ b) -> !(a | b) */
> (for first_op (bit_xor eq)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
> new file mode 100644
> index 00000000000..126705d7731
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-optimized" } */
> +
> +int
> +f (int a, int b)
> +{
> + return ((~a) & b) ^ (a | b);
> +}
> +
> +int
> +g (int a, int b)
> +{
> + return ((~a) | b) ^ (a & b);
> +}
> +
> +/* Above patterns should simplify to a and ~a respectively. */
> +/* { dg-final { scan-tree-dump "return a_" "optimized" } } */
> +/* { dg-final { scan-tree-dump "~a_" "optimized" } } */
> +
> --
> 2.34.1
>