On Thu, Feb 3, 2022 at 4:50 AM Arjun Shankar <ar...@redhat.com> wrote: > > Expressions of the form "X + CST < Y + CST" where: > > * CST is an unsigned integer constant with only the MSB set, and > * X and Y's types have integer conversion ranks <= CST's > > can be simplified to "(signed) X < (signed) Y". > > This is because, assuming a 32-bit signed numbers, > (unsigned) INT_MIN + 0x80000000 is 0, and > (unsigned) INT_MAX + 0x80000000 is UINT_MAX. > > i.e. the result increases monotonically with signed input. > > This means: > ((signed) X < (signed) Y) iff (X + 0x80000000 < Y + 0x80000000)
+ (op (plus:c INTEGER_CST@0 @1) (plus:c INTEGER_CST@0 @2)) INTEGER_CST are put last by canonicalization so you should write (op (plus @1 INTEGER_CST@0) (plus @2 INTEGER_CST@0)) and thus omit the :c. +#define MAGIC 0x80000000 I _think_ writing the constant this way requires /* { dg-require-effective-target int32plus } */ as on a target where int is 16 bits it possibly yields a diagnostic? I've been using explicit int32_t types w/o such effective target in the past but I'm not sure how to write an explicit precision constant to avoid diagnostics. Note I didn't actually check we get a diagnostic ... Slapping on the dg-requires-effective-target should be safe though. Otherwise looks good now - note this has to wait for stage1 of GCC 13, so make sure to ping then or commit then in case you have git access. Thanks, Richard. > gcc/ > * match.pd (X + C < Y + C -> (signed) X < (signed) Y, if C is > 0x80000000): New simplification. > gcc/testsuite/ > * gcc.dg/pr94899.c: New test. > --- > gcc/match.pd | 13 +++++++++ > gcc/testsuite/gcc.dg/pr94899.c | 48 ++++++++++++++++++++++++++++++++++ > 2 files changed, 61 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/pr94899.c > --- > v1: https://gcc.gnu.org/pipermail/gcc-patches/2022-February/589557.html > > Notes on v2, based on Richard's review comments: > > 1. I removed matching on "convert", and therefore also replaced the > removal of convert upon simplification with an explicit cast to > signed. I originally thought this simplification only applies to > signed operands that have been cast to unsigned, but thinking about > it, it became clear that they do not necessarily have to be signed > originally. The simplification is now a bit more general. > > 2. Removed checks for operands' types as it seems to be unnecessary. I > hope this is correct. > > 3. Added unsigned types and mismatched sizes of operands to the test. > These are now simplified.