On Tue, Jan 13, 2026 at 12:52 AM Richard Biener <[email protected]> wrote: > > On Mon, Jan 12, 2026 at 11:16 PM Andrew Pinski > <[email protected]> wrote: > > > > On Mon, Jan 12, 2026 at 12:33 AM Richard Biener > > <[email protected]> wrote: > > > > > > On Sun, Jan 11, 2026 at 10:05 PM Andrew Pinski > > > <[email protected]> wrote: > > > > > > > > This adds the simpliciation of: > > > > ``` > > > > <unnamed-signed:3> _1; > > > > > > > > _2 = (signed char) _1; > > > > _3 = _2 ^ -47; > > > > _4 = (<unnamed-signed:3>) _3; > > > > ``` > > > > > > > > to: > > > > ``` > > > > <unnamed-signed:3> _n; > > > > _4 = _1 ^ -47; > > > > ``` > > > > > > > > This also fixes PR 122843 by optimizing out the xor such that we get: > > > > ``` > > > > _1 = b.a; > > > > _21 = (<unnamed-signed:3>) t_23(D); > > > > // t_23 in the original testcase was 200 so this is reduced to 0 > > > > _5 = _1 ^ _21; > > > > # .MEM_24 = VDEF <.MEM_13> > > > > b.a = _5; > > > > ``` > > > > And then there is no cast catch this pattern: > > > > `(bit_xor (convert1? (bit_xor:c @0 @1)) (convert2? (bit_xor:c @0 @2)))` > > > > As we get: > > > > ``` > > > > _21 = (<unnamed-signed:3>) t_23(D); > > > > _5 = _1 ^ _21; > > > > _22 = (<unnamed-signed:3>) t_23(D); > > > > _7 = _5 ^ _22; > > > > _25 = (<unnamed-signed:3>) t_23(D); > > > > _8 = _7 ^ _25; > > > > _26 = (<unnamed-signed:3>) t_23(D); > > > > _9 = _7 ^ _26; > > > > ``` > > > > After unrolling and then fre will optimize away all of those xor. > > > > > > > > Bootstrapped and tested on x86_64-linux-gnu. > > > > > > > > PR tree-optimization/122845 > > > > PR tree-optimization/122843 > > > > gcc/ChangeLog: > > > > > > > > * match.pd (`(T1)(a bit_op (T2)b)`): Also > > > > simplify if T1 is the same type as b and T2 is wider > > > > type than T1. > > > > > > > > gcc/testsuite/ChangeLog: > > > > > > > > * gcc.dg/tree-ssa/bitops-12.c: New test. > > > > * gcc.dg/tree-ssa/bitops-13.c: New test. > > > > * gcc.dg/store_merging_18.c: xfail store merging. > > > > > > > > Signed-off-by: Andrew Pinski <[email protected]> > > > > --- > > > > gcc/match.pd | 10 +++++++++- > > > > gcc/testsuite/gcc.dg/store_merging_18.c | 3 ++- > > > > gcc/testsuite/gcc.dg/tree-ssa/bitops-12.c | 18 ++++++++++++++++++ > > > > gcc/testsuite/gcc.dg/tree-ssa/bitops-13.c | 18 ++++++++++++++++++ > > > > 4 files changed, 47 insertions(+), 2 deletions(-) > > > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-12.c > > > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-13.c > > > > > > > > diff --git a/gcc/match.pd b/gcc/match.pd > > > > index 492d88514fc..16ce2d1edd2 100644 > > > > --- a/gcc/match.pd > > > > +++ b/gcc/match.pd > > > > @@ -2323,7 +2323,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > > > && !POINTER_TYPE_P (TREE_TYPE (@0)) > > > > && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE > > > > && TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)) > > > > - (bitop:type (convert @0) (convert @1))))) > > > > + (bitop:type (convert @0) (convert @1)) > > > > + /* Similar as above, but the outer and inner most types match > > > > + and it was widening cast; replacing 2 casts with only one. */ > > > > + (if (GIMPLE > > > > + && INTEGRAL_TYPE_P (type) > > > > + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) > > > > + && types_match (type, TREE_TYPE (@0)) > > > > + && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (type)) > > > > > > I think you need the pointer and offset type checks here as well given > > > bitops are not valid on those in general. > > > > The `INTEGRAL_TYPE_P (type)` check will already reject pointer and > > offset types. And the type on @2 will already be an integer type > > because it is on the bitop. > > So there is no need to add the extra checks. > > Hmm, indeed. Can you remove the redundant hecks on the previous case then: > > (if (GIMPLE > && INTEGRAL_TYPE_P (type) > && INTEGRAL_TYPE_P (TREE_TYPE (@0)) > && TREE_CODE (@1) != INTEGER_CST > && tree_nop_conversion_p (type, TREE_TYPE (@2)) > && !POINTER_TYPE_P (TREE_TYPE (@0)) > && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE > ?
Done with the attached patch which I pushed too.
Thanks,
Andrew
>
> > >
> > > OK with adding those.
> >
> > I pushed it without the extra checks added.
> >
> > Thanks,
> > Andrew Pinski
> >
> >
> >
> > > Richard.
> > >
> > > > + (bitop:type @0 (convert @1))))))
> > > >
> > > > (for bitop (bit_and bit_ior)
> > > > rbitop (bit_ior bit_and)
> > > > diff --git a/gcc/testsuite/gcc.dg/store_merging_18.c
> > > > b/gcc/testsuite/gcc.dg/store_merging_18.c
> > > > index fdff6b4d812..546c17dc7c4 100644
> > > > --- a/gcc/testsuite/gcc.dg/store_merging_18.c
> > > > +++ b/gcc/testsuite/gcc.dg/store_merging_18.c
> > > > @@ -1,7 +1,8 @@
> > > > /* PR tree-optimization/83843 */
> > > > /* { dg-do run } */
> > > > /* { dg-options "-O2 -fno-tree-vectorize -fdump-tree-store-merging" }
> > > > */
> > > > -/* { dg-final { scan-tree-dump-times "Merging successful" 3
> > > > "store-merging" { target { store_merge && { ! arm*-*-* } } } } } */
> > > > +/* xfailed after PR 122845, see PR 123541 ( */
> > > > +/* { dg-final { scan-tree-dump-times "Merging successful" 3
> > > > "store-merging" { target { store_merge && { ! arm*-*-* } } xfail *-*-*
> > > > } } } */
> > > >
> > > > __attribute__((noipa)) void
> > > > foo (unsigned char *buf, unsigned char *tab)
> > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-12.c
> > > > b/gcc/testsuite/gcc.dg/tree-ssa/bitops-12.c
> > > > new file mode 100644
> > > > index 00000000000..50d8dc2180f
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-12.c
> > > > @@ -0,0 +1,18 @@
> > > > +/* { dg-do compile } */
> > > > +/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
> > > > +/* PR tree-optimization/122845 */
> > > > +
> > > > +struct s1
> > > > +{
> > > > + signed f1:3;
> > > > +};
> > > > +struct s1 p;
> > > > +void f(void)
> > > > +{
> > > > + p.f1 ^= -47;
> > > > + p.f1 ^= -47;
> > > > +}
> > > > +
> > > > +/* There should be no gimple stmts left except for return.
> > > > + That is the ^ has been optimized away. */
> > > > +/* { dg-final { scan-tree-dump-not "gimple_assign <" "optimized" } }
> > > > */
> > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-13.c
> > > > b/gcc/testsuite/gcc.dg/tree-ssa/bitops-13.c
> > > > new file mode 100644
> > > > index 00000000000..ecf69738267
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-13.c
> > > > @@ -0,0 +1,18 @@
> > > > +/* { dg-do compile } */
> > > > +/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
> > > > +/* PR tree-optimization/122845 */
> > > > +
> > > > +int f(signed char a, int b)
> > > > +{
> > > > + int aa = a;
> > > > + int bb = b;
> > > > + aa &= bb;
> > > > + signed char t = aa;
> > > > + aa = t;
> > > > + aa &= bb;
> > > > + t = aa;
> > > > + return t;
> > > > +}
> > > > +
> > > > +/* There should be only 1 bit_and_expr left as both ands are the same.
> > > > */
> > > > +/* { dg-final { scan-tree-dump-times "bit_and_expr, " 1 "optimized" }
> > > > } */
> > > > --
> > > > 2.43.0
> > > >
0001-match-Remove-redundant-type-checks-from-T1-a-bit_op-.patch
Description: Binary data
