From: Andrew Pinski <pins...@gmail.com>

On targets with native copysign instructions, (copysign x, -1) is
usually more efficient than (fneg (fabs x)).  Since r14-5284, in the
middle end we always optimize (fneg (fabs x)) to (copysign x, -1), not
vice versa.  If the target does not support native fcopysign,
expand_COPYSIGN will expand it as (fneg (fabs x)) anyway.

gcc/ChangeLog:

        PR rtl-optimization/112483
        * simplify-rtx.cc (simplify_binary_operation_1) <case COPYSIGN>:
        Call simplify_unary_operation for NEG instead of
        simplify_gen_unary.
---

[xry111]:

Following Andrew's suggestion, I bootstrapped and regtested this
patch on loongarch64-linux-gnu.  Now with

        float t(float x)
        {
          return __builtin_copysignf(x, -0.1234);
        }

It correctly generates

        pcalau12i       $r12,%pc_hi20(.LC0)
        fld.s   $f1,$r12,%pc_lo12(.LC0)
        fcopysign.s     $f0,$f0,$f1
        jr      $r1

instead of the de-optimized fabs.s and fneg.s

Ok for trunk?

 gcc/simplify-rtx.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 2d2e5a3c1ca..f3745d86aea 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -4392,7 +4392,7 @@ simplify_ashift:
          real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
          rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
          if (REAL_VALUE_NEGATIVE (f1))
-           tmp = simplify_gen_unary (NEG, mode, tmp, mode);
+           tmp = simplify_unary_operation (NEG, mode, tmp, mode);
          return tmp;
        }
       if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
-- 
2.42.1

Reply via email to