On Thu, Jul 2, 2026 at 6:57 AM Eikansh Gupta
<[email protected]> wrote:
>
> Add a pattern for `(trunc)copysign ((extend)x, CST)`.  Only the sign of
> CST matters, not its value, so it can be simplified to
> `copysign (x, -1.0/1.0)` depending on the sign of CST.

OK.

Thanks,
Richard.

>         PR tree-optimization/112472
>
> gcc/ChangeLog:
>
>         * match.pd ((trunc)copysign ((extend)x, CST) --> copysign (x, 
> -1.0/1.0)):
>         New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/pr112472.c: New test.
>
> Signed-off-by: Eikansh Gupta <[email protected]>
> ---
>  gcc/match.pd                             | 14 +++++++++++++-
>  gcc/testsuite/gcc.dg/tree-ssa/pr112472.c | 15 +++++++++++++++
>  2 files changed, 28 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index ddf3b61638c..7edc73945fb 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -9343,7 +9343,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>         && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@2))
>         && direct_internal_fn_supported_p (IFN_COPYSIGN,
>                                           type, OPTIMIZE_FOR_BOTH))
> -    (IFN_COPYSIGN @0 @1))))
> +    (IFN_COPYSIGN @0 @1)))
> + /* Simplify (trunc)copysign ((extend)x, CST) to copysign (x, -1.0/1.0).  */
> + (simplify
> +  (convert (copysigns (convert@2 @0) REAL_CST@1))
> +   (if (optimize
> +       && !HONOR_SNANS (@2)
> +       && types_match (type, TREE_TYPE (@0))
> +       && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@2))
> +       && direct_internal_fn_supported_p (IFN_COPYSIGN,
> +                                         type, OPTIMIZE_FOR_BOTH))
> +    (if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)))
> +     (IFN_COPYSIGN @0 { build_minus_one_cst (type); })
> +     (IFN_COPYSIGN @0 { build_one_cst (type); })))))
>
>  (for froms (BUILT_IN_FMAF BUILT_IN_FMA BUILT_IN_FMAL)
>       tos (IFN_FMA IFN_FMA IFN_FMA)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
> new file mode 100644
> index 00000000000..30ef7636a50
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/112472 */
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fdump-tree-optimized" } */
> +
> +/* (trunc)copysign ((extend)a, CST) with a negative CST should be
> +   simplified to .COPYSIGN (a, -1.0e+0).  */
> +float f(float a)
> +{
> +  return (float)__builtin_copysign(a, -3.0);
> +}
> +
> +/* { dg-final { scan-tree-dump-not "= __builtin_copysign" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not " double " "optimized" { target 
> ifn_copysign } } } */
> +/* { dg-final { scan-tree-dump-times ".COPYSIGN" 1 "optimized" { target 
> ifn_copysign } } } */
> +/* { dg-final { scan-tree-dump-times "-1.0e\\+0" 1 "optimized" { target 
> ifn_copysign } } } */
> --
> 2.34.1
>
>
> From bcf5f5a3836a3c0841f70dc98b964003fb3d1c89 Mon Sep 17 00:00:00 2001
> From: Eikansh Gupta <[email protected]>
> Date: Mon, 15 Jun 2026 12:19:45 +0530
> Subject: [PATCH v3 2/2] MATCH: Simplify `(trunc)abs ((extend)x)` to `abs (x)`
>  [PR112472]
>
> When the second argument of copysign is a non-negative constant, the
> inner copysign is canonicalized to abs before the copysign pattern can
> match, leaving (trunc)abs ((extend)x) with a redundant extend/truncate.
> Add a pattern so the non-negative-constant copysign case is fully optimized 
> too.
>
>         PR tree-optimization/112472
>
> gcc/ChangeLog:
>
>         * match.pd ((trunc)abs (extend x) --> abs (x)): New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/pr112472.c: Add non-negative constant case.
>
> Signed-off-by: Eikansh Gupta <[email protected]>
> ---
>  gcc/match.pd                             | 9 +++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/pr112472.c | 9 +++++++++
>  2 files changed, 18 insertions(+)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7edc73945fb..d627aa4728e 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -9357,6 +9357,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>       (IFN_COPYSIGN @0 { build_minus_one_cst (type); })
>       (IFN_COPYSIGN @0 { build_one_cst (type); })))))
>
> +/* (trunc)abs (extend x) --> abs (x)  */
> +(simplify
> + (convert (abs (convert@1 @0)))
> +  (if (optimize
> +      && !HONOR_SNANS (@1)
> +      && types_match (type, TREE_TYPE (@0))
> +      && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@1)))
> +   (abs @0)))
> +
>  (for froms (BUILT_IN_FMAF BUILT_IN_FMA BUILT_IN_FMAL)
>       tos (IFN_FMA IFN_FMA IFN_FMA)
>   (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
> index 30ef7636a50..6838c73c77e 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c
> @@ -9,7 +9,16 @@ float f(float a)
>    return (float)__builtin_copysign(a, -3.0);
>  }
>
> +/* With a non-negative CST, copysign is canonicalized to abs, so this
> +   becomes (float)abs((double)a) and is then simplified to abs(a),
> +   dropping the wider type.  */
> +float f2(float a)
> +{
> +  return (float)__builtin_copysign(a, 5.0);
> +}
> +
>  /* { dg-final { scan-tree-dump-not "= __builtin_copysign" "optimized" } } */
>  /* { dg-final { scan-tree-dump-not " double " "optimized" { target 
> ifn_copysign } } } */
>  /* { dg-final { scan-tree-dump-times ".COPYSIGN" 1 "optimized" { target 
> ifn_copysign } } } */
>  /* { dg-final { scan-tree-dump-times "-1.0e\\+0" 1 "optimized" { target 
> ifn_copysign } } } */
> +/* { dg-final { scan-tree-dump-times " ABS_EXPR " 1 "optimized" { target 
> ifn_copysign } } } */
> --
> 2.34.1
>

Reply via email to