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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.