xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/musttail.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=x86 < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=x86 -O0 < %s | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=x86 -disable-tail-calls < %s | FileCheck %s
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdeclare void @t1_callee(i8*)
6*9880d681SAndroid Build Coastguard Workerdefine void @t1(i32* %a) {
7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t1:
8*9880d681SAndroid Build Coastguard Worker; CHECK: jmp {{_?}}t1_callee
9*9880d681SAndroid Build Coastguard Worker  %b = bitcast i32* %a to i8*
10*9880d681SAndroid Build Coastguard Worker  musttail call void @t1_callee(i8* %b)
11*9880d681SAndroid Build Coastguard Worker  ret void
12*9880d681SAndroid Build Coastguard Worker}
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerdeclare i8* @t2_callee()
15*9880d681SAndroid Build Coastguard Workerdefine i32* @t2() {
16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t2:
17*9880d681SAndroid Build Coastguard Worker; CHECK: jmp {{_?}}t2_callee
18*9880d681SAndroid Build Coastguard Worker  %v = musttail call i8* @t2_callee()
19*9880d681SAndroid Build Coastguard Worker  %w = bitcast i8* %v to i32*
20*9880d681SAndroid Build Coastguard Worker  ret i32* %w
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; Complex frame layout: stack realignment with dynamic alloca.
24*9880d681SAndroid Build Coastguard Workerdefine void @t3(i32 %n) alignstack(32) nounwind {
25*9880d681SAndroid Build Coastguard Workerentry:
26*9880d681SAndroid Build Coastguard Worker; CHECK: t3:
27*9880d681SAndroid Build Coastguard Worker; CHECK: pushl %ebp
28*9880d681SAndroid Build Coastguard Worker; CHECK: pushl %esi
29*9880d681SAndroid Build Coastguard Worker; CHECK: andl $-32, %esp
30*9880d681SAndroid Build Coastguard Worker; CHECK: movl %esp, %esi
31*9880d681SAndroid Build Coastguard Worker; CHECK: popl %esi
32*9880d681SAndroid Build Coastguard Worker; CHECK: popl %ebp
33*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp {{_?}}t3_callee
34*9880d681SAndroid Build Coastguard Worker  %a = alloca i8, i32 %n
35*9880d681SAndroid Build Coastguard Worker  call void @capture(i8* %a)
36*9880d681SAndroid Build Coastguard Worker  musttail call void @t3_callee(i32 %n) nounwind
37*9880d681SAndroid Build Coastguard Worker  ret void
38*9880d681SAndroid Build Coastguard Worker}
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Workerdeclare void @capture(i8*)
41*9880d681SAndroid Build Coastguard Workerdeclare void @t3_callee(i32)
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; Test that we actually copy in and out stack arguments that aren't forwarded
44*9880d681SAndroid Build Coastguard Worker; without modification.
45*9880d681SAndroid Build Coastguard Workerdefine i32 @t4({}* %fn, i32 %n, i32 %r) {
46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t4:
47*9880d681SAndroid Build Coastguard Worker; CHECK: incl %[[r:.*]]
48*9880d681SAndroid Build Coastguard Worker; CHECK: decl %[[n:.*]]
49*9880d681SAndroid Build Coastguard Worker; CHECK: movl %[[r]], {{[0-9]+}}(%esp)
50*9880d681SAndroid Build Coastguard Worker; CHECK: movl %[[n]], {{[0-9]+}}(%esp)
51*9880d681SAndroid Build Coastguard Worker; CHECK: jmpl *%{{.*}}
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerentry:
54*9880d681SAndroid Build Coastguard Worker  %r1 = add i32 %r, 1
55*9880d681SAndroid Build Coastguard Worker  %n1 = sub i32 %n, 1
56*9880d681SAndroid Build Coastguard Worker  %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)*
57*9880d681SAndroid Build Coastguard Worker  %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1)
58*9880d681SAndroid Build Coastguard Worker  ret i32 %r2
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; Combine the complex stack frame with the parameter modification.
62*9880d681SAndroid Build Coastguard Workerdefine i32 @t5({}* %fn, i32 %n, i32 %r) alignstack(32) {
63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t5:
64*9880d681SAndroid Build Coastguard Worker; CHECK: pushl %ebp
65*9880d681SAndroid Build Coastguard Worker; CHECK: movl %esp, %ebp
66*9880d681SAndroid Build Coastguard Worker; CHECK: pushl %esi
67*9880d681SAndroid Build Coastguard Worker; 	Align the stack.
68*9880d681SAndroid Build Coastguard Worker; CHECK: andl $-32, %esp
69*9880d681SAndroid Build Coastguard Worker; CHECK: movl %esp, %esi
70*9880d681SAndroid Build Coastguard Worker; 	Modify the args.
71*9880d681SAndroid Build Coastguard Worker; CHECK: incl %[[r:.*]]
72*9880d681SAndroid Build Coastguard Worker; CHECK: decl %[[n:.*]]
73*9880d681SAndroid Build Coastguard Worker; 	Store them through ebp, since that's the only stable arg pointer.
74*9880d681SAndroid Build Coastguard Worker; CHECK: movl %[[r]], {{[0-9]+}}(%ebp)
75*9880d681SAndroid Build Coastguard Worker; CHECK: movl %[[n]], {{[0-9]+}}(%ebp)
76*9880d681SAndroid Build Coastguard Worker; 	Epilogue.
77*9880d681SAndroid Build Coastguard Worker; CHECK: leal {{[-0-9]+}}(%ebp), %esp
78*9880d681SAndroid Build Coastguard Worker; CHECK: popl %esi
79*9880d681SAndroid Build Coastguard Worker; CHECK: popl %ebp
80*9880d681SAndroid Build Coastguard Worker; CHECK: jmpl *%{{.*}}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerentry:
83*9880d681SAndroid Build Coastguard Worker  %a = alloca i8, i32 %n
84*9880d681SAndroid Build Coastguard Worker  call void @capture(i8* %a)
85*9880d681SAndroid Build Coastguard Worker  %r1 = add i32 %r, 1
86*9880d681SAndroid Build Coastguard Worker  %n1 = sub i32 %n, 1
87*9880d681SAndroid Build Coastguard Worker  %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)*
88*9880d681SAndroid Build Coastguard Worker  %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1)
89*9880d681SAndroid Build Coastguard Worker  ret i32 %r2
90*9880d681SAndroid Build Coastguard Worker}
91