On Mon, Jun 22, 2026 at 2:01 AM Richard Biener <[email protected]> wrote: > > On Mon, Jun 22, 2026 at 7:29 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, +-0.0)` depending on the sign of CST. When signed zeros > > are not honored their sign may be lost, so `copysign (x, +-1.0)` is used > > instead. > > Is it worth that trouble? Why not always use +-1.0?
Jeff asked him to change it to be that way but I think it is not so useful. So yes using +-1.0 should be used. Though +1 will turn into ABS_EXPR anyways. > > As a side-note (but existing pattern before looks the same), I wonder if > there's any two FP formats X and Y with TYPE_PRECISION (X) > TYPE_PRECISION > (Y) > where "extending" from Y to X can involve rounding, thus not all values in Y > are exactly representable in X? What about normalization to NaNs or Infs or > denormals? Yes, that could be an issue. infs should not be an issue. Normalization for NaN and rounding might be an issue. The other pattern which has a similar issue is the conversion to/from even without copysign. -frounding-math should disable both of those but don't. I will file a bug about these set of patterns in the morning for this. Thanks, Andrea > > > > > PR tree-optimization/112472 > > > > gcc/ChangeLog: > > > > * match.pd ((trunc)copysign ((extend)x, CST) --> copysign (x, > > +-0.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 | 20 +++++++++++++++++++- > > gcc/testsuite/gcc.dg/tree-ssa/pr112472.c | 24 ++++++++++++++++++++++++ > > 2 files changed, 43 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 8c410c2f3b3..e050ecdf6d6 100644 > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -9293,7 +9293,25 @@ 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, +-0.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)) > > + (with { bool neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (@1)); > > + /* Use +-0.0 if possible. When signed zeros are not honored, > > + use +-1.0 instead. */ > > + tree cst = HONOR_SIGNED_ZEROS (type) > > + ? (neg ? build_real (type, dconstm0) > > + : build_zero_cst (type)) > > + : (neg ? build_minus_one_cst (type) > > + : build_one_cst (type)); } > > + (IFN_COPYSIGN @0 { cst; }))))) > > > > (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..0112b4a2b61 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c > > @@ -0,0 +1,24 @@ > > +/* PR tree-optimization/112472 */ > > +/* { dg-do compile } */ > > +/* { dg-options "-O1 -fdump-tree-optimized" } */ > > + > > +/* (trunc)copysign ((extend)a, negative CST) is simplified to > > + .COPYSIGN (a, -0.0). */ > > +float f(float a) > > +{ > > + return (float)__builtin_copysign(a, -3.0); > > +} > > + > > +/* When signed zeros are not honored, .COPYSIGN (a, -1.0) is used > > + instead. */ > > +__attribute__((optimize("no-signed-zeros"))) > > +float g(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" 2 "optimized" { target > > ifn_copysign } } } */ > > +/* { dg-final { scan-tree-dump-times "-0\\.0" 1 "optimized" { target > > ifn_copysign } } } */ > > +/* { dg-final { scan-tree-dump-times "-1\\.0e\\+0" 1 "optimized" { target > > ifn_copysign } } } */ > > -- > > 2.34.1 > > > > > > From 208e5c41a71f0900d37ba3d51a57911a32931de4 Mon Sep 17 00:00:00 2001 > > From: Eikansh Gupta <[email protected]> > > Date: Mon, 15 Jun 2026 12:19:45 +0530 > > Subject: [PATCH v2 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 e050ecdf6d6..7f540aa1c4e 100644 > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -9313,6 +9313,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > : build_one_cst (type)); } > > (IFN_COPYSIGN @0 { cst; }))))) > > > > +/* (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 0112b4a2b61..6aa905497bc 100644 > > --- a/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112472.c > > @@ -17,8 +17,17 @@ float g(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" 2 "optimized" { target > > ifn_copysign } } } */ > > /* { dg-final { scan-tree-dump-times "-0\\.0" 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 > >
