aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2025-03-09 07:00:23 -0700
committerH.J. Lu <hjl.tools@gmail.com>2025-03-11 05:30:57 -0700
commit06440e726acfa9c9695a07dc524a832a53057ad6 (patch)
tree5c888ce929b08f81d883136a8ea1012754ca6568 /gcc
parent86eb3fb520b2a2026f6816ab51b88180b85d6882 (diff)
downloadgcc-06440e726acfa9c9695a07dc524a832a53057ad6.zip
gcc-06440e726acfa9c9695a07dc524a832a53057ad6.tar.gz
gcc-06440e726acfa9c9695a07dc524a832a53057ad6.tar.bz2
i386: Verify that argument registers are spilled properly
While working on a local x86 patch, which passed the GCC testsuite, I got a compiler error: In function ‘paravirt_read_msr’, inlined from ‘perf_ibs_handle_irq’ at arch/x86/events/amd/ibs.c:1055:2: ./arch/x86/include/asm/paravirt_types.h:397:17: error: ‘asm’ operand has impossible constraints or there are not enough registers 397 | asm volatile(ALTERNATIVE(PARAVIRT_CALL, ALT_CALL_INSTR, \ | ^~~ when building x86-64 Linux kernel. RDI, RSI, RDX and RCX registers are used to pass arguments in 64-bit mode. EAX, EDX and ECX registers are used to pass arguments in 32-bit mode. But there is no coverage in the GCC testsuite. Add tests to verify that argument registers are spilled properly. PR target/119171 * gcc.target/i386/pr119171-1.c: New test. * gcc.target/i386/pr119171-2.c: Likewise. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119171-1.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119171-2.c13
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/i386/pr119171-1.c b/gcc/testsuite/gcc.target/i386/pr119171-1.c
new file mode 100644
index 0000000..a017e6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119171-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+extern long a1, a2, a3, a4;
+extern void foo (void *, void *, void *, void *);
+void
+bar (void *rdi, void *rsi, void *rdx, void *rcx)
+{
+ asm ("" : "=D"(a1) : "D"(0));
+ asm ("" : "=S"(a2) : "S"(0));
+ asm ("" : "=d"(a3) : "d"(0));
+ asm ("" : "=c"(a4) : "c"(0));
+ foo (rdi, rsi, rdx, rcx);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr119171-2.c b/gcc/testsuite/gcc.target/i386/pr119171-2.c
new file mode 100644
index 0000000..5c209f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119171-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mregparm=3" } */
+
+extern long a1, a2, a3;
+extern void foo (void *, void *, void *);
+void
+bar (void *eax, void *edx, void *ecx)
+{
+ asm ("" : "=a"(a1) : "a"(0));
+ asm ("" : "=d"(a2) : "d"(0));
+ asm ("" : "=c"(a3) : "c"(0));
+ foo (eax, edx, ecx);
+}