On Thu, Jan 29, 2026 at 8:22 AM Andrew Pinski
<[email protected]> wrote:
>
> The problem here is we try to use the widening type before
> doing the bitwise expansion of neg/and for floating point types.
> This moves the code around to try the bitwise expansion first.
>
> Note this mostly matters for NaNs where you widening (promotion)
> would cause a NaN to be slightly different when doing the rounding
> back.

So we may not try widening for FP neg/abs at all (unless maybe
with -funsafe-math-optimizations), but instead should fall back
to libcalls, no?

>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

Thanks,
Richard.

>         PR middle-end/123869
>
> gcc/ChangeLog:
>
>         * optabs.cc (expand_unop): Move the NEG optab
>         handling before the widening code.
>         Move the ABS bitwise expansion from expand_abs_nojump
>         to before the widening code.
>         (expand_abs_nojump): Remove the bitwise expansion trial
>         since expand_unop is called right above.
>
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
>  gcc/optabs.cc | 65 ++++++++++++++++++++++++++-------------------------
>  1 file changed, 33 insertions(+), 32 deletions(-)
>
> diff --git a/gcc/optabs.cc b/gcc/optabs.cc
> index 5a1d4c75704..f94d2e49820 100644
> --- a/gcc/optabs.cc
> +++ b/gcc/optabs.cc
> @@ -3376,6 +3376,39 @@ expand_unop (machine_mode mode, optab unoptab, rtx 
> op0, rtx target,
>        goto try_libcall;
>      }
>
> +  /* Neg should be tried via expand_absneg_bit before widening. */
> +  if (optab_to_code (unoptab) == NEG)
> +    {
> +      /* Try negating floating point values by flipping the sign bit.  */
> +      if (is_a <scalar_float_mode> (GET_MODE_INNER (mode), &float_mode))
> +       {
> +         temp = expand_absneg_bit (NEG, mode, float_mode, op0, target);
> +         if (temp)
> +           return temp;
> +       }
> +
> +      /* If there is no negation pattern, and we have no negative zero,
> +        try subtracting from zero.  */
> +      if (!HONOR_SIGNED_ZEROS (mode))
> +       {
> +         temp = expand_binop (mode, (unoptab == negv_optab
> +                                     ? subv_optab : sub_optab),
> +                              CONST0_RTX (mode), op0, target,
> +                              unsignedp, OPTAB_DIRECT);
> +         if (temp)
> +           return temp;
> +       }
> +    }
> +
> +  /* ABS also needs to be handled similarly. */
> +  if (optab_to_code (unoptab) == ABS
> +      && is_a <scalar_float_mode> (GET_MODE_INNER (mode), &float_mode))
> +    {
> +      temp = expand_absneg_bit (ABS, mode, float_mode, op0, target);
> +      if (temp)
> +       return temp;
> +    }
> +
>    if (CLASS_HAS_WIDER_MODES_P (mclass))
>      FOR_EACH_WIDER_MODE (wider_mode, mode)
>        {
> @@ -3460,29 +3493,6 @@ expand_unop (machine_mode mode, optab unoptab, rtx 
> op0, rtx target,
>         return temp;
>      }
>
> -  if (optab_to_code (unoptab) == NEG)
> -    {
> -      /* Try negating floating point values by flipping the sign bit.  */
> -      if (is_a <scalar_float_mode> (GET_MODE_INNER (mode), &float_mode))
> -       {
> -         temp = expand_absneg_bit (NEG, mode, float_mode, op0, target);
> -         if (temp)
> -           return temp;
> -       }
> -
> -      /* If there is no negation pattern, and we have no negative zero,
> -        try subtracting from zero.  */
> -      if (!HONOR_SIGNED_ZEROS (mode))
> -       {
> -         temp = expand_binop (mode, (unoptab == negv_optab
> -                                     ? subv_optab : sub_optab),
> -                              CONST0_RTX (mode), op0, target,
> -                              unsignedp, OPTAB_DIRECT);
> -         if (temp)
> -           return temp;
> -       }
> -    }
> -
>    /* Try calculating parity (x) as popcount (x) % 2.  */
>    if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
>      {
> @@ -3680,15 +3690,6 @@ expand_abs_nojump (machine_mode mode, rtx op0, rtx 
> target,
>    if (temp != 0)
>      return temp;
>
> -  /* For floating point modes, try clearing the sign bit.  */
> -  scalar_float_mode float_mode;
> -  if (is_a <scalar_float_mode> (GET_MODE_INNER (mode), &float_mode))
> -    {
> -      temp = expand_absneg_bit (ABS, mode, float_mode, op0, target);
> -      if (temp)
> -       return temp;
> -    }
> -
>    /* If we have a MAX insn, we can do this as MAX (x, -x).  */
>    if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
>        && !HONOR_SIGNED_ZEROS (mode))
> --
> 2.43.0
>

Reply via email to