[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / PowerPC / pcrel-tail-calls.ll
blob583e7950b6d536dd473cdac58636f245a9b6a5c0
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
3 ; RUN:   -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
4 ; RUN:   FileCheck %s
5 ; RUN: llc -verify-machineinstrs -target-abi=elfv2 -mtriple=powerpc64-- \
6 ; RUN:   -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
7 ; RUN:   FileCheck %s
10 ; The tests check the behaviour of PC Relative tail calls. When using
11 ; PC Relative we are able to do more tail calling than we have done in
12 ; the past as we no longer need to restore the TOC pointer into R2 after
13 ; most calls.
15 @Func = external local_unnamed_addr global i32 (...)*, align 8
16 @FuncLocal = common dso_local local_unnamed_addr global i32 (...)* null, align 8
18 ; No calls in this function but we assign the function pointers.
19 define dso_local void @AssignFuncPtr() local_unnamed_addr {
20 ; CHECK-LABEL: AssignFuncPtr:
21 ; CHECK:       # %bb.0: # %entry
22 ; CHECK-NEXT:    pld r3, Func@got@pcrel(0), 1
23 ; CHECK-NEXT:    pld r4, Function@got@pcrel(0), 1
24 ; CHECK-NEXT:    std r4, 0(r3)
25 ; CHECK-NEXT:    pstd r4, FuncLocal@PCREL(0), 1
26 ; CHECK-NEXT:    blr
27 entry:
28   store i32 (...)* @Function, i32 (...)** @Func, align 8
29   store i32 (...)* @Function, i32 (...)** @FuncLocal, align 8
30   ret void
33 declare signext i32 @Function(...)
35 define dso_local void @TailCallLocalFuncPtr() local_unnamed_addr {
36 ; CHECK-LABEL: TailCallLocalFuncPtr:
37 ; CHECK:         .localentry TailCallLocalFuncPtr, 1
38 ; CHECK-NEXT:  # %bb.0: # %entry
39 ; CHECK-NEXT:    pld r12, FuncLocal@PCREL(0), 1
40 ; CHECK-NEXT:    mtctr r12
41 ; CHECK-NEXT:    bctr
42 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
43 entry:
44   %0 = load i32 ()*, i32 ()** bitcast (i32 (...)** @FuncLocal to i32 ()**), align 8
45   %call = tail call signext i32 %0()
46   ret void
49 define dso_local void @TailCallExtrnFuncPtr() local_unnamed_addr {
50 ; CHECK-LABEL: TailCallExtrnFuncPtr:
51 ; CHECK:         .localentry TailCallExtrnFuncPtr, 1
52 ; CHECK-NEXT:  # %bb.0: # %entry
53 ; CHECK-NEXT:    pld r3, Func@got@pcrel(0), 1
54 ; CHECK-NEXT:  .Lpcrel0:
55 ; CHECK-NEXT:    .reloc .Lpcrel0-8,R_PPC64_PCREL_OPT,.-(.Lpcrel0-8)
56 ; CHECK-NEXT:    ld r12, 0(r3)
57 ; CHECK-NEXT:    mtctr r12
58 ; CHECK-NEXT:    bctr
59 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
60 entry:
61   %0 = load i32 ()*, i32 ()** bitcast (i32 (...)** @Func to i32 ()**), align 8
62   %call = tail call signext i32 %0()
63   ret void
66 define dso_local signext i32 @TailCallParamFuncPtr(i32 (...)* nocapture %passedfunc) local_unnamed_addr {
67 ; CHECK-LABEL: TailCallParamFuncPtr:
68 ; CHECK:         .localentry TailCallParamFuncPtr, 1
69 ; CHECK-NEXT:  # %bb.0: # %entry
70 ; CHECK-NEXT:    mtctr r3
71 ; CHECK-NEXT:    mr r12, r3
72 ; CHECK-NEXT:    bctr
73 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
74 entry:
75   %callee.knr.cast = bitcast i32 (...)* %passedfunc to i32 ()*
76   %call = tail call signext i32 %callee.knr.cast()
77   ret i32 %call
80 define dso_local signext i32 @NoTailIndirectCall(i32 (...)* nocapture %passedfunc, i32 signext %a) local_unnamed_addr {
81 ; CHECK-LABEL: NoTailIndirectCall:
82 ; CHECK:         .localentry NoTailIndirectCall, 1
83 ; CHECK-NEXT:  # %bb.0: # %entry
84 ; CHECK-NEXT:    mflr r0
85 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
86 ; CHECK-NEXT:    .cfi_offset lr, 16
87 ; CHECK-NEXT:    .cfi_offset r30, -16
88 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
89 ; CHECK-NEXT:    std r0, 16(r1)
90 ; CHECK-NEXT:    stdu r1, -48(r1)
91 ; CHECK-NEXT:    mtctr r3
92 ; CHECK-NEXT:    mr r12, r3
93 ; CHECK-NEXT:    mr r30, r4
94 ; CHECK-NEXT:    bctrl
95 ; CHECK-NEXT:    add r3, r3, r30
96 ; CHECK-NEXT:    extsw r3, r3
97 ; CHECK-NEXT:    addi r1, r1, 48
98 ; CHECK-NEXT:    ld r0, 16(r1)
99 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
100 ; CHECK-NEXT:    mtlr r0
101 ; CHECK-NEXT:    blr
102 entry:
103   %callee.knr.cast = bitcast i32 (...)* %passedfunc to i32 ()*
104   %call = tail call signext i32 %callee.knr.cast()
105   %add = add nsw i32 %call, %a
106   ret i32 %add
109 define dso_local signext i32 @TailCallDirect() local_unnamed_addr {
110 ; CHECK-LABEL: TailCallDirect:
111 ; CHECK:         .localentry TailCallDirect, 1
112 ; CHECK-NEXT:  # %bb.0: # %entry
113 ; CHECK-NEXT:    b Function@notoc
114 ; CHECK-NEXT:    #TC_RETURNd8 Function@notoc 0
115 entry:
116   %call = tail call signext i32 bitcast (i32 (...)* @Function to i32 ()*)()
117   ret i32 %call
120 define dso_local signext i32 @NoTailCallDirect(i32 signext %a) local_unnamed_addr {
121 ; CHECK-LABEL: NoTailCallDirect:
122 ; CHECK:         .localentry NoTailCallDirect, 1
123 ; CHECK-NEXT:  # %bb.0: # %entry
124 ; CHECK-NEXT:    mflr r0
125 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
126 ; CHECK-NEXT:    .cfi_offset lr, 16
127 ; CHECK-NEXT:    .cfi_offset r30, -16
128 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
129 ; CHECK-NEXT:    std r0, 16(r1)
130 ; CHECK-NEXT:    stdu r1, -48(r1)
131 ; CHECK-NEXT:    mr r30, r3
132 ; CHECK-NEXT:    bl Function@notoc
133 ; CHECK-NEXT:    add r3, r3, r30
134 ; CHECK-NEXT:    extsw r3, r3
135 ; CHECK-NEXT:    addi r1, r1, 48
136 ; CHECK-NEXT:    ld r0, 16(r1)
137 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
138 ; CHECK-NEXT:    mtlr r0
139 ; CHECK-NEXT:    blr
140 entry:
141   %call = tail call signext i32 bitcast (i32 (...)* @Function to i32 ()*)()
142   %add = add nsw i32 %call, %a
143   ret i32 %add
146 define dso_local signext i32 @TailCallDirectLocal() local_unnamed_addr {
147 ; CHECK-LABEL: TailCallDirectLocal:
148 ; CHECK:         .localentry TailCallDirectLocal, 1
149 ; CHECK-NEXT:  # %bb.0: # %entry
150 ; CHECK-NEXT:    b LocalFunction@notoc
151 ; CHECK-NEXT:    #TC_RETURNd8 LocalFunction@notoc 0
152 entry:
153   %call = tail call fastcc signext i32 @LocalFunction()
154   ret i32 %call
157 define dso_local signext i32 @NoTailCallDirectLocal(i32 signext %a) local_unnamed_addr {
158 ; CHECK-LABEL: NoTailCallDirectLocal:
159 ; CHECK:         .localentry NoTailCallDirectLocal, 1
160 ; CHECK-NEXT:  # %bb.0: # %entry
161 ; CHECK-NEXT:    mflr r0
162 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
163 ; CHECK-NEXT:    .cfi_offset lr, 16
164 ; CHECK-NEXT:    .cfi_offset r30, -16
165 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
166 ; CHECK-NEXT:    std r0, 16(r1)
167 ; CHECK-NEXT:    stdu r1, -48(r1)
168 ; CHECK-NEXT:    mr r30, r3
169 ; CHECK-NEXT:    bl LocalFunction@notoc
170 ; CHECK-NEXT:    add r3, r3, r30
171 ; CHECK-NEXT:    extsw r3, r3
172 ; CHECK-NEXT:    addi r1, r1, 48
173 ; CHECK-NEXT:    ld r0, 16(r1)
174 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
175 ; CHECK-NEXT:    mtlr r0
176 ; CHECK-NEXT:    blr
177 entry:
178   %call = tail call fastcc signext i32 @LocalFunction()
179   %add = add nsw i32 %call, %a
180   ret i32 %add
183 define dso_local signext i32 @TailCallAbs() local_unnamed_addr {
184 ; CHECK-LABEL: TailCallAbs:
185 ; CHECK:         .localentry TailCallAbs, 1
186 ; CHECK-NEXT:  # %bb.0: # %entry
187 ; CHECK-NEXT:    li r3, 400
188 ; CHECK-NEXT:    li r12, 400
189 ; CHECK-NEXT:    mtctr r3
190 ; CHECK-NEXT:    bctr
191 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
192 entry:
193   %call = tail call signext i32 inttoptr (i64 400 to i32 ()*)()
194   ret i32 %call
197 define dso_local signext i32 @NoTailCallAbs(i32 signext %a) local_unnamed_addr {
198 ; CHECK-LABEL: NoTailCallAbs:
199 ; CHECK:         .localentry NoTailCallAbs, 1
200 ; CHECK-NEXT:  # %bb.0: # %entry
201 ; CHECK-NEXT:    mflr r0
202 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
203 ; CHECK-NEXT:    .cfi_offset lr, 16
204 ; CHECK-NEXT:    .cfi_offset r30, -16
205 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
206 ; CHECK-NEXT:    std r0, 16(r1)
207 ; CHECK-NEXT:    stdu r1, -48(r1)
208 ; CHECK-NEXT:    mr r30, r3
209 ; CHECK-NEXT:    li r3, 400
210 ; CHECK-NEXT:    li r12, 400
211 ; CHECK-NEXT:    mtctr r3
212 ; CHECK-NEXT:    bctrl
213 ; CHECK-NEXT:    add r3, r3, r30
214 ; CHECK-NEXT:    extsw r3, r3
215 ; CHECK-NEXT:    addi r1, r1, 48
216 ; CHECK-NEXT:    ld r0, 16(r1)
217 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
218 ; CHECK-NEXT:    mtlr r0
219 ; CHECK-NEXT:    blr
220 entry:
221   %call = tail call signext i32 inttoptr (i64 400 to i32 ()*)()
222   %add = add nsw i32 %call, %a
223   ret i32 %add
226 ; Function Attrs: noinline
227 ; This function should be tail called and not inlined.
228 define internal fastcc signext i32 @LocalFunction() unnamed_addr #0 {
229 ; CHECK-LABEL: LocalFunction:
230 ; CHECK:         .localentry LocalFunction, 1
231 ; CHECK-NEXT:  # %bb.0: # %entry
232 ; CHECK-NEXT:    #APP
233 ; CHECK-NEXT:    li r3, 42
234 ; CHECK-NEXT:    #NO_APP
235 ; CHECK-NEXT:    extsw r3, r3
236 ; CHECK-NEXT:    blr
237 entry:
238   %0 = tail call i32 asm "li $0, 42", "=&r"()
239   ret i32 %0
242 attributes #0 = { noinline }