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.
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

Reply via email to