https://gcc.gnu.org/g:e2c4fc6b1cff0d32dd7e6e4049d87c5193fea6dc
commit r17-2276-ge2c4fc6b1cff0d32dd7e6e4049d87c5193fea6dc Author: Eikansh Gupta <[email protected]> Date: Thu Jul 9 07:24:31 2026 -0600 [PATCH v3 1/2] MATCH: Simplify `(trunc)copysign ((extend)x, CST)` to `copysign (x, -1.0/1.0)` [PR112472] 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. 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. Diff: --- gcc/match.pd | 23 ++++++++++++++++++++++- gcc/testsuite/gcc.dg/tree-ssa/pr112472.c | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index 84fdb420af31..a7b658e9e940 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -9425,7 +9425,28 @@ 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); }))))) + +/* (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) 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 000000000000..6838c73c77e1 --- /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, 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); +} + +/* 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 } } } */
