Open
Description
Given x.ll
%t = type { i64, i64 }
declare %t @f()
define private %t @g() {
entry:
%0 = musttail call %t @f()
ret %t %0
}
the WebAssembly backend does not generate a return_call
but a plain call
, thus growing the stack.
I'm using LLVM 20.1.2 with the invocation llc-20 -mattr=+multivalue,+tail-call -mtriple=wasm64-unknown-unknown --filetype=asm -o x.wat x.ll
, but the same issue arises on wasm32
and without multivalue
enabled.
When changing the type to %t = type i64
, return_call
is used as expected.
The (faulty) generated WebAssembly for the module above is:
.file "x.ll"
.globaltype __stack_pointer, i64
.functype f (i64) -> ()
.functype .Lg (i64) -> ()
.section .text..Lg,"",@
.type .Lg,@function # -- Begin function g
.Lg: # @g
.functype .Lg (i64) -> ()
.local i64, i64
# %bb.0: # %entry
global.get __stack_pointer
i64.const 16
i64.sub
local.tee 1
global.set __stack_pointer
local.get 1
call f
local.get 1
i64.load 0
local.set 2
local.get 0
local.get 1
i64.load 8
i64.store 8
local.get 0
local.get 2
i64.store 0
local.get 1
i64.const 16
i64.add
global.set __stack_pointer
# fallthrough-return
end_function
# -- End function
.section .custom_section.target_features,"",@
.int8 10
.int8 43
.int8 11
.ascii "bulk-memory"
.int8 43
.int8 15
.ascii "bulk-memory-opt"
.int8 43
.int8 22
.ascii "call-indirect-overlong"
.int8 43
.int8 10
.ascii "multivalue"
.int8 43
.int8 15
.ascii "mutable-globals"
.int8 43
.int8 19
.ascii "nontrapping-fptoint"
.int8 43
.int8 15
.ascii "reference-types"
.int8 43
.int8 8
.ascii "sign-ext"
.int8 43
.int8 9
.ascii "tail-call"
.int8 43
.int8 8
.ascii "memory64"
.section .text..Lg,"",@
Note that this is a regression: LLVM 18 would generate a return_call
:
.Lg: # @g
.functype .Lg () -> (i64, i64)
# %bb.0: # %entry
return_call f
end_function