On Fri, Aug 21, 2026 at 9:23 AM Sun, Qin <[email protected]> wrote:
>
> Fix 2 bugs mentioned in Bugzilla 119300:
>
> 1. When compiling with `-msoft-float -mfpmath=387`, `-msoft-float` turns off 
> 387.
> With neither FPMATH_SSE nor FPMATH_387 enabled, no unit can do FP arithmetics.
> The i386-options.cc omits this kind of check, so ICE is triggered. We need
> to add check in i386-options.cc to cover FPMATH_387 scenario when FPMATH_SSE
> is false.

This part is OK.

> 2. When compiling with `-std=c11 -mfpmath=387`, `-std=c11` denies XFmode 
> arithmetics
> for SFmode. When encountering: `(mult:SF (xx)(xx))`, `*fop_<mode>_comm` is not
> allowed to be chosen (because `X87_ENABLE_ARITH (<MODE>mode)` is false), which
> triggers an "unrecognizable insn". So we need to check whether SFmode 
> arithmetics
> are allowed before calling `ix86_emit_swsqrtsf` and use alternative methods if
> not.

__builtin_X is an internal implementation detail and these "builtin
functions" should not be used directly. There are several documented
__builtin_ia32_X builtins, but __builtin_ia32_rsqrtf is not one of
them (and for a reason, one can always write 1.0/sqrtf() ).

So, while ICE is unfortunate, it falls into the "Doctor it hurts when
I do that..." category.

Although ICE can be fixed by disabling __builtin_ia32_rsqrtf for
-mfpmath=387, the compilation will then fail with a call to the
unimplemented __builtin_ia32_rsqrtf function.

Uros

> gcc/ChangeLog:
>
>         PR target/119300
>         * config/i386/i386-options.cc (ix86_option_override_internal): Add 
> check for
>         FPMATH_SSE == 0 scenario to enable 387 (if available).
>         * config/i386/i386.md (rsqrthf2): Generate a software library call if 
> 387 is

rsqrtsf2

>         not enabled for SFmode.
>
> gcc/testsuite/ChangeLog:
>
>         PR target/119300
>         * gcc.target/i386/pr119300-1.c: New test.
>         * gcc.target/i386/pr119300-2.c: Ditto.
>         * gcc.target/i386/pr119300-3.c: Ditto.
> ---
>  gcc/config/i386/i386-options.cc            | 13 ++++++++
>  gcc/config/i386/i386.md                    | 36 +++++++++++++++++++++-
>  gcc/testsuite/gcc.target/i386/pr119300-1.c | 11 +++++++
>  gcc/testsuite/gcc.target/i386/pr119300-2.c |  6 ++++
>  gcc/testsuite/gcc.target/i386/pr119300-3.c |  7 +++++
>  5 files changed, 72 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr119300-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr119300-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr119300-3.c
>
> diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
> index 480862c7134..67c73d2ec6a 100644
> --- a/gcc/config/i386/i386-options.cc
> +++ b/gcc/config/i386/i386-options.cc
> @@ -2823,6 +2823,19 @@ ix86_option_override_internal (bool main_args_p,
>               opts->x_ix86_fpmath = FPMATH_SSE;
>             }
>         }
> +      else if (opts->x_ix86_fpmath & FPMATH_387)
> +       {
> +         if (!TARGET_80387_P (opts->x_target_flags))
> +           {
> +             if (TARGET_SSE_P (opts->x_ix86_isa_flags))
> +               {
> +                 warning (0, "387 instruction set disabled, using SSE 
> arithmetics");
> +                 opts->x_ix86_fpmath = FPMATH_SSE;
> +               }
> +             else
> +               error ("387 and SSE instruction sets disabled, no FP math 
> units");
> +           }
> +       }
>      }
>    /* For all chips supporting SSE2, -mfpmath=sse performs better than
>       fpmath=387.  The second is however default at many targets since the
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 81517eff7ec..484021855bb 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -25159,7 +25159,41 @@
>                    UNSPEC_RSQRT))]
>    "TARGET_SSE && TARGET_SSE_MATH"
>  {
> -  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
> +  /* Since builtin will call gen_* function directly, we need a guard
> +     "if" to avoid a ix86_emit_swsqrtsf call if SFmode mul is not
> +     supported. In this situation, we compute 1.0 / sqrt (a) in XFmode
> +     if TARGET_USE_FANCY_MATH_387 is on; and generate SW library call
> +     otherwise. */
> +  if (!(TARGET_SSE && TARGET_SSE_MATH)
> +      && !(TARGET_80387 && X87_ENABLE_ARITH(SFmode)))

Space after X87_ENABLE_ARITH.

> +    {
> +      if (TARGET_USE_FANCY_MATH_387)
> +        {
> +          /* TARGET_USE_FANCY_MATH_387 implies TARGET_80387 */
> +          rtx op0 = gen_reg_rtx (XFmode);
> +          rtx op1 = gen_reg_rtx (XFmode);
> +          rtx one = force_reg (XFmode, CONST1_RTX (XFmode));
> +          rtx res = gen_reg_rtx (XFmode);
> +
> +          emit_insn (gen_extendsfxf2 (op1, operands[1]));
> +          emit_insn (gen_sqrtxf2 (op0, op1));
> +          emit_insn (gen_divxf3 (res, one, op0));
> +          emit_insn (gen_truncxfsf2_i387_noop_unspec (operands[0], res));
> +        }
> +      else
> +        {
> +          rtx a = force_reg (SFmode, operands[1]);
> +          rtx sqrt = emit_library_call_value (init_one_libfunc ("sqrtf"),
> +                                              NULL_RTX, LCT_CONST, SFmode,
> +                                              a, SFmode);
> +          rtx recip = expand_binop (SFmode, sdiv_optab, CONST1_RTX (SFmode),
> +                                    sqrt, operands[0], 0, OPTAB_LIB_WIDEN);
> +          if (recip != operands[0])
> +            emit_move_insn (operands[0], recip);
> +        }
> +    }
> +  else
> +    ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
>    DONE;
>  })
>
> diff --git a/gcc/testsuite/gcc.target/i386/pr119300-1.c 
> b/gcc/testsuite/gcc.target/i386/pr119300-1.c
> new file mode 100644
> index 00000000000..aa10b5e2314
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr119300-1.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=c11 -msse -mfpmath=387" } */
> +
> +float
> +foo (float f)
> +{
> +  return __builtin_ia32_rsqrtf (f);
> +}
> +
> +/* { dg-final { scan-assembler "fsqrt" } } */
> +/* { dg-final { scan-assembler "fdiv" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr119300-2.c 
> b/gcc/testsuite/gcc.target/i386/pr119300-2.c
> new file mode 100644
> index 00000000000..db0129e4b0b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr119300-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msoft-float -mfpmath=387" } */
> +
> +#include "pr119300-1.c"
> +
> +/* { dg-warning "387 instruction set disabled, using SSE arithmetics" "" { 
> target *-*-* } 0 } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr119300-3.c 
> b/gcc/testsuite/gcc.target/i386/pr119300-3.c
> new file mode 100644
> index 00000000000..e21ab7d517e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr119300-3.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target ia32 } } */
> +/* { dg-options "-std=c11 -msse -mfpmath=387 -mno-fancy-math-387 
> -mtune=i486" } */
> +
> +#include "pr119300-1.c"
> +
> +/* { dg-final { scan-assembler "call\[ \t\]*sqrtf" } } */
> +/* { dg-final { scan-assembler-not "fsqrt" } } */
> --
> 2.25.1
>

Reply via email to