I found this gem in some glibc test case: if (c != 0) c /= abs (c); This could turn into: if (c < 0) c = -1; else if (c > 0) c = 1; This would eliminate the division and also paper of the bug (the unexpected 1 result for INT_MIN).
Full testcase(?) int foo (int c) { if (c != 0) c /= __builtin_abs (c); return c; } Possible "fix": (simplify (trunc_div @0 (abs @0)) (if (! TYPE_UNSIGNED (type) && TYPE_OVERFLOW_UNDEFINED (type)) (cond (lt @0 { build_zero_cst (type); }) { build_minus_one_cst (type); } { build_one_cst (type); }))) but eventually we should simply make __builtin_copysign also work on integers... Not sure if desirable also for _Complex int and vector int (both handled above). Need to double-check for non-truncating divisions. Similar testcase would be if (c != 0) c /= -c;
Fixed.
Author: rguenth Date: Thu Sep 29 12:28:19 2016 New Revision: 240616 URL: https://gcc.gnu.org/viewcvs?rev=240616&root=gcc&view=rev Log: 2016-09-29 Richard Biener <rguenther@suse.de> PR middle-end/77407 * match.pd: Add X / abs (X) -> X < 0 ? -1 : 1 and X / -X -> -1 simplifications. * gcc.dg/pr77407.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/pr77407.c Modified: trunk/gcc/ChangeLog trunk/gcc/match.pd trunk/gcc/testsuite/ChangeLog
Author: rguenth Date: Tue Oct 4 13:18:18 2016 New Revision: 240742 URL: https://gcc.gnu.org/viewcvs?rev=240742&root=gcc&view=rev Log: 2016-10-04 Richard Biener <rguenther@suse.de> PR middle-end/77407 * match.pd (X / abs (X) -> X < 0 ? -1 : 1): Drop vector type support, mark with :C. (X / -X -> -1): Mark with :C. Modified: trunk/gcc/ChangeLog trunk/gcc/match.pd