[gcc r17-2276] [PATCH v3 1/2] MATCH: Simplify `(trunc)copysign ((extend)x, CST)` to `copysign (x, -1.0/1.0)` [PR112

Jeff Law via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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 } } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.