https://gcc.gnu.org/g:82a07ea30aa3a2442dcb0f3e2c9ff073a2c475e7

commit r17-3973-g82a07ea30aa3a2442dcb0f3e2c9ff073a2c475e7
Author: Andrew Stubbs <[email protected]>
Date:   Mon Aug 24 16:10:13 2026 +0000

    amdgcn: Spill scalars to SGPRS, not AVGPRs
    
    Scalars located in VGPRs can be safely spilled to either AVGPRs or SGPRs,
    but the AVGPRs are a much more limited resource, and are also much more
    expensive to save around calls, so we should prefer to use SGPRs where we 
can.
    
    SGPR spills will also work on devices that do not have AVGPRs.
    
    The existing testcases for AVGPR spills were using scalars, and therefore
    FAILed, so we change them to use vectors, and add new testcases for the 
scalar
    case.
    
    gcc/ChangeLog:
    
            * config/gcn/gcn.cc (gcn_spill_class): Spill scalars to SGPRs.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/gcn/avgpr-spill-double.c: Switch to vector type.
            * gcc.target/gcn/avgpr-spill-int.c: Likewise.
            * gcc.target/gcn/avgpr-spill-long.c: Likewise.
            * gcc.target/gcn/avgpr-spill-short.c: Likewise.
            * gcc.target/gcn/sgpr-spill-double.c: New test.
            * gcc.target/gcn/sgpr-spill-int.c: New test.
            * gcc.target/gcn/sgpr-spill-long.c: New test.
            * gcc.target/gcn/sgpr-spill-short.c: New test.

Diff:
---
 gcc/config/gcn/gcn.cc                             |  8 ++++++--
 gcc/testsuite/gcc.target/gcn/avgpr-spill-double.c |  3 ++-
 gcc/testsuite/gcc.target/gcn/avgpr-spill-int.c    |  3 ++-
 gcc/testsuite/gcc.target/gcn/avgpr-spill-long.c   |  3 ++-
 gcc/testsuite/gcc.target/gcn/avgpr-spill-short.c  |  3 ++-
 gcc/testsuite/gcc.target/gcn/sgpr-spill-double.c  | 10 ++++++++++
 gcc/testsuite/gcc.target/gcn/sgpr-spill-int.c     | 12 ++++++++++++
 gcc/testsuite/gcc.target/gcn/sgpr-spill-long.c    | 10 ++++++++++
 gcc/testsuite/gcc.target/gcn/sgpr-spill-short.c   | 10 ++++++++++
 9 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index ed27acfb8a16..bbeaef3f9271 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -854,13 +854,17 @@ gcn_can_split_p (machine_mode, rtx op)
    if it is not possible or non-profitable.  */
 
 static reg_class_t
-gcn_spill_class (reg_class_t c, machine_mode /*mode */ )
+gcn_spill_class (reg_class_t c, machine_mode mode)
 {
   if (reg_classes_intersect_p (ALL_CONDITIONAL_REGS, c)
       || c == VCC_CONDITIONAL_REG || c == EXEC_MASK_REG)
     return SGPR_REGS;
+  else if (c == VGPR_REGS && !VECTOR_MODE_P (mode))
+    return SGPR_REGS;
+  else if (c == VGPR_REGS && TARGET_AVGPRS)
+    return AVGPR_REGS;
   else
-    return c == VGPR_REGS && TARGET_AVGPRS ? AVGPR_REGS : NO_REGS;
+    return NO_REGS;
 }
 
 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS.
diff --git a/gcc/testsuite/gcc.target/gcn/avgpr-spill-double.c 
b/gcc/testsuite/gcc.target/gcn/avgpr-spill-double.c
index 53853a4b0757..3015f8ec6bb8 100644
--- a/gcc/testsuite/gcc.target/gcn/avgpr-spill-double.c
+++ b/gcc/testsuite/gcc.target/gcn/avgpr-spill-double.c
@@ -2,6 +2,7 @@
 /* { dg-additional-options "-march=gfx908 -O1" } */
 /* { dg-final { scan-assembler "accvgpr" } } */
 
-#define TYPE double
+typedef double v32df __attribute__ ((__vector_size__ (sizeof(double)*32)));
+#define TYPE v32df
 
 #include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/avgpr-spill-int.c 
b/gcc/testsuite/gcc.target/gcn/avgpr-spill-int.c
index 650f1587a1bb..462d67417c37 100644
--- a/gcc/testsuite/gcc.target/gcn/avgpr-spill-int.c
+++ b/gcc/testsuite/gcc.target/gcn/avgpr-spill-int.c
@@ -2,8 +2,9 @@
 /* { dg-additional-options "-march=gfx908 -O1" } */
 /* { dg-final { scan-assembler "accvgpr" } } */
 
+typedef int v32si __attribute__ ((__vector_size__ (sizeof(int)*32)));
 #ifndef TYPE
-#define TYPE int
+#define TYPE v32si
 #endif
 
 TYPE a[50];
diff --git a/gcc/testsuite/gcc.target/gcn/avgpr-spill-long.c 
b/gcc/testsuite/gcc.target/gcn/avgpr-spill-long.c
index 51f887c4d59e..1926fd9df0b4 100644
--- a/gcc/testsuite/gcc.target/gcn/avgpr-spill-long.c
+++ b/gcc/testsuite/gcc.target/gcn/avgpr-spill-long.c
@@ -2,6 +2,7 @@
 /* { dg-additional-options "-march=gfx908 -O1" } */
 /* { dg-final { scan-assembler "accvgpr" } } */
 
-#define TYPE long
+typedef long v32di __attribute__ ((__vector_size__ (sizeof(long)*32)));
+#define TYPE v32di
 
 #include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/avgpr-spill-short.c 
b/gcc/testsuite/gcc.target/gcn/avgpr-spill-short.c
index 983d2017ff5f..71032e7674fd 100644
--- a/gcc/testsuite/gcc.target/gcn/avgpr-spill-short.c
+++ b/gcc/testsuite/gcc.target/gcn/avgpr-spill-short.c
@@ -2,6 +2,7 @@
 /* { dg-additional-options "-march=gfx908 -O1" } */
 /* { dg-final { scan-assembler "accvgpr" } } */
 
-#define TYPE short
+typedef short v32hi __attribute__ ((__vector_size__ (sizeof(short)*32)));
+#define TYPE v32hi
 
 #include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/sgpr-spill-double.c 
b/gcc/testsuite/gcc.target/gcn/sgpr-spill-double.c
new file mode 100644
index 000000000000..6757a19d8c9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/sgpr-spill-double.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=gfx908 -O1" } */
+/* { dg-final { scan-assembler-not "accvgpr" } } */
+
+/* Function epilogues use v6, but other registers may be a spill.  */
+/* { dg-final { scan-assembler "v_readlane.+, v\[12345789]" } } */
+
+#define TYPE double
+
+#include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/sgpr-spill-int.c 
b/gcc/testsuite/gcc.target/gcn/sgpr-spill-int.c
new file mode 100644
index 000000000000..aed29442ce2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/sgpr-spill-int.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=gfx908 -O1" } */
+/* { dg-final { scan-assembler-not "accvgpr" } } */
+
+/* Function epilogues use v6, but other registers may be a spill.  */
+/* { dg-final { scan-assembler "v_readlane.+, v\[12345789]" } } */
+
+#ifndef TYPE
+#define TYPE int
+#endif
+
+#include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/sgpr-spill-long.c 
b/gcc/testsuite/gcc.target/gcn/sgpr-spill-long.c
new file mode 100644
index 000000000000..248624381b8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/sgpr-spill-long.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=gfx908 -O1" } */
+/* { dg-final { scan-assembler-not "accvgpr" } } */
+
+/* Function epilogues use v6, but other registers may be a spill.  */
+/* { dg-final { scan-assembler "v_readlane.+, v\[12345789]" } } */
+
+#define TYPE long
+
+#include "avgpr-spill-int.c"
diff --git a/gcc/testsuite/gcc.target/gcn/sgpr-spill-short.c 
b/gcc/testsuite/gcc.target/gcn/sgpr-spill-short.c
new file mode 100644
index 000000000000..35bd0d560895
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/sgpr-spill-short.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=gfx908 -O1" } */
+/* { dg-final { scan-assembler-not "accvgpr" } } */
+
+/* Function epilogues use v6, but other registers may be a spill.  */
+/* { dg-final { scan-assembler "v_readlane.+, v\[12345789]" } } */
+
+#define TYPE short
+
+#include "avgpr-spill-int.c"

Reply via email to