@@ -21,3 +21,77 @@ define i32 @test_musttail_args(i32 %x, i32 %y, i32 %z) {
2121 %ret = musttail call i32 @callee_args (i32 %x , i32 %y , i32 %z )
2222 ret i32 %ret
2323}
24+
25+ ; Test musttail with many arguments that spill to stack (involves memory)
26+ ; MIPS O32 ABI: first 4 args in $a0-$a3, rest on stack
27+ declare i32 @many_args_callee (i32 %a , i32 %b , i32 %c , i32 %d , i32 %e , i32 %f , i32 %g , i32 %h )
28+
29+ define i32 @test_musttail_many_args (i32 %a , i32 %b , i32 %c , i32 %d , i32 %e , i32 %f , i32 %g , i32 %h ) {
30+ ; MIPS32-LABEL: test_musttail_many_args:
31+ ; MIPS32: # %bb.0:
32+ ; MIPS32-NEXT: lw $1, 24($sp)
33+ ; MIPS32-NEXT: lw $2, 20($sp)
34+ ; MIPS32-NEXT: lw $3, 16($sp)
35+ ; MIPS32-NEXT: sw $3, 16($sp)
36+ ; MIPS32-NEXT: sw $2, 20($sp)
37+ ; MIPS32-NEXT: sw $1, 24($sp)
38+ ; MIPS32-NEXT: lw $1, 28($sp)
39+ ; MIPS32-NEXT: j many_args_callee
40+ ; MIPS32-NEXT: sw $1, 28($sp)
41+ ;
42+ ; MIPS64-LABEL: test_musttail_many_args:
43+ ; MIPS64: # %bb.0:
44+ ; MIPS64-NEXT: j many_args_callee
45+ ; MIPS64-NEXT: nop
46+ %ret = musttail call i32 @many_args_callee (i32 %a , i32 %b , i32 %c , i32 %d , i32 %e , i32 %f , i32 %g , i32 %h )
47+ ret i32 %ret
48+ }
49+
50+ ; Test musttail with large struct passed by value (involves memory)
51+ %struct.large = type { i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 }
52+
53+ declare i32 @callee_with_struct (%struct.large %s , i32 %x )
54+
55+ define i32 @test_musttail_struct (%struct.large %s , i32 %x ) {
56+ ; MIPS32-LABEL: test_musttail_struct:
57+ ; MIPS32: # %bb.0:
58+ ; MIPS32-NEXT: lw $1, 28($sp)
59+ ; MIPS32-NEXT: lw $2, 24($sp)
60+ ; MIPS32-NEXT: lw $3, 20($sp)
61+ ; MIPS32-NEXT: lw $8, 16($sp)
62+ ; MIPS32-NEXT: sw $8, 16($sp)
63+ ; MIPS32-NEXT: sw $3, 20($sp)
64+ ; MIPS32-NEXT: sw $2, 24($sp)
65+ ; MIPS32-NEXT: sw $1, 28($sp)
66+ ; MIPS32-NEXT: lw $1, 32($sp)
67+ ; MIPS32-NEXT: j callee_with_struct
68+ ; MIPS32-NEXT: sw $1, 32($sp)
69+ ;
70+ ; MIPS64-LABEL: test_musttail_struct:
71+ ; MIPS64: # %bb.0:
72+ ; MIPS64-NEXT: ld $1, 0($sp)
73+ ; MIPS64-NEXT: j callee_with_struct
74+ ; MIPS64-NEXT: sd $1, 0($sp)
75+ %ret = musttail call i32 @callee_with_struct (%struct.large %s , i32 %x )
76+ ret i32 %ret
77+ }
78+
79+ ; Test musttail with mixed int and float arguments that use stack
80+ declare float @mixed_args_callee (i32 %a , float %b , i32 %c , float %d , i32 %e , float %f )
81+
82+ define float @test_musttail_mixed_args (i32 %a , float %b , i32 %c , float %d , i32 %e , float %f ) {
83+ ; MIPS32-LABEL: test_musttail_mixed_args:
84+ ; MIPS32: # %bb.0:
85+ ; MIPS32-NEXT: lw $1, 16($sp)
86+ ; MIPS32-NEXT: sw $1, 16($sp)
87+ ; MIPS32-NEXT: lwc1 $f0, 20($sp)
88+ ; MIPS32-NEXT: j mixed_args_callee
89+ ; MIPS32-NEXT: swc1 $f0, 20($sp)
90+ ;
91+ ; MIPS64-LABEL: test_musttail_mixed_args:
92+ ; MIPS64: # %bb.0:
93+ ; MIPS64-NEXT: j mixed_args_callee
94+ ; MIPS64-NEXT: nop
95+ %ret = musttail call float @mixed_args_callee (i32 %a , float %b , i32 %c , float %d , i32 %e , float %f )
96+ ret float %ret
97+ }
0 commit comments