master: x86-64, struct-by-value: correctly pass small structs on the stack

stassats via Sbcl-commits <[email protected]>
Newsgroups gmane.lisp.steel-bank.cvs
Message-ID <[email protected]>
The branch "master" has been updated in SBCL:
       via  2c30eafc7e483a873b46edfcf3346e0c4a17cf4e (commit)
      from  0e7a0d79815c34cca6a0e0f294529b25a21dbde8 (commit)

- Log -----------------------------------------------------------------
commit 2c30eafc7e483a873b46edfcf3346e0c4a17cf4e
Author: Stas Boukarev <[email protected]>
Date:   Thu Apr 23 10:50:34 2026 +0300

    x86-64, struct-by-value: correctly pass small structs on the stack
---
 src/compiler/x86-64/c-call.lisp | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/compiler/x86-64/c-call.lisp b/src/compiler/x86-64/c-call.lisp
index 4ef45a199..80a8a3385 100644
--- a/src/compiler/x86-64/c-call.lisp
+++ b/src/compiler/x86-64/c-call.lisp
@@ -376,8 +376,20 @@ Floats are passed in integer registers."
   "Handle struct arguments.
    For large structs (>16 bytes), copies to stack per System V AMD64 ABI.
    For small structs, returns a function that emits load VOPs into registers."
-  (let ((classification (classify-struct type)))
-    (if (sb-alien::struct-classification-memory-p classification)
+  (let* ((classification (classify-struct type))
+         (slots (sb-alien::struct-classification-register-slots classification)))
+    (if (or (sb-alien::struct-classification-memory-p classification)
+            (let (stack
+                  (n-int (count :integer slots))
+                  (n-fp (+ (count :single slots) (count :double slots))))
+              ;; Don't split between registers/stack
+              (when (> (+ (arg-state-register-args state) n-int) max-int-args)
+                (setf (arg-state-register-args state) max-int-args
+                      stack t))
+              (when (> (+ (arg-state-xmm-args state) n-fp) max-xmm-args)
+                (setf (arg-state-xmm-args state) max-xmm-args
+                      stack t))
+              stack))
         ;; Large struct: copy to stack (System V AMD64 ABI)
         ;; The struct is passed by value on the stack, not by pointer
         (let* ((size (sb-alien::struct-classification-size classification))
@@ -402,7 +414,7 @@ Floats are passed in integer registers."
         (let ((arg-tns nil)
               (offsets nil)
               (offset 0))
-          (dolist (class (sb-alien::struct-classification-register-slots classification))
+          (dolist (class slots)
             (case class
               (:integer
                (push (int-arg state 'unsigned-byte-64

-----------------------------------------------------------------------


hooks/post-receive
-- 
SBCL
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.