declared return type prevents tail call

Bug #2039301 reported by Gábor Melis
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

In the following example, the funcall is compiled as a tail call but not if the caller's return type is declared although the callee's and caller's return types are the same. I would expect both to be tail calls although clearly it's not mandated by the spec.

Tested on linux x86-64 with sbcl commit 8c119e5a4 (latest as of today).

CL-USER> (defun fff (fn x)
           (declare (type (function (t) (values fixnum &optional)) fn)
                    (optimize (safety 0)))
           (funcall fn x))
FFF
CL-USER> (disassemble 'fff)
; disassembly for FFF
; Size: 25 bytes. Origin: #x53667E78 ; FFF
; 78: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; 7C: 488945F8 MOV [RBP-8], RAX
; 80: 488BD7 MOV RDX, RDI
; 83: 488BC6 MOV RAX, RSI
; 86: B902000000 MOV ECX, 2
; 8B: FF7508 PUSH QWORD PTR [RBP+8]
; 8E: FF60FD JMP [RAX-3]
NIL
CL-USER> (declaim (ftype (function (t t) (values fixnum &optional)) fff))
(FFF)
CL-USER> (defun fff (fn x)
           (declare (type (function (t) (values fixnum &optional)) fn)
                    (optimize (safety 0)))
           (funcall fn x))
WARNING: redefining COMMON-LISP-USER::FFF in DEFUN
FFF
CL-USER> (disassemble 'fff)
; disassembly for FFF
; Size: 44 bytes. Origin: #x53667F21 ; FFF
; 21: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; 25: 488945F8 MOV [RBP-8], RAX
; 29: 4883EC10 SUB RSP, 16
; 2D: 488BD7 MOV RDX, RDI
; 30: 498BC0 MOV RAX, R8
; 33: B902000000 MOV ECX, 2
; 38: 48892C24 MOV [RSP], RBP
; 3C: 488BEC MOV RBP, RSP
; 3F: FF50FD CALL [RAX-3]
; 42: 4C8B45E8 MOV R8, [RBP-24]
; 46: 488B7DF0 MOV RDI, [RBP-16]
; 4A: C9 LEAVE
; 4B: F8 CLC
; 4C: C3 RET

Revision history for this message
Paul F. Dietz (paul-f-dietz) wrote (last edit ):

If you also declare (optimize (debug 0)) the tail call is converted to a jump.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.