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
>