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.

-- 
H.J.
From 8740c4f1bc7ecbcfc99f11225d7ca3f467b659fe 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       | 14 ++++++++++++++
 .../gcc.target/x86_64/abi/ms-sysv/gen.cc          | 15 ++++-----------
 2 files changed, 18 insertions(+), 11 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..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
@@ -105,6 +105,20 @@ 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	$32, %rsp
+	addq	$16, %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..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
@@ -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,7 +402,8 @@ 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" : "")
+	  out << ") = (void*)" << (unaligned ? "call_" : "")
+	      << "do_test_" << (unaligned ? "un" : "")
 	      << "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