https://gcc.gnu.org/g:35bf490452e06b3e3567933342fb15ef5d11f503
commit r15-4689-g35bf490452e06b3e3567933342fb15ef5d11f503 Author: Andrew Pinski <quic_apin...@quicinc.com> Date: Sun Oct 20 10:44:14 2024 -0700 simplify-rtx: Handle `a != 0 ? -a : 0` [PR58195] The gimple (and generic) levels have this optmization since r12-2041-g7d6979197274a662da7bdc5. It seems like a good idea to add a similar one to rtl just in case it is not caught at the gimple level. Note the loop case in csel-neg-1.c is not handled at the gimple level (even with phiopt turned back on), this is because of casts to avoid signed integer overflow; a patch to fix this at the gimple level will be submitted seperately. Changes since v1: * v2: Use `CONST0_RTX (mode)` instead of const0_rtx. Add csel-neg-2.c for float testcase which now passes. Build and tested for aarch64-linux-gnu. PR rtl-optimization/58195 gcc/ChangeLog: * simplify-rtx.cc (simplify_context::simplify_ternary_operation): Handle `a != 0 ? -a : 0` and `a == 0 ? 0 : -a`. gcc/testsuite/ChangeLog: * gcc.target/aarch64/csel-neg-1.c: New test. * gcc.target/aarch64/csel-neg-2.c: New test. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> Diff: --- gcc/simplify-rtx.cc | 22 +++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/csel-neg-1.c | 31 +++++++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/csel-neg-2.c | 19 ++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index e9591680f7c9..2c04ce960ee4 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -6909,6 +6909,28 @@ simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode, && rtx_equal_p (XEXP (op0, 1), op1)))) return op2; + /* Convert a != 0 ? -a : 0 into "-a". */ + if (GET_CODE (op0) == NE + && ! side_effects_p (op0) + && ! HONOR_NANS (mode) + && ! HONOR_SIGNED_ZEROS (mode) + && XEXP (op0, 1) == CONST0_RTX (mode) + && op2 == CONST0_RTX (mode) + && GET_CODE (op1) == NEG + && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))) + return op1; + + /* Convert a == 0 ? 0 : -a into "-a". */ + if (GET_CODE (op0) == EQ + && ! side_effects_p (op0) + && ! HONOR_NANS (mode) + && ! HONOR_SIGNED_ZEROS (mode) + && op1 == CONST0_RTX (mode) + && XEXP (op0, 1) == CONST0_RTX (mode) + && GET_CODE (op2) == NEG + && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0))) + return op2; + /* Convert (!c) != {0,...,0} ? a : b into c != {0,...,0} ? b : a for vector modes. */ if (VECTOR_MODE_P (GET_MODE (op1)) diff --git a/gcc/testsuite/gcc.target/aarch64/csel-neg-1.c b/gcc/testsuite/gcc.target/aarch64/csel-neg-1.c new file mode 100644 index 000000000000..7551965bccab --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/csel-neg-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* Disable phiopt as that will optimize away the `?:`, + want to test simplify-rtx */ +/* { dg-options "-O2 -fno-ssa-phiopt" } */ + +/* PR rtl-optimization/58195 */ + +int a2(int input) +{ + if (input == 0) + return 0; + return -input; +} +int a1(int input) +{ + int t = -input; + return input == 0 ? 0 : t; +} + +int a(int input) +{ + int value = 0; + for(int n = input; n != 0; ++n) + ++value; + return value; +} + +/* There should be no comparison against 0 here, */ +/* { dg-final { scan-assembler-not "cmp\t" } } */ +/* { dg-final { scan-assembler "\tneg\t" } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/csel-neg-2.c b/gcc/testsuite/gcc.target/aarch64/csel-neg-2.c new file mode 100644 index 000000000000..72fe9b7d03f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/csel-neg-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* Disable phiopt as that will optimize away the `?:`, + want to test simplify-rtx */ +/* { dg-options "-O2 -ffast-math -fno-ssa-phiopt" } */ + +/* PR rtl-optimization/58195 */ + +float a2(float input) +{ + if (input == 0) + return 0; + return -input; +} + +/* There should be no comparison against 0 here, */ +/* { dg-final { scan-assembler-not "\tfcmp\t" } } */ +/* { dg-final { scan-assembler-not "\tfcsel\t" } } */ +/* { dg-final { scan-assembler "\tfneg\t" } } */ +