495 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py2; RUN: llc %s -stop-after=irtranslator -verify-machineinstrs -mtriple aarch64-apple-darwin -global-isel -o - 2>&1 | FileCheck %s --check-prefix=DARWIN3; RUN: llc %s -stop-after=irtranslator -verify-machineinstrs -mtriple aarch64-windows -global-isel -o - 2>&1 | FileCheck %s --check-prefix=WINDOWS4 5declare void @simple_fn()6define void @tail_call() {7 ; DARWIN-LABEL: name: tail_call8 ; DARWIN: bb.1 (%ir-block.0):9 ; DARWIN-NEXT: TCRETURNdi @simple_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp10 ; WINDOWS-LABEL: name: tail_call11 ; WINDOWS: bb.1 (%ir-block.0):12 ; WINDOWS-NEXT: TCRETURNdi @simple_fn, 0, csr_aarch64_aapcs, implicit $sp13 tail call void @simple_fn()14 ret void15}16 17; We should get a TCRETURNri here.18; FIXME: We don't need the COPY.19define void @indirect_tail_call(ptr %func) {20 ; DARWIN-LABEL: name: indirect_tail_call21 ; DARWIN: bb.1 (%ir-block.0):22 ; DARWIN-NEXT: liveins: $x023 ; DARWIN-NEXT: {{ $}}24 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:tcgpr64(p0) = COPY $x025 ; DARWIN-NEXT: TCRETURNri [[COPY]](p0), 0, csr_darwin_aarch64_aapcs, implicit $sp26 ; WINDOWS-LABEL: name: indirect_tail_call27 ; WINDOWS: bb.1 (%ir-block.0):28 ; WINDOWS-NEXT: liveins: $x029 ; WINDOWS-NEXT: {{ $}}30 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:tcgpr64(p0) = COPY $x031 ; WINDOWS-NEXT: TCRETURNri [[COPY]](p0), 0, csr_aarch64_aapcs, implicit $sp32 tail call void %func()33 ret void34}35 36declare void @outgoing_args_fn(i32)37define void @test_outgoing_args(i32 %a) {38 ; DARWIN-LABEL: name: test_outgoing_args39 ; DARWIN: bb.1 (%ir-block.0):40 ; DARWIN-NEXT: liveins: $w041 ; DARWIN-NEXT: {{ $}}42 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w043 ; DARWIN-NEXT: $w0 = COPY [[COPY]](s32)44 ; DARWIN-NEXT: TCRETURNdi @outgoing_args_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $w045 ; WINDOWS-LABEL: name: test_outgoing_args46 ; WINDOWS: bb.1 (%ir-block.0):47 ; WINDOWS-NEXT: liveins: $w048 ; WINDOWS-NEXT: {{ $}}49 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w050 ; WINDOWS-NEXT: $w0 = COPY [[COPY]](s32)51 ; WINDOWS-NEXT: TCRETURNdi @outgoing_args_fn, 0, csr_aarch64_aapcs, implicit $sp, implicit $w052 tail call void @outgoing_args_fn(i32 %a)53 ret void54}55 56; Verify that we create frame indices for memory arguments in tail calls.57; We get a bunch of copies here which are unused and thus eliminated. So, let's58; just focus on what matters, which is that we get a G_FRAME_INDEX.59declare void @outgoing_stack_args_fn(<4 x half>)60define void @test_outgoing_stack_args([8 x <2 x double>], <4 x half> %arg) {61 ; DARWIN-LABEL: name: test_outgoing_stack_args62 ; DARWIN: bb.1 (%ir-block.1):63 ; DARWIN-NEXT: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q764 ; DARWIN-NEXT: {{ $}}65 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q066 ; DARWIN-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q167 ; DARWIN-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q268 ; DARWIN-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q369 ; DARWIN-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q470 ; DARWIN-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q571 ; DARWIN-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q672 ; DARWIN-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q773 ; DARWIN-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.074 ; DARWIN-NEXT: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)75 ; DARWIN-NEXT: $d0 = COPY [[LOAD]](<4 x s16>)76 ; DARWIN-NEXT: TCRETURNdi @outgoing_stack_args_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $d077 ; WINDOWS-LABEL: name: test_outgoing_stack_args78 ; WINDOWS: bb.1 (%ir-block.1):79 ; WINDOWS-NEXT: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q780 ; WINDOWS-NEXT: {{ $}}81 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q082 ; WINDOWS-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q183 ; WINDOWS-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q284 ; WINDOWS-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q385 ; WINDOWS-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q486 ; WINDOWS-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q587 ; WINDOWS-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q688 ; WINDOWS-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q789 ; WINDOWS-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.090 ; WINDOWS-NEXT: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)91 ; WINDOWS-NEXT: $d0 = COPY [[LOAD]](<4 x s16>)92 ; WINDOWS-NEXT: TCRETURNdi @outgoing_stack_args_fn, 0, csr_aarch64_aapcs, implicit $sp, implicit $d093 tail call void @outgoing_stack_args_fn(<4 x half> %arg)94 ret void95}96 97; Verify that we don't tail call when we cannot fit arguments on the caller's98; stack.99declare i32 @too_big_stack(i64 %x0, i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i8 %c, i16 %s)100define i32 @test_too_big_stack() {101 ; DARWIN-LABEL: name: test_too_big_stack102 ; DARWIN: bb.1.entry:103 ; DARWIN-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF104 ; DARWIN-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 8105 ; DARWIN-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 9106 ; DARWIN-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $sp, implicit $sp107 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $sp108 ; DARWIN-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 0109 ; DARWIN-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)110 ; DARWIN-NEXT: G_STORE [[C]](s8), [[PTR_ADD]](p0) :: (store (s8) into stack)111 ; DARWIN-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2112 ; DARWIN-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)113 ; DARWIN-NEXT: G_STORE [[C1]](s16), [[PTR_ADD1]](p0) :: (store (s16) into stack + 2, align 1)114 ; DARWIN-NEXT: $x0 = COPY [[DEF]](s64)115 ; DARWIN-NEXT: $x1 = COPY [[DEF]](s64)116 ; DARWIN-NEXT: $x2 = COPY [[DEF]](s64)117 ; DARWIN-NEXT: $x3 = COPY [[DEF]](s64)118 ; DARWIN-NEXT: $x4 = COPY [[DEF]](s64)119 ; DARWIN-NEXT: $x5 = COPY [[DEF]](s64)120 ; DARWIN-NEXT: $x6 = COPY [[DEF]](s64)121 ; DARWIN-NEXT: $x7 = COPY [[DEF]](s64)122 ; DARWIN-NEXT: BL @too_big_stack, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit-def $w0123 ; DARWIN-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $sp, implicit $sp124 ; DARWIN-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0125 ; DARWIN-NEXT: $w0 = COPY [[COPY1]](s32)126 ; DARWIN-NEXT: RET_ReallyLR implicit $w0127 ; WINDOWS-LABEL: name: test_too_big_stack128 ; WINDOWS: bb.1.entry:129 ; WINDOWS-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF130 ; WINDOWS-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 8131 ; WINDOWS-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 9132 ; WINDOWS-NEXT: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp133 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $sp134 ; WINDOWS-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 0135 ; WINDOWS-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)136 ; WINDOWS-NEXT: G_STORE [[C]](s8), [[PTR_ADD]](p0) :: (store (s8) into stack)137 ; WINDOWS-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8138 ; WINDOWS-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)139 ; WINDOWS-NEXT: G_STORE [[C1]](s16), [[PTR_ADD1]](p0) :: (store (s16) into stack + 8, align 1)140 ; WINDOWS-NEXT: $x0 = COPY [[DEF]](s64)141 ; WINDOWS-NEXT: $x1 = COPY [[DEF]](s64)142 ; WINDOWS-NEXT: $x2 = COPY [[DEF]](s64)143 ; WINDOWS-NEXT: $x3 = COPY [[DEF]](s64)144 ; WINDOWS-NEXT: $x4 = COPY [[DEF]](s64)145 ; WINDOWS-NEXT: $x5 = COPY [[DEF]](s64)146 ; WINDOWS-NEXT: $x6 = COPY [[DEF]](s64)147 ; WINDOWS-NEXT: $x7 = COPY [[DEF]](s64)148 ; WINDOWS-NEXT: BL @too_big_stack, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit-def $w0149 ; WINDOWS-NEXT: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp150 ; WINDOWS-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0151 ; WINDOWS-NEXT: $w0 = COPY [[COPY1]](s32)152 ; WINDOWS-NEXT: RET_ReallyLR implicit $w0153entry:154 %call = tail call i32 @too_big_stack(i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i8 8, i16 9)155 ret i32 %call156}157 158; Right now, we don't want to tail call callees with nonvoid return types, since159; call lowering will insert COPYs after the call.160; TODO: Support this.161declare i32 @nonvoid_ret()162define i32 @test_nonvoid_ret() {163 ; DARWIN-LABEL: name: test_nonvoid_ret164 ; DARWIN: bb.1 (%ir-block.0):165 ; DARWIN-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp166 ; WINDOWS-LABEL: name: test_nonvoid_ret167 ; WINDOWS: bb.1 (%ir-block.0):168 ; WINDOWS-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp169 %call = tail call i32 @nonvoid_ret()170 ret i32 %call171}172 173declare void @varargs(i32, double, i64, ...)174define void @test_varargs() {175 ; DARWIN-LABEL: name: test_varargs176 ; DARWIN: bb.1 (%ir-block.0):177 ; DARWIN-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42178 ; DARWIN-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00179 ; DARWIN-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12180 ; DARWIN-NEXT: $w0 = COPY [[C]](s32)181 ; DARWIN-NEXT: $d0 = COPY [[C1]](s64)182 ; DARWIN-NEXT: $x1 = COPY [[C2]](s64)183 ; DARWIN-NEXT: TCRETURNdi @varargs, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1184 ; WINDOWS-LABEL: name: test_varargs185 ; WINDOWS: bb.1 (%ir-block.0):186 ; WINDOWS-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42187 ; WINDOWS-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00188 ; WINDOWS-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12189 ; WINDOWS-NEXT: $w0 = COPY [[C]](s32)190 ; WINDOWS-NEXT: $x1 = COPY [[C1]](s64)191 ; WINDOWS-NEXT: $x2 = COPY [[C2]](s64)192 ; WINDOWS-NEXT: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2193 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12)194 ret void195}196 197; Darwin should not tail call here, because the last parameter to @varargs is198; not fixed. So, it's passed on the stack, which will make us not fit. On199; Windows, it's passed in a register, so it's safe to tail call.200define void @test_varargs_2() {201 202 ; DARWIN-LABEL: name: test_varargs_2203 ; DARWIN: bb.1 (%ir-block.0):204 ; DARWIN-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42205 ; DARWIN-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00206 ; DARWIN-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12207 ; DARWIN-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314208 ; DARWIN-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $sp, implicit $sp209 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $sp210 ; DARWIN-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 0211 ; DARWIN-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s64)212 ; DARWIN-NEXT: G_STORE [[C3]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 1)213 ; DARWIN-NEXT: $w0 = COPY [[C]](s32)214 ; DARWIN-NEXT: $d0 = COPY [[C1]](s64)215 ; DARWIN-NEXT: $x1 = COPY [[C2]](s64)216 ; DARWIN-NEXT: BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1217 ; DARWIN-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp218 ; DARWIN-NEXT: RET_ReallyLR219 ; WINDOWS-LABEL: name: test_varargs_2220 ; WINDOWS: bb.1 (%ir-block.0):221 ; WINDOWS-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42222 ; WINDOWS-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00223 ; WINDOWS-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12224 ; WINDOWS-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314225 ; WINDOWS-NEXT: $w0 = COPY [[C]](s32)226 ; WINDOWS-NEXT: $x1 = COPY [[C1]](s64)227 ; WINDOWS-NEXT: $x2 = COPY [[C2]](s64)228 ; WINDOWS-NEXT: $x3 = COPY [[C3]](s64)229 ; WINDOWS-NEXT: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2, implicit $x3230 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)231 ret void232}233 234; Same deal here, even though we have enough room to fit. On Darwin, we'll pass235; the last argument to @varargs on the stack. We don't allow tail calling236; varargs arguments that are on the stack.237define void @test_varargs_3([8 x <2 x double>], <4 x half> %arg) {238 239 ; DARWIN-LABEL: name: test_varargs_3240 ; DARWIN: bb.1 (%ir-block.1):241 ; DARWIN-NEXT: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7242 ; DARWIN-NEXT: {{ $}}243 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0244 ; DARWIN-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1245 ; DARWIN-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2246 ; DARWIN-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3247 ; DARWIN-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4248 ; DARWIN-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5249 ; DARWIN-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6250 ; DARWIN-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7251 ; DARWIN-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0252 ; DARWIN-NEXT: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)253 ; DARWIN-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42254 ; DARWIN-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00255 ; DARWIN-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12256 ; DARWIN-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314257 ; DARWIN-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $sp, implicit $sp258 ; DARWIN-NEXT: [[COPY8:%[0-9]+]]:_(p0) = COPY $sp259 ; DARWIN-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 0260 ; DARWIN-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY8]], [[C4]](s64)261 ; DARWIN-NEXT: G_STORE [[C3]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 1)262 ; DARWIN-NEXT: $w0 = COPY [[C]](s32)263 ; DARWIN-NEXT: $d0 = COPY [[C1]](s64)264 ; DARWIN-NEXT: $x1 = COPY [[C2]](s64)265 ; DARWIN-NEXT: BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1266 ; DARWIN-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp267 ; DARWIN-NEXT: RET_ReallyLR268 ; WINDOWS-LABEL: name: test_varargs_3269 ; WINDOWS: bb.1 (%ir-block.1):270 ; WINDOWS-NEXT: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7271 ; WINDOWS-NEXT: {{ $}}272 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0273 ; WINDOWS-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1274 ; WINDOWS-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2275 ; WINDOWS-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3276 ; WINDOWS-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4277 ; WINDOWS-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5278 ; WINDOWS-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6279 ; WINDOWS-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7280 ; WINDOWS-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0281 ; WINDOWS-NEXT: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)282 ; WINDOWS-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42283 ; WINDOWS-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00284 ; WINDOWS-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12285 ; WINDOWS-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314286 ; WINDOWS-NEXT: $w0 = COPY [[C]](s32)287 ; WINDOWS-NEXT: $x1 = COPY [[C1]](s64)288 ; WINDOWS-NEXT: $x2 = COPY [[C2]](s64)289 ; WINDOWS-NEXT: $x3 = COPY [[C3]](s64)290 ; WINDOWS-NEXT: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2, implicit $x3291 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)292 ret void293}294 295; Unsupported calling convention for tail calls. Make sure we never tail call296; it.297declare ghccc void @bad_call_conv_fn()298define void @test_bad_call_conv() {299 ; DARWIN-LABEL: name: test_bad_call_conv300 ; DARWIN: bb.1 (%ir-block.0):301 ; DARWIN-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp302 ; DARWIN-NEXT: BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp303 ; DARWIN-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp304 ; DARWIN-NEXT: RET_ReallyLR305 ; WINDOWS-LABEL: name: test_bad_call_conv306 ; WINDOWS: bb.1 (%ir-block.0):307 ; WINDOWS-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp308 ; WINDOWS-NEXT: BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp309 ; WINDOWS-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp310 ; WINDOWS-NEXT: RET_ReallyLR311 tail call ghccc void @bad_call_conv_fn()312 ret void313}314 315; Shouldn't tail call when the caller has byval arguments.316define void @test_byval(ptr byval(i8) %ptr) {317 ; DARWIN-LABEL: name: test_byval318 ; DARWIN: bb.1 (%ir-block.0):319 ; DARWIN-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0320 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[FRAME_INDEX]](p0)321 ; DARWIN-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp322 ; DARWIN-NEXT: BL @simple_fn, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp323 ; DARWIN-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp324 ; DARWIN-NEXT: RET_ReallyLR325 ; WINDOWS-LABEL: name: test_byval326 ; WINDOWS: bb.1 (%ir-block.0):327 ; WINDOWS-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0328 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[FRAME_INDEX]](p0)329 ; WINDOWS-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp330 ; WINDOWS-NEXT: BL @simple_fn, csr_aarch64_aapcs, implicit-def $lr, implicit $sp331 ; WINDOWS-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp332 ; WINDOWS-NEXT: RET_ReallyLR333 tail call void @simple_fn()334 ret void335}336 337; Shouldn't tail call when the caller has inreg arguments.338define void @test_inreg(ptr inreg %ptr) {339 ; DARWIN-LABEL: name: test_inreg340 ; DARWIN: bb.1 (%ir-block.0):341 ; DARWIN-NEXT: liveins: $x0342 ; DARWIN-NEXT: {{ $}}343 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0344 ; DARWIN-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp345 ; DARWIN-NEXT: BL @simple_fn, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp346 ; DARWIN-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp347 ; DARWIN-NEXT: RET_ReallyLR348 ; WINDOWS-LABEL: name: test_inreg349 ; WINDOWS: bb.1 (%ir-block.0):350 ; WINDOWS-NEXT: liveins: $x0351 ; WINDOWS-NEXT: {{ $}}352 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0353 ; WINDOWS-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp354 ; WINDOWS-NEXT: BL @simple_fn, csr_aarch64_aapcs, implicit-def $lr, implicit $sp355 ; WINDOWS-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp356 ; WINDOWS-NEXT: RET_ReallyLR357 tail call void @simple_fn()358 ret void359}360 361declare fastcc void @fast_fn()362define void @test_mismatched_caller() {363 ; DARWIN-LABEL: name: test_mismatched_caller364 ; DARWIN: bb.1 (%ir-block.0):365 ; DARWIN-NEXT: TCRETURNdi @fast_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp366 ; WINDOWS-LABEL: name: test_mismatched_caller367 ; WINDOWS: bb.1 (%ir-block.0):368 ; WINDOWS-NEXT: TCRETURNdi @fast_fn, 0, csr_aarch64_aapcs, implicit $sp369 tail call fastcc void @fast_fn()370 ret void371}372 373; Verify that lifetime markers and llvm.assume don't impact tail calling.374declare void @llvm.assume(i1)375define void @test_assume() local_unnamed_addr {376 ; DARWIN-LABEL: name: test_assume377 ; DARWIN: bb.1.entry:378 ; DARWIN-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp379 ; WINDOWS-LABEL: name: test_assume380 ; WINDOWS: bb.1.entry:381 ; WINDOWS-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp382entry:383 %x = tail call i32 @nonvoid_ret()384 %y = icmp ne i32 %x, 0385 tail call void @llvm.assume(i1 %y)386 ret void387}388 389declare void @llvm.lifetime.start.p0(i64, ptr nocapture)390declare void @llvm.lifetime.end.p0(i64, ptr nocapture)391define void @test_lifetime() local_unnamed_addr {392 ; DARWIN-LABEL: name: test_lifetime393 ; DARWIN: bb.1.entry:394 ; DARWIN-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.t395 ; DARWIN-NEXT: LIFETIME_START %stack.0.t396 ; DARWIN-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp397 ; WINDOWS-LABEL: name: test_lifetime398 ; WINDOWS: bb.1.entry:399 ; WINDOWS-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.t400 ; WINDOWS-NEXT: LIFETIME_START %stack.0.t401 ; WINDOWS-NEXT: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp402entry:403 %t = alloca i8, align 1404 call void @llvm.lifetime.start.p0(i64 1, ptr %t)405 %x = tail call i32 @nonvoid_ret()406 %y = icmp ne i32 %x, 0407 tail call void @llvm.lifetime.end.p0(i64 1, ptr %t)408 ret void409}410 411; We can tail call when the callee swiftself is the same as the caller one.412; It would be nice to move this to swiftself.ll, but it's important to verify413; that we get the COPY that makes this safe in the first place.414declare ptr @pluto()415define hidden swiftcc i64 @swiftself_indirect_tail(ptr swiftself %arg) {416 ; DARWIN-LABEL: name: swiftself_indirect_tail417 ; DARWIN: bb.1 (%ir-block.0):418 ; DARWIN-NEXT: liveins: $x20419 ; DARWIN-NEXT: {{ $}}420 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x20421 ; DARWIN-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp422 ; DARWIN-NEXT: BL @pluto, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0423 ; DARWIN-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp424 ; DARWIN-NEXT: [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0425 ; DARWIN-NEXT: $x20 = COPY [[COPY]](p0)426 ; DARWIN-NEXT: TCRETURNri [[COPY1]](p0), 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $x20427 ; WINDOWS-LABEL: name: swiftself_indirect_tail428 ; WINDOWS: bb.1 (%ir-block.0):429 ; WINDOWS-NEXT: liveins: $x20430 ; WINDOWS-NEXT: {{ $}}431 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x20432 ; WINDOWS-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp433 ; WINDOWS-NEXT: BL @pluto, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0434 ; WINDOWS-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp435 ; WINDOWS-NEXT: [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0436 ; WINDOWS-NEXT: $x20 = COPY [[COPY]](p0)437 ; WINDOWS-NEXT: TCRETURNri [[COPY1]](p0), 0, csr_aarch64_aapcs, implicit $sp, implicit $x20438 %tmp = call ptr @pluto()439 %tmp2 = tail call swiftcc i64 %tmp(ptr swiftself %arg)440 ret i64 %tmp2441}442 443; Verify that we can tail call musttail callees.444declare void @must_callee(ptr)445define void @foo(ptr) {446 ; DARWIN-LABEL: name: foo447 ; DARWIN: bb.1 (%ir-block.1):448 ; DARWIN-NEXT: liveins: $x0449 ; DARWIN-NEXT: {{ $}}450 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0451 ; DARWIN-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0452 ; DARWIN-NEXT: $x0 = COPY [[C]](p0)453 ; DARWIN-NEXT: TCRETURNdi @must_callee, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $x0454 ; WINDOWS-LABEL: name: foo455 ; WINDOWS: bb.1 (%ir-block.1):456 ; WINDOWS-NEXT: liveins: $x0457 ; WINDOWS-NEXT: {{ $}}458 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0459 ; WINDOWS-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0460 ; WINDOWS-NEXT: $x0 = COPY [[C]](p0)461 ; WINDOWS-NEXT: TCRETURNdi @must_callee, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0462 musttail call void @must_callee(ptr null)463 ret void464}465 466; Verify we emit a tail call with a type that requires splitting into467; multiple registers.468declare void @outgoing_v16f16(<16 x half>)469define void @test_tail_call_outgoing_v16f16(<16 x half> %arg) {470 ; DARWIN-LABEL: name: test_tail_call_outgoing_v16f16471 ; DARWIN: bb.1 (%ir-block.0):472 ; DARWIN-NEXT: liveins: $q0, $q1473 ; DARWIN-NEXT: {{ $}}474 ; DARWIN-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0475 ; DARWIN-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $q1476 ; DARWIN-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[COPY]](<8 x s16>), [[COPY1]](<8 x s16>)477 ; DARWIN-NEXT: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[CONCAT_VECTORS]](<16 x s16>)478 ; DARWIN-NEXT: $q0 = COPY [[UV]](<8 x s16>)479 ; DARWIN-NEXT: $q1 = COPY [[UV1]](<8 x s16>)480 ; DARWIN-NEXT: TCRETURNdi @outgoing_v16f16, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $q0, implicit $q1481 ; WINDOWS-LABEL: name: test_tail_call_outgoing_v16f16482 ; WINDOWS: bb.1 (%ir-block.0):483 ; WINDOWS-NEXT: liveins: $q0, $q1484 ; WINDOWS-NEXT: {{ $}}485 ; WINDOWS-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0486 ; WINDOWS-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $q1487 ; WINDOWS-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[COPY]](<8 x s16>), [[COPY1]](<8 x s16>)488 ; WINDOWS-NEXT: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[CONCAT_VECTORS]](<16 x s16>)489 ; WINDOWS-NEXT: $q0 = COPY [[UV]](<8 x s16>)490 ; WINDOWS-NEXT: $q1 = COPY [[UV1]](<8 x s16>)491 ; WINDOWS-NEXT: TCRETURNdi @outgoing_v16f16, 0, csr_aarch64_aapcs, implicit $sp, implicit $q0, implicit $q1492 tail call void @outgoing_v16f16(<16 x half> %arg)493 ret void494}495