On Mon, Jul 20, 2026 at 4:03 PM H.J. Lu <[email protected]> wrote:
>
> On Mon, Jul 20, 2026 at 3:41 PM Hongtao Liu <[email protected]> wrote:
> >
> > On Fri, Jul 10, 2026 at 2:51 PM H.J. Lu <[email protected]> wrote:
> > >
> > > On Thu, Jul 9, 2026 at 2:42 PM Hongtao Liu <[email protected]> wrote:
> > > >
> > > > On Thu, Jul 9, 2026 at 9:41 AM H.J. Lu <[email protected]> wrote:
> > > > >
> > > > > In 64-bit mode, preserve_none attribute uses a different calling
> > > > > convention.  Ignore MS ABI with preserve_none attribute to always
> > > > > use the preserve_none calling convention with preserve_none
> > > > > attribute.
> > > > >
> > > > > gcc/
> > > > >
> > > >
> > > > >
> > > > > It has 8 registers.   Tests show that
> > > > > x86_64_preserve_none_int_parameter_registers
> > > > > is used for functions with __attribute__ ((preserve_none, ms_abi)).
> > > > I mean for sse registers, init_cumulative_args sets the integer count
> > > > via the new predicate but leaves the SSE count keyed on the raw ABI
> > > > (i386.cc:1940):
> > >
> > > Fixed with tests in the v3 patch.
> > >
> > > > 927  /* Set up the number of registers to use for passing arguments.  */
> > > > 928  cum->nregs = ix86_regparm;
> > > > 929  if (TARGET_64BIT)
> > > > 930    {
> > > > 931      cum->nregs = (x86_64_cumulative_ms_abi_p (cum)
> > > > 932                    ? X86_64_MS_REGPARM_MAX
> > > > 933                    : X86_64_REGPARM_MAX);
> > > > 934    }
> > > > 935  if (TARGET_SSE)
> > > > 936    {
> > > > 937      cum->sse_nregs = SSE_REGPARM_MAX;
> > > > 938      if (TARGET_64BIT)
> > > > 939        {
> > > > 940          cum->sse_nregs = (cum->call_abi == SYSV_ABI
> > > > 941                           ? X86_64_SSE_REGPARM_MAX
> > > > 942                           : X86_64_MS_SSE_REGPARM_MAX);
> > > > 943        }
> > > > 944    }
> > > >
> > > >
> > > >  if  -mabi=ms is in the command line, with plain preserve_none in the
> > > > attribute, only 4 sse registers is used for parameter passing
> > > > But with __attribute__ ((preserve_none, ms_abi)), 8 sse registers are
> > > > used for parameter passing.
> > > >
> > > > .i.e
> > > > void bar(double,double,double,double,double,double)
> > > > __attribute__((preserve_none));
> > > >
> > > > void
> > > > entry (long a1, long a2, long a3, long a4, long a5, long a6)
> > > > {
> > > > bar (a1, a2, a3, a4, a5, a6);
> > > > }
> > > >
> > >
> > > Fixed with tests in the v3 patch.
> > >
> > > Here is the v3 patch.
> >
> > Ok.
>
> I found an issue with the v3 patch.   Here is the v4 patch with
> the fix:
>
> @@ -1665,10 +1668,18 @@ ix86_function_type_abi (const_tree fntype)
>           warned = 1;
>         }
>
> -      abi = MS_ABI;
> +      /* NB: preserve_none attribute overrides ms_abi in 64-bit mode.  */
> +      if (!TARGET_64BIT
> +         || !lookup_attribute ("preserve_none",
> +                               TYPE_ATTRIBUTES (fntype)))
> +       abi = MS_ABI;
>      }
>    else if (abi == MS_ABI
> -          && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
> +          && ((TARGET_64BIT
> +               && lookup_attribute ("preserve_none",             <<<<
> This is added.
> +                                    TYPE_ATTRIBUTES (fntype)))
> +              || lookup_attribute ("sysv_abi",
> +                                   TYPE_ATTRIBUTES (fntype))))
>      abi = SYSV_ABI;
>
>    return abi;

Routing everything through ix86_function_type_abi means a
preserve_none function under -mabi=ms now flips all
MS-vs-SYSV-keyed behavior to SYSV, not just argument registers:

- ix86_function_value / ix86_return_in_memory → SYSV return conventions
- STACK_BOUNDARY (via TARGET_64BIT_MS_ABI) → 64 instead of 128

Do they make sense?

+  return !cum->preserve_none_abi && cum->call_abi == MS_ABI;

Also !cum->preserve_none_abi seems redundant if we set abi  to
SYSV_ABI whenever preserve_none_abi exists.

>
> and tests.
>
> --
> H.J.
> ---
> In 64-bit mode, preserve_none attribute uses a different calling
> convention.  Ignore MS ABI with preserve_none attribute to always
> use the preserve_none calling convention with preserve_none
> attribute.
>
> gcc/
>
> PR target/125297
> * config/i386/i386.cc (ix86_function_arg_regno_p): Use
> x86_64_preserve_none_int_parameter_registers for
> TYPE_PRESERVE_NONE.
> (ix86_function_type_abi): In 64-bit mode, ignore ms_abi
> attribute with preserve_none attribute.
> (x86_64_cumulative_ms_abi_p): New function.
> (init_cumulative_args): Call x86_64_cumulative_ms_abi_p to
> decide if MS_ABI is used.
> (ix86_function_arg_advance): Likewise.
> (ix86_function_arg): Likewise.
> (ix86_pass_by_reference): Likewise.
> (ix86_setup_incoming_varargs): Likewise.
>
> gcc/testsuite/
>
> PR target/125297
> * gcc.target/i386/preserve-none-31a.c: New test.
> * gcc.target/i386/preserve-none-31b.c: Likewise.
> * gcc.target/i386/preserve-none-32a.c: Likewise.
> * gcc.target/i386/preserve-none-32b.c: Likewise.
> * gcc.target/i386/preserve-none-33a.c: Likewise.
> * gcc.target/i386/preserve-none-33b.c: Likewise.
> * gcc.target/i386/preserve-none-34a.c: Likewise.
> * gcc.target/i386/preserve-none-34b.c: Likewise.
> * gcc.target/i386/preserve-none-35a.c: Likewise.
> * gcc.target/i386/preserve-none-35b.c: Likewise.
> * gcc.target/i386/preserve-none-35c.c: Likewise.
> * gcc.target/i386/preserve-none-35d.c: Likewise.
> * gcc.target/i386/preserve-none-35e.c: Likewise.
> * gcc.target/i386/preserve-none-35f.c: Likewise.
> * gcc.target/i386/preserve-none-35g.c: Likewise.
> * gcc.target/i386/preserve-none-36a.c: Likewise.
> * gcc.target/i386/preserve-none-36b.c: Likewise.
> * gcc.target/i386/preserve-none-36c.c: Likewise.
> * gcc.target/i386/preserve-none-36d.c: Likewise.
> * gcc.target/i386/preserve-none-36e.c: Likewise.
> * gcc.target/i386/preserve-none-36f.c: Likewise.
> * gcc.target/i386/preserve-none-36g.c: Likewise.
> * gcc.target/i386/preserve-none-37a.c: Likewise.
> * gcc.target/i386/preserve-none-37b.c: Likewise.
> * gcc.target/i386/preserve-none-37c.c: Likewise.
> * gcc.target/i386/preserve-none-37d.c: Likewise.
> * gcc.target/i386/preserve-none-37e.c: Likewise.
> * gcc.target/i386/preserve-none-37f.c: Likewise.
> * gcc.target/i386/preserve-none-37g.c: Likewise.
> * gcc.target/i386/preserve-none-37h.c: Likewise.
> * gcc.target/i386/preserve-none-37i.c: Likewise.
> * gcc.target/i386/preserve-none-37j.c: Likewise.



-- 
BR,
Hongtao

Reply via email to