On Wed, May 6, 2026 at 3:10 PM Eikansh Gupta
<[email protected]> wrote:
>
> (float)a - (float)b -> (float)((signed_wider)a - (signed_wider)b) when
> a and b are the same integer type exactly representable in the float
> type. Uses a signed type one bit wider than the operand type to hold
> the full mathematical difference without overflow.
>
> PR tree-optimization/124571
>
> gcc/ChangeLog:
>
> * match.pd ((float)a - (float)b -> (float)(signed)(a - b)): New
> pattern.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/pr124571.c: New test.
>
> Signed-off-by: Eikansh Gupta <[email protected]>
> ---
> gcc/match.pd | 15 +++++++++++++
> gcc/testsuite/gcc.dg/tree-ssa/pr124571.c | 28 ++++++++++++++++++++++++
> 2 files changed, 43 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr124571.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7db8ce7580f..4cb0cf4bece 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2112,6 +2112,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (if (!flag_trapping_math)
> (abs @0))))
>
> +/* (float)a - (float)b -> (float)(signed)(a - b) */
> +(simplify
> + (minus (float @0) (float @1))
> + (if (!DECIMAL_FLOAT_TYPE_P (type)
> + && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> + && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1)))
> + (with
> + {
> + tree stype = build_nonstandard_integer_type
> + (TYPE_PRECISION (TREE_TYPE (@0)) + 1, 0);
> + format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (type)));
> + }
> + (if (fmt.can_represent_integral_type_p (stype))
> + (float (minus (convert:stype @0) (convert:stype @1)))))))
Mostly OK. Do we need to consider sfloat<stype> to be not supported but
sfloat<typeof (@0)> supported? That said, you are building (and using)
a bit-precision integer type, I think you want to use an integer type
twice as wide for the convert and the minus?
> +
> (simplify
> (absu (negate @0))
> (absu @0))
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr124571.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr124571.c
> new file mode 100644
> index 00000000000..4827549bbec
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr124571.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +/* The two separate float casts must be gone; only one remains. */
> +float f1 (unsigned short a, unsigned short b)
> +{
> + return (float)a - (float)b;
> +}
> +
> +float f2 (short a, short b)
> +{
> + return (float)a - (float)b;
> +}
> +
> +double f3 (unsigned short a, unsigned short b)
> +{
> + return (double)a - (double)b;
> +}
> +
> +double f4 (int a, int b)
> +{
> + return (double)a - (double)b;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "(float) a" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "(float) b" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "(double) a" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "(double) b" "optimized" } } */
> --
> 2.34.1
>
>
> From a678afce7b931a937b779a33e5f6109637d5ea96 Mon Sep 17 00:00:00 2001
> From: Eikansh Gupta <[email protected]>
> Date: Wed, 6 May 2026 18:21:03 +0530
> Subject: [PATCH 2/3] MATCH: Simplify abs((float)a) -> (float)abs(a) [PR124571]
>
> abs((float)a) -> (float)abs(a) when a is an integer exactly
> representable in the float type.
>
> PR tree-optimization/124571
>
> gcc/ChangeLog:
>
> * match.pd (abs((float)a) -> (float)abs(a)): New pattern.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/pr124571-1.c: New test.
>
> Signed-off-by: Eikansh Gupta <[email protected]>
> ---
> gcc/match.pd | 14 ++++++++++++++
> gcc/testsuite/gcc.dg/tree-ssa/pr124571-1.c | 15 +++++++++++++++
> 2 files changed, 29 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr124571-1.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 4cb0cf4bece..02479af9dc1 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2127,6 +2127,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (if (fmt.can_represent_integral_type_p (stype))
> (float (minus (convert:stype @0) (convert:stype @1)))))))
>
> +/* abs((float)a) -> (float)abs(a) */
> +(simplify
> + (abs (float @0))
> + (if (!DECIMAL_FLOAT_TYPE_P (type)
> + && INTEGRAL_TYPE_P (TREE_TYPE (@0)))
> + (with
> + {
> + tree stype = build_nonstandard_integer_type
> + (TYPE_PRECISION (TREE_TYPE (@0)) + 1, 0);
> + format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (type)));
> + }
> + (if (fmt.can_represent_integral_type_p (stype))
> + (float (abs (convert:stype @0)))))))
> +
> (simplify
> (absu (negate @0))
> (absu @0))
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr124571-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr124571-1.c
> new file mode 100644
> index 00000000000..6cc82c4faea
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr124571-1.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +/* abs((float)a) < 1.0f folds to a == 0. */
> +int f1 (short a)
> +{
> + return __builtin_fabsf ((float)a) < 1.0f;
> +}
> +
> +int f2 (short a)
> +{
> + return __builtin_fabs ((double)a) < 1.0;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "ABS_EXPR" "optimized" } } */
> --
> 2.34.1
>
>
> From e293f8dc88d64556bfa203a1f2e4ce34a42e3074 Mon Sep 17 00:00:00 2001
> From: Eikansh Gupta <[email protected]>
> Date: Wed, 6 May 2026 18:25:23 +0530
> Subject: [PATCH 3/3] testsuite: Add combined minus+abs test for PR124571
>
> PR tree-optimization/124571
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/pr124571-2.c: New test.
>
> Signed-off-by: Eikansh Gupta <[email protected]>
> ---
> gcc/testsuite/gcc.dg/tree-ssa/pr124571-2.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr124571-2.c
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr124571-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr124571-2.c
> new file mode 100644
> index 00000000000..bf75ad06424
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr124571-2.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int f1 (unsigned short a, unsigned short b)
> +{
> + float s = __builtin_fabsf ((float)a - (float)b);
> + return s < 1.0f;
> +}
> +
> +int f2 (short a, short b)
> +{
> + float s = __builtin_fabsf ((float)a - (float)b);
> + return s < 1.0f;
> +}
> +
> +int f4 (unsigned short a, unsigned short b)
> +{
> + double s = __builtin_fabs ((double)a - (double)b);
> + return s < 1.0;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "ABS_EXPR" "optimized" } } */
> --
> 2.34.1
>