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 } } } */

Reply via email to