[X86] X86DAGToDAGISel - attempt to merge XMM/YMM loads with YMM/ZMM loads of the...
[llvm-project.git] / llvm / test / CodeGen / PowerPC / pcrel-tail-calls.ll
blob319c346f08f9db36770368e638385d2bc0e955c3
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 ptr, align 8
16 @FuncLocal = common dso_local local_unnamed_addr global ptr 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 ptr @Function, ptr @Func, align 8
29   store ptr @Function, ptr @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:       # %bb.0: # %entry
38 ; CHECK-NEXT:    pld r12, FuncLocal@PCREL(0), 1
39 ; CHECK-NEXT:    mtctr r12
40 ; CHECK-NEXT:    bctr
41 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
42 entry:
43   %0 = load ptr, ptr @FuncLocal, align 8
44   %call = tail call signext i32 %0()
45   ret void
48 define dso_local void @TailCallExtrnFuncPtr() local_unnamed_addr {
49 ; CHECK-LABEL: TailCallExtrnFuncPtr:
50 ; CHECK:       # %bb.0: # %entry
51 ; CHECK-NEXT:    pld r3, Func@got@pcrel(0), 1
52 ; CHECK-NEXT:  .Lpcrel0:
53 ; CHECK-NEXT:    .reloc .Lpcrel0-8,R_PPC64_PCREL_OPT,.-(.Lpcrel0-8)
54 ; CHECK-NEXT:    ld r12, 0(r3)
55 ; CHECK-NEXT:    mtctr r12
56 ; CHECK-NEXT:    bctr
57 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
58 entry:
59   %0 = load ptr, ptr @Func, align 8
60   %call = tail call signext i32 %0()
61   ret void
64 define dso_local signext i32 @TailCallParamFuncPtr(ptr nocapture %passedfunc) local_unnamed_addr {
65 ; CHECK-LABEL: TailCallParamFuncPtr:
66 ; CHECK:       # %bb.0: # %entry
67 ; CHECK-NEXT:    mtctr r3
68 ; CHECK-NEXT:    mr r12, r3
69 ; CHECK-NEXT:    bctr
70 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
71 entry:
72   %call = tail call signext i32 %passedfunc()
73   ret i32 %call
76 define dso_local signext i32 @NoTailIndirectCall(ptr nocapture %passedfunc, i32 signext %a) local_unnamed_addr {
77 ; CHECK-LABEL: NoTailIndirectCall:
78 ; CHECK:       # %bb.0: # %entry
79 ; CHECK-NEXT:    mflr r0
80 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
81 ; CHECK-NEXT:    .cfi_offset lr, 16
82 ; CHECK-NEXT:    .cfi_offset r30, -16
83 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
84 ; CHECK-NEXT:    std r0, 16(r1)
85 ; CHECK-NEXT:    stdu r1, -48(r1)
86 ; CHECK-NEXT:    mr r12, r3
87 ; CHECK-NEXT:    mtctr r3
88 ; CHECK-NEXT:    mr r30, r4
89 ; CHECK-NEXT:    bctrl
90 ; CHECK-NEXT:    add r3, r3, r30
91 ; CHECK-NEXT:    extsw r3, r3
92 ; CHECK-NEXT:    addi r1, r1, 48
93 ; CHECK-NEXT:    ld r0, 16(r1)
94 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
95 ; CHECK-NEXT:    mtlr r0
96 ; CHECK-NEXT:    blr
97 entry:
98   %call = tail call signext i32 %passedfunc()
99   %add = add nsw i32 %call, %a
100   ret i32 %add
103 define dso_local signext i32 @TailCallDirect() local_unnamed_addr {
104 ; CHECK-LABEL: TailCallDirect:
105 ; CHECK:       # %bb.0: # %entry
106 ; CHECK-NEXT:    b Function@notoc
107 ; CHECK-NEXT:    #TC_RETURNd8 Function@notoc 0
108 entry:
109   %call = tail call signext i32 @Function()
110   ret i32 %call
113 define dso_local signext i32 @NoTailCallDirect(i32 signext %a) local_unnamed_addr {
114 ; CHECK-LABEL: NoTailCallDirect:
115 ; CHECK:       # %bb.0: # %entry
116 ; CHECK-NEXT:    mflr r0
117 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
118 ; CHECK-NEXT:    .cfi_offset lr, 16
119 ; CHECK-NEXT:    .cfi_offset r30, -16
120 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
121 ; CHECK-NEXT:    std r0, 16(r1)
122 ; CHECK-NEXT:    stdu r1, -48(r1)
123 ; CHECK-NEXT:    mr r30, r3
124 ; CHECK-NEXT:    bl Function@notoc
125 ; CHECK-NEXT:    add r3, r3, r30
126 ; CHECK-NEXT:    extsw r3, r3
127 ; CHECK-NEXT:    addi r1, r1, 48
128 ; CHECK-NEXT:    ld r0, 16(r1)
129 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
130 ; CHECK-NEXT:    mtlr r0
131 ; CHECK-NEXT:    blr
132 entry:
133   %call = tail call signext i32 @Function()
134   %add = add nsw i32 %call, %a
135   ret i32 %add
138 define dso_local signext i32 @TailCallDirectLocal() local_unnamed_addr {
139 ; CHECK-LABEL: TailCallDirectLocal:
140 ; CHECK:       # %bb.0: # %entry
141 ; CHECK-NEXT:    b LocalFunction@notoc
142 ; CHECK-NEXT:    #TC_RETURNd8 LocalFunction@notoc 0
143 entry:
144   %call = tail call fastcc signext i32 @LocalFunction()
145   ret i32 %call
148 define dso_local signext i32 @NoTailCallDirectLocal(i32 signext %a) local_unnamed_addr {
149 ; CHECK-LABEL: NoTailCallDirectLocal:
150 ; CHECK:       # %bb.0: # %entry
151 ; CHECK-NEXT:    mflr r0
152 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
153 ; CHECK-NEXT:    .cfi_offset lr, 16
154 ; CHECK-NEXT:    .cfi_offset r30, -16
155 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
156 ; CHECK-NEXT:    std r0, 16(r1)
157 ; CHECK-NEXT:    stdu r1, -48(r1)
158 ; CHECK-NEXT:    mr r30, r3
159 ; CHECK-NEXT:    bl LocalFunction@notoc
160 ; CHECK-NEXT:    add r3, r3, r30
161 ; CHECK-NEXT:    extsw r3, r3
162 ; CHECK-NEXT:    addi r1, r1, 48
163 ; CHECK-NEXT:    ld r0, 16(r1)
164 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
165 ; CHECK-NEXT:    mtlr r0
166 ; CHECK-NEXT:    blr
167 entry:
168   %call = tail call fastcc signext i32 @LocalFunction()
169   %add = add nsw i32 %call, %a
170   ret i32 %add
173 define dso_local signext i32 @TailCallAbs() local_unnamed_addr {
174 ; CHECK-LABEL: TailCallAbs:
175 ; CHECK:       # %bb.0: # %entry
176 ; CHECK-NEXT:    li r3, 400
177 ; CHECK-NEXT:    li r12, 400
178 ; CHECK-NEXT:    mtctr r3
179 ; CHECK-NEXT:    bctr
180 ; CHECK-NEXT:    #TC_RETURNr8 ctr 0
181 entry:
182   %call = tail call signext i32 inttoptr (i64 400 to ptr)()
183   ret i32 %call
186 define dso_local signext i32 @NoTailCallAbs(i32 signext %a) local_unnamed_addr {
187 ; CHECK-LABEL: NoTailCallAbs:
188 ; CHECK:       # %bb.0: # %entry
189 ; CHECK-NEXT:    mflr r0
190 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
191 ; CHECK-NEXT:    .cfi_offset lr, 16
192 ; CHECK-NEXT:    .cfi_offset r30, -16
193 ; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
194 ; CHECK-NEXT:    std r0, 16(r1)
195 ; CHECK-NEXT:    stdu r1, -48(r1)
196 ; CHECK-NEXT:    mr r30, r3
197 ; CHECK-NEXT:    li r3, 400
198 ; CHECK-NEXT:    li r12, 400
199 ; CHECK-NEXT:    mtctr r3
200 ; CHECK-NEXT:    bctrl
201 ; CHECK-NEXT:    add r3, r3, r30
202 ; CHECK-NEXT:    extsw r3, r3
203 ; CHECK-NEXT:    addi r1, r1, 48
204 ; CHECK-NEXT:    ld r0, 16(r1)
205 ; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
206 ; CHECK-NEXT:    mtlr r0
207 ; CHECK-NEXT:    blr
208 entry:
209   %call = tail call signext i32 inttoptr (i64 400 to ptr)()
210   %add = add nsw i32 %call, %a
211   ret i32 %add
214 ; Function Attrs: noinline
215 ; This function should be tail called and not inlined.
216 define internal fastcc signext i32 @LocalFunction() unnamed_addr #0 {
217 ; CHECK-LABEL: LocalFunction:
218 ; CHECK:       # %bb.0: # %entry
219 ; CHECK-NEXT:    #APP
220 ; CHECK-NEXT:    li r3, 42
221 ; CHECK-NEXT:    #NO_APP
222 ; CHECK-NEXT:    extsw r3, r3
223 ; CHECK-NEXT:    blr
224 entry:
225   %0 = tail call i32 asm "li $0, 42", "=&r"()
226   ret i32 %0
229 attributes #0 = { noinline }