On Sun, Aug 7, 2022 at 9:08 PM Roger Sayle <ro...@nextmovesoftware.com> wrote: > > > Following my middle-end patch for PR tree-optimization/94026, I'd promised > Jeff Law that I'd clean up the dead-code in fold-const.cc now that these > optimizations are handled in match.pd. Alas, I discovered things aren't > quite that simple, as the transformations I'd added avoided cases where > C2 overlapped with the new bits introduced by the shift, but the original > code handled any value of C2 provided that it had a single-bit set (under > the condition that C3 was always zero). > > This patch upgrades the transformations supported by match.pd to cover > any values of C2 and C3, provided that C1 is a valid bit shift constant, > for all three shift types (logical right, arithmetic right and left). > This then makes the code in fold-const.cc fully redundant, and adds > support for some new (corner) cases not previously handled. If the > constant C1 is valid for the type's precision, the shift is now always > eliminated (with C2 and C3 possibly updated to test the sign bit). > > Interestingly, the fold-const.cc code that I'm now deleting was originally > added by me back in 2006 to resolve PR middle-end/21137. I've confirmed > that those testcase(s) remain resolved with this patch (and I'll close > 21137 in Bugzilla). This patch also implements most (but not all) of the > examples mentioned in PR tree-optimization/98954, for which I have some > follow-up patches. > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap > and make -k check, both with and without --target_board=unix{-m32}, > with no new failures. Ok for mainline?
+ (with { wide_int smask = wi::arshift (sb, c1); } + (if ((c2 & smask) == 0) + (cmp (bit_and @0 { wide_int_to_tree (t0, c2 << c1); }) + { wide_int_to_tree (t0, c3 << c1); }) + (if ((c3 & smask) == 0) + (cmp (bit_and @0 { wide_int_to_tree (t0, (c2 << c1) | sb); }) + { wide_int_to_tree (t0, c3 << c1); }) + (if ((c2 & smask) != (c3 & smask)) you can use (switch (if ((c2 & smask) == 0) (...) (if ((c3 & smask) == 0) (..) (if ((c2 & smask) != (c3 & smask)) (..))) to make this better readable (switch is basically an if else-if else-if ... clause). OK with that change. Thanks, Richard. > > 2022-08-07 Roger Sayle <ro...@nextmovesoftware.com> > > gcc/ChangeLog > PR middle-end/21137 > PR tree-optimization/98954 > * fold-const.cc (fold_binary_loc): Remove optimizations to > optimize ((X >> C1) & C2) ==/!= 0. > * match.pd (cmp (bit_and (lshift @0 @1) @2) @3): Remove wi::ctz > check, and handle all values of INTEGER_CSTs @2 and @3. > (cmp (bit_and (rshift @0 @1) @2) @3): Likewise, remove wi::clz > checks, and handle all values of INTEGER_CSTs @2 and @3. > > gcc/testsuite/ChangeLog > PR middle-end/21137 > PR tree-optimization/98954 > * gcc.dg/fold-eqandshift-4.c: New test case. > > > Thanks in advance, > Roger > -- >