Re: [PATCH] ms-sysv: Add call_do_test_unaligned
"H.J. Lu" <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CAMe9rOoe51aitNTVHaVkQeWhAUwLFTnRhGRS7PUNiTu-ARrZUA@mail.gmail.com> |
On Wed, Aug 19, 2026 at 4:00 PM Uros Bizjak <[email protected]> wrote: > > On Tue, Aug 18, 2026 at 5:21 PM H.J. Lu <[email protected]> wrote: > > > > We can't use > > > > void > > test (long a, long b, long c, long d, long e) > > { > > ... > > __asm__ __volatile__ ("subq $8,%%rsp":::"cc"); > > ret = do_test_unaligned (a, b, c, d, e); > > __asm__ __volatile__ ("addq $8,%%rsp":::"cc"); > > ... > > } > > Uh, this violates GCC's inline-asm contract for %rsp. GCC requires the > stack pointer to have the identical value on exit from an asm as it > had on entry. > > > to call do_test_unaligned, which is marked with ms_abi attribute, with > > an unaligned stack since GCC may save a function argument on stack and > > retrieve it from stack to pass it to do_test_unaligned. When it happens, > > stack adjustment in asm statements can lead to a random value in the > > outgoing argument. Add an assembly function, call_do_test_unaligned, to > > call do_test_unaligned with an unaligned stack. > > > > PR testsuite/126927 > > * gcc.target/x86_64/abi/ms-sysv/do-test.S (call_do_test_unaligned): > > New. > > * gcc.target/x86_64/abi/ms-sysv/gen.cc (make_do_tests_decl): > > Replace do_test_unaligned with call_do_test_unaligned. > > (make_do_test): Remove asm statements with stack adjustment. > > OK with a couple of simplifications below. > > Thanks, > Uros. > > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S > b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S > index 9bc108b3e98..7432994bc95 100644 > --- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S > +++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S > > +FUNC_BEGIN(call_do_test_unaligned) > + # Load the 5th argument to R10. > + movq 0x28(%rsp), %r10 > + # Unalign stack. > + subq $8, %rsp > + # Push the 5th argument. > + pushq %r10 > + subq $32, %rsp > + call do_test_unaligned > + addq $32, %rsp > + addq $16, %rsp > > addq $48, %rsp Fixed. > + ret > +FUNC_END(call_do_test_unaligned) > > diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc > b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc > index 818a8875a6d..ceade25cd29 100644 > --- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc > +++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc > > - out << ") = (void*)do_test_" << (unaligned ? "un" : "") > + out << ") = (void*)" << (unaligned ? "call_" : "") > + << "do_test_" << (unaligned ? "un" : "") > << "aligned;" << endl; > > out << ") = (void*)" << (unaligned ? "call_do_test_unaligned" : > "do_test_aligned") > << ";" << endl; Fixed. This is the patch I am checking in. -- H.J.
0001-ms-sysv-Add-call_do_test_unaligned.patch
(text/x-patch, 4.3 KB)
From 27f9709decac0eccf5bc8d856f22f22ce89ddb36 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <[email protected]> Date: Tue, 18 Aug 2026 22:55:38 +0800 Subject: [PATCH] ms-sysv: Add call_do_test_unaligned We can't use void test (long a, long b, long c, long d, long e) { ... __asm__ __volatile__ ("subq $8,%%rsp":::"cc"); ret = do_test_unaligned (a, b, c, d, e); __asm__ __volatile__ ("addq $8,%%rsp":::"cc"); ... } to call do_test_unaligned, which is marked with ms_abi attribute, with an unaligned stack since GCC may save a function argument on stack and retrieve it from stack to pass it to do_test_unaligned. When it happens, stack adjustment in asm statements can lead to a random value in the outgoing argument. Add an assembly function, call_do_test_unaligned, to call do_test_unaligned with an unaligned stack. PR testsuite/126927 * gcc.target/x86_64/abi/ms-sysv/do-test.S (call_do_test_unaligned): New. * gcc.target/x86_64/abi/ms-sysv/gen.cc (make_do_tests_decl): Replace do_test_unaligned with call_do_test_unaligned. (make_do_test): Remove asm statements with stack adjustment. Signed-off-by: H.J. Lu <[email protected]> --- .../gcc.target/x86_64/abi/ms-sysv/do-test.S | 13 +++++++++++++ .../gcc.target/x86_64/abi/ms-sysv/gen.cc | 17 +++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S index 9bc108b3e98..c0268f97455 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S @@ -105,6 +105,19 @@ FUNC_BEGIN(mem_to_regs) retq FUNC_END(mem_to_regs) +FUNC_BEGIN(call_do_test_unaligned) + # Load the 5th argument to R10. + movq 0x28(%rsp), %r10 + # Unalign stack. + subq $8, %rsp + # Push the 5th argument. + pushq %r10 + subq $32, %rsp + call do_test_unaligned + addq $48, %rsp + ret +FUNC_END(call_do_test_unaligned) + # NOTE: Not MT safe FUNC_BEGIN(do_test_unaligned) # The below alignment checks are to verify correctness of the test diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc index 818a8875a6d..5a584b7c941 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc +++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc @@ -372,7 +372,7 @@ vector<class fn*> sysv_funcs; vector<class fn*> msabi_funcs; -/* Emit extern for do_test_aligned and do_test_unaligned (defined in do_test.S) +/* Emit extern for do_test_aligned and call_do_test_unaligned (defined in do_test.S) followed by all of the various do_test* function function pointers that are just aliases of them. */ static void make_do_tests_decl (const vector<class arg> &args, ostream &out) @@ -381,7 +381,7 @@ static void make_do_tests_decl (const vector<class arg> &args, ostream &out) unsigned i, varargs, unaligned; out << "extern __attribute__ ((ms_abi)) long do_test_aligned ();" << endl - << "extern __attribute__ ((ms_abi)) long do_test_unaligned ();" << endl; + << "extern __attribute__ ((ms_abi)) long call_do_test_unaligned ();" << endl; list_delimiter comma (", "); for (i = extra_params_min; i <= args.size (); ++i) @@ -402,8 +402,9 @@ static void make_do_tests_decl (const vector<class arg> &args, ostream &out) << ai->get_name (); if (varargs) out << comma.get () << "..."; - out << ") = (void*)do_test_" << (unaligned ? "un" : "") - << "aligned;" << endl; + out << ") = (void*)" << (unaligned + ? "call_do_test_unaligned;" + : "do_test_aligned;") << endl; } } @@ -510,10 +511,6 @@ void make_do_test (const vector<class arg> &args, out << ");" << endl; /* End if init_test call. */ - if (f.get_realign () && unaligned == 1) - out << " __asm__ __volatile__ (\"subq $8,%%rsp\":::\"cc\");" - << endl; - out << " ret = do_test_" << (f.get_realign () && unaligned == 1 ? "u" : "") << (f.get_varargs () ? "v" : "") @@ -524,10 +521,6 @@ void make_do_test (const vector<class arg> &args, out << comma.get () << arg.get_name (); out << ");" << endl; - if (f.get_realign () && unaligned == 1) - out << " __asm__ __volatile__ (\"addq $8,%%rsp\":::\"cc\");" - << endl; - out << " check_results (ret);" << endl; } } -- 2.55.0