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 >
