[gcc r17-3279] match: Try to remove casts for `(int)-(unsigned)a`[PR107765]
Andrea Pinski via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:8d004ef91c4f7c315519975ffaec78d28d4a21ff commit r17-3279-g8d004ef91c4f7c315519975ffaec78d28d4a21ff Author: Andrea Pinski <[email protected]> Date: Mon Jul 27 23:02:07 2026 -0700 match: Try to remove casts for `(int)-(unsigned)a`[PR107765] This adds some extra checks to see if we can remove the casts for signed integer overflow reasons while doing a negative. This is needed more due to the recent patch which adds them in some cases. This also changes TYPE_UNSIGNED to be TYPE_OVERFLOW_WRAPS to allow this to happen with -fwrapv too. Changes since v1: * Use expr_not_equal_to and simplify the if stmt. Also use TYPE_OVERFLOW_WRAPS instead of TYPE_UNSIGNED. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/107765 gcc/ChangeLog: * match.pd (`(cast)-(cast)a`): Expand to use expr_not_equal_to of INT_MIN. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/neg-cast-1.c: New test. * gcc.dg/tree-ssa/neg-cast-4.c: New test. Signed-off-by: Andrea Pinski <[email protected]> Diff: --- gcc/match.pd | 10 +++++++--- gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c | 16 ++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index f43d2e79363b..4ddddc43bd72 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1231,13 +1231,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) show up. Else it is safe if the negation is done in an unsigned type. Note the outer cast cannot be a boolean type as the only valid values are 0,-1/1 (depending on the signedness of the boolean) and the negative - is there to get the correct value. */ + is there to get the correct value. + Also handle the case where we know that we won't cause a signed + integer overflow at the point of the negation. */ (simplify - (convert (negate:s@1 (convert:s @0))) + (convert (negate:s@1 (convert:s@ic @0))) (if (INTEGRAL_TYPE_P (type) && tree_nop_conversion_p (type, TREE_TYPE (@1)) && (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)) - || TYPE_UNSIGNED (type)) + || TYPE_OVERFLOW_WRAPS (type) + || expr_not_equal_to (@ic, wi::min_value (signed_type_for (type)), + gimple_match_ctx (@1))) && TREE_CODE (type) != BOOLEAN_TYPE) (negate (convert @0)))) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c new file mode 100644 index 000000000000..ec5d0e15251b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-cddce1" } */ +/* PR tree-optimization/107765 */ + +int a(int input) +{ + if (input == -__INT_MAX__-1) return 1; + unsigned t = input; + int tt = -t; + return tt == -input; +} + +int b(int input) +{ + if (input == -__INT_MAX__-1) __builtin_trap(); + unsigned t = input; + int tt = -t; + return tt; +} + +/* { dg-final { scan-tree-dump "return 1" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(unsigned int\\)" "cddce1" } } */ +/* { dg-final { scan-tree-dump-not "\\(int\\)" "cddce1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c new file mode 100644 index 000000000000..fe3fe6a2eccf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/neg-cast-4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt2-details -fdump-tree-optimized" } */ +/* PR tree-optimization/107765 */ + +int b(int input) +{ + if (input == -__INT_MAX__-1) return input; + unsigned t = input; + int tt = -t; + return tt; +} + +/* { dg-final { scan-tree-dump-not "if " "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\(int\\)" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "converted to straightline code" 1 "phiopt2" } } */