On Sat, May 25, 2024 at 11:42 AM Jeff Law <j...@ventanamicro.com> wrote: > > This is a revamp of what started as a target specific patch. > > Basically xalan (corrected, I originally thought it was perlbench) has a > bitset implementation with a bit of an oddity. Specifically setBit will > clear the bit before it is set: > > > if (bitToSet < 32) > > { > > fBits1 &= ~mask; > > fBits1 |= mask; > > } > > else > > { > > fBits2 &= ~mask; > > fBits2 |= mask; > > } > > We can clean this up pretty easily in RTL with a small bit of code in > simplify-rtx. While xalan doesn't have other cases, we can synthesize > tests pretty easily and handle them as well. > > > It turns out we don't actually have to recognize this stuff at the bit > level, just standard logical identities are sufficient. For example > > (X | Y) & ~Y -> X & ~Y > > > > Andrew P. might poke at this at the gimple level. The type changes > kindof get in the way in gimple but he's much better at match.pd than I > am, so if he wants to chase it from the gimple side, I'll fully support > that.
So we already have this pattern (without the type change) in gimple: /* (~x | y) & x -> x & y */ /* (~x & y) | x -> x | y */ (simplify (bitop:c (rbitop:c @2 @1) @0) (with { bool wascmp; } (if (bitwise_inverted_equal_p (@0, @2, wascmp) && (!wascmp || element_precision (type) == 1)) (bitop @0 @1)))) The problem is bitwise_inverted_equal_p does not see that: c.0_4 = (signed char) _1; _5 = ~c.0_4; _16 = (charD.11) _5; and c_11 = (charD.11) _1; are bitwise inversions of each other. I filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115449 to keep track of this. Thanks, Andrew Pinski > > Bootstrapped and regression tested on x86. Also run through my tester > on its embedded targets. > > Pushing to the trunk. > > jeff >