On Wed, Aug 13, 2025 at 11:33 PM Uros Bizjak <ubiz...@gmail.com> wrote:
>
> On Thu, Aug 14, 2025 at 6:58 AM H.J. Lu <hjl.to...@gmail.com> wrote:
> >
> > Add target("80387") attribute to enable and disable x87 instructions in a
> > function.
> >
> > gcc/
> >
> >         PR target/121541
> >         * config/i386/i386-options.cc
> >         (ix86_valid_target_attribute_inner_p): Add a bool argument to
> >         return if x87 is disabled by target("no-80387") attribute.  Add
> >         and handle target("80387") attribute.
> >         (ix86_valid_target_attribute_tree): Get the x87 info from
> >         ix86_valid_target_attribute_inner_p and pass the info to
> >         ix86_option_override_internal.
> >         (ix86_option_override_internal): Add a bool argument to indicate
> >         if x87 should be disabled.  Don't enable x87 if it should be
> >         disabled.
> >         (ix86_option_override): Pass false to
> >         ix86_option_override_internal.
> >         * doc/extend.texi: Document target("80387") function attribute.
> >
> > gcc/testsuite/
> >
> >         PR target/121541
> >         * gcc.target/i386/pr121541-1a.c: New test.
> >         * gcc.target/i386/pr121541-1b.c: Likewise.
> >         * gcc.target/i386/pr121541-2.c: Likewise.
> >         * gcc.target/i386/pr121541-3.c: Likewise.
> >         * gcc.target/i386/pr121541-4.c: Likewise.
> >         * gcc.target/i386/pr121541-5a.c: Likewise.
> >         * gcc.target/i386/pr121541-5b.c: Likewise.
> >
> > Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> > ---
> >  gcc/config/i386/i386-options.cc             | 42 +++++++++++++++------
> >  gcc/doc/extend.texi                         |  5 +++
> >  gcc/testsuite/gcc.target/i386/pr121541-1a.c | 11 ++++++
> >  gcc/testsuite/gcc.target/i386/pr121541-1b.c |  6 +++
> >  gcc/testsuite/gcc.target/i386/pr121541-2.c  | 11 ++++++
> >  gcc/testsuite/gcc.target/i386/pr121541-3.c  | 11 ++++++
> >  gcc/testsuite/gcc.target/i386/pr121541-4.c  | 11 ++++++
> >  gcc/testsuite/gcc.target/i386/pr121541-5a.c | 11 ++++++
> >  gcc/testsuite/gcc.target/i386/pr121541-5b.c |  6 +++
> >  9 files changed, 102 insertions(+), 12 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-1a.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-1b.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-2.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-3.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-4.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-5a.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr121541-5b.c
> >
> > diff --git a/gcc/config/i386/i386-options.cc 
> > b/gcc/config/i386/i386-options.cc
> > index 09a35ef6298..30c10bed6bc 100644
> > --- a/gcc/config/i386/i386-options.cc
> > +++ b/gcc/config/i386/i386-options.cc
> > @@ -825,7 +825,8 @@ STATIC_ASSERT (ARRAY_SIZE (processor_cost_table) == 
> > PROCESSOR_max);
> >  static bool
> >  ix86_option_override_internal (bool main_args_p,
> >                                struct gcc_options *opts,
> > -                              struct gcc_options *opts_set);
> > +                              struct gcc_options *opts_set,
> > +                              bool disable_80387);
>
> m80387 option is a target option just like e.g. mrecip, so it should
> be processed in the same way. A new bool argument should not be
> needed, everything you need should be available via *opts and
> *opts_set.

It doesn't work because

        /* Don't enable x87 instructions if only general registers are
           allowed by target("general-regs-only") function attribute or
           -mgeneral-regs-only.  */
        if (!(opts->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
            && !(opts_set->x_target_flags & MASK_80387))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When MASK_80387 in opts_set and opts are cleared by target("80387")
function attribute,  MASK_80387 will be turned on again without
target("general-regs-only") function attribute nor  -mgeneral-regs-only.

          {
            if (((processor_alias_table[i].flags & PTA_NO_80387) != 0))
              opts->x_target_flags &= ~MASK_80387;
            else
              opts->x_target_flags |= MASK_80387;
          }

> Uros.
>
> >  static void
> >  set_ix86_tune_features (struct gcc_options *opts,
> >                         enum processor_type ix86_tune, bool dump);
> > @@ -988,7 +989,8 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree 
> > args, char *p_strings[],
> >                                      struct gcc_options *opts,
> >                                      struct gcc_options *opts_set,
> >                                      struct gcc_options *enum_opts_set,
> > -                                    bool target_clone_attr)
> > +                                    bool target_clone_attr,
> > +                                    bool &disable_80387)
> >  {
> >    char *next_optstr;
> >    bool ret = true;
> > @@ -1172,6 +1174,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, 
> > tree args, char *p_strings[],
> >                    OPT_mrecip,
> >                    MASK_RECIP),
> >
> > +    IX86_ATTR_YES ("80387",
> > +                  OPT_m80387,
> > +                  MASK_80387),
> > +
> >      IX86_ATTR_IX86_YES ("general-regs-only",
> >                         OPT_mgeneral_regs_only,
> >                         OPTION_MASK_GENERAL_REGS_ONLY),
> > @@ -1193,7 +1199,8 @@ ix86_valid_target_attribute_inner_p (tree fndecl, 
> > tree args, char *p_strings[],
> >             && !ix86_valid_target_attribute_inner_p (fndecl, TREE_VALUE 
> > (args),
> >                                                      p_strings, opts, 
> > opts_set,
> >                                                      enum_opts_set,
> > -                                                    target_clone_attr))
> > +                                                    target_clone_attr,
> > +                                                    disable_80387))
> >           ret = false;
> >
> >        return ret;
> > @@ -1287,7 +1294,11 @@ ix86_valid_target_attribute_inner_p (tree fndecl, 
> > tree args, char *p_strings[],
> >           if (opt_set_p)
> >             opts->x_target_flags |= mask;
> >           else
> > -           opts->x_target_flags &= ~mask;
> > +           {
> > +             if (mask == MASK_80387)
> > +               disable_80387 = true;
> > +             opts->x_target_flags &= ~mask;
> > +           }
> >         }
> >
> >        else if (type == ix86_opt_ix86_yes || type == ix86_opt_ix86_no)
> > @@ -1417,9 +1428,11 @@ ix86_valid_target_attribute_tree (tree fndecl, tree 
> > args,
> >    memset (&enum_opts_set, 0, sizeof (enum_opts_set));
> >
> >    /* Process each of the options on the chain.  */
> > +  bool disable_80387 = false;
> >    if (!ix86_valid_target_attribute_inner_p (fndecl, args, option_strings, 
> > opts,
> >                                             opts_set, &enum_opts_set,
> > -                                           target_clone_attr))
> > +                                           target_clone_attr,
> > +                                           disable_80387))
> >      return error_mark_node;
> >
> >    /* If the changed options are different from the default, rerun
> > @@ -1459,7 +1472,8 @@ ix86_valid_target_attribute_tree (tree fndecl, tree 
> > args,
> >         opts_set->x_prefer_vector_width_type = (enum prefer_vector_width) 1;
> >
> >        /* Do any overrides, such as arch=xxx, or tune=xxx support.  */
> > -      bool r = ix86_option_override_internal (false, opts, opts_set);
> > +      bool r = ix86_option_override_internal (false, opts, opts_set,
> > +                                             disable_80387);
> >        if (!r)
> >         {
> >           release_options_strings (option_strings);
> > @@ -1993,7 +2007,8 @@ ix86_init_machine_status (void)
> >  static bool
> >  ix86_option_override_internal (bool main_args_p,
> >                                struct gcc_options *opts,
> > -                              struct gcc_options *opts_set)
> > +                              struct gcc_options *opts_set,
> > +                              bool disable_80387)
> >  {
> >    unsigned int i;
> >    unsigned HOST_WIDE_INT ix86_arch_mask;
> > @@ -2371,10 +2386,12 @@ ix86_option_override_internal (bool main_args_p,
> >            & (PTA_PREFETCH_SSE | PTA_SSE)) != 0)
> >           ix86_prefetch_sse = true;
> >
> > -       /* Don't enable x87 instructions if only general registers are
> > -          allowed by target("general-regs-only") function attribute or
> > -          -mgeneral-regs-only.  */
> > -       if (!(opts->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
> > +       /* Don't enable x87 instructions if x87 instructions are disabled
> > +          by target("no-80387") function attribute, or only general
> > +          registers are allowed by target("general-regs-only") function
> > +          attribute or -mgeneral-regs-only.  */
> > +       if (!disable_80387
> > +           && !(opts->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
> >             && !(opts_set->x_target_flags & MASK_80387))
> >           {
> >             if (((processor_alias_table[i].flags & PTA_NO_80387) != 0))
> > @@ -3179,7 +3196,8 @@ ix86_option_override_internal (bool main_args_p,
> >  void
> >  ix86_option_override (void)
> >  {
> > -  ix86_option_override_internal (true, &global_options, 
> > &global_options_set);
> > +  ix86_option_override_internal (true, &global_options,
> > +                                &global_options_set, false);
> >  }
> >
> >  /* Remember the last target of ix86_set_current_function.  */
> > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> > index 224d6197d63..e2771d7e36a 100644
> > --- a/gcc/doc/extend.texi
> > +++ b/gcc/doc/extend.texi
> > @@ -6798,6 +6798,11 @@ Enable/disable the generation of RCPSS, RCPPS, 
> > RSQRTSS and RSQRTPS
> >  instructions followed an additional Newton-Raphson step instead of
> >  doing a floating-point division.
> >
> > +@cindex @code{target("80387")} function attribute, x86
> > +@item 80387
> > +@itemx no-80387
> > +Generate code containing 80387 instructions for floating point.
> > +
> >  @cindex @code{target("general-regs-only")} function attribute, x86
> >  @item general-regs-only
> >  Generate code which uses only the general registers.
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-1a.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-1a.c
> > new file mode 100644
> > index 00000000000..83884a7b15c
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-1a.c
> > @@ -0,0 +1,11 @@
> > +/* { dg-do compile { target { ! ia32 } } } */
> > +/* { dg-options "-O2 -march=x86-64" } */
> > +
> > +extern long double d;
> > +
> > +__attribute__ ((target("no-80387")))
> > +void
> > +func1 (void)
> > +{
> > +  d *= 3; /* { dg-error "x87 register return with x87 disabled" } */
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-1b.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-1b.c
> > new file mode 100644
> > index 00000000000..f440b14ca71
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-1b.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile { target ia32 } } */
> > +/* { dg-options "-O2" } */
> > +
> > +#include "pr121541-1a.c"
> > +
> > +/* { dg-final { scan-assembler "call\[\\t \]+_?__mulxf3" } } */
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-2.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-2.c
> > new file mode 100644
> > index 00000000000..281341e9bb9
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-2.c
> > @@ -0,0 +1,11 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mno-80387" } */
> > +
> > +extern long double d;
> > +
> > +__attribute__ ((target("80387")))
> > +void
> > +func1 (void)
> > +{
> > +  d *= 3;
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-3.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-3.c
> > new file mode 100644
> > index 00000000000..380fab2aad9
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-3.c
> > @@ -0,0 +1,11 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mgeneral-regs-only" } */
> > +
> > +extern long double d;
> > +
> > +__attribute__ ((target("80387")))
> > +void
> > +func1 (void)
> > +{
> > +  d *= 3;
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-4.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-4.c
> > new file mode 100644
> > index 00000000000..1f4381a52b0
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-4.c
> > @@ -0,0 +1,11 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2" } */
> > +
> > +extern long double d;
> > +
> > +__attribute__ ((target("general-regs-only","80387")))
> > +void
> > +func1 (void)
> > +{
> > +  d *= 3;
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-5a.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-5a.c
> > new file mode 100644
> > index 00000000000..e6137e22e98
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-5a.c
> > @@ -0,0 +1,11 @@
> > +/* { dg-do compile { target { ! ia32 } } } */
> > +/* { dg-options "-O2 -march=x86-64" } */
> > +
> > +extern long double d;
> > +
> > +__attribute__ ((target("80387","general-regs-only")))
> > +void
> > +func1 (void)
> > +{
> > +  d *= 3; /* { dg-error "x87 register return with x87 disabled" } */
> > +}
> > diff --git a/gcc/testsuite/gcc.target/i386/pr121541-5b.c 
> > b/gcc/testsuite/gcc.target/i386/pr121541-5b.c
> > new file mode 100644
> > index 00000000000..b61a7fe6a3f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr121541-5b.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile { target ia32 } } */
> > +/* { dg-options "-O2" } */
> > +
> > +#include "pr121541-5a.c"
> > +
> > +/* { dg-final { scan-assembler "call\[\\t \]+_?__mulxf3" } } */
> > --
> > 2.50.1
> >



-- 
H.J.

Reply via email to