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
