1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=SDAG,COMMON 2; RUN: llc -global-isel -global-isel-abort=1 -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=GISEL,COMMON 3 4declare swifttailcc void @callee_stack0() 5declare swifttailcc void @callee_stack8([8 x i64], i64) 6declare swifttailcc void @callee_stack16([8 x i64], i64, i64) 7declare extern_weak swifttailcc void @callee_weak() 8 9define swifttailcc void @caller_to0_from0() nounwind { 10; COMMON-LABEL: caller_to0_from0: 11; COMMON-NEXT: // %bb. 12 13 musttail call swifttailcc void @callee_stack0() 14 ret void 15 16; COMMON-NEXT: b callee_stack0 17} 18 19define swifttailcc void @caller_to0_from8([8 x i64], i64) #0 { 20; COMMON-LABEL: caller_to0_from8: 21 22 musttail call swifttailcc void @callee_stack0() 23 ret void 24 25; COMMON: add sp, sp, #16 26; COMMON-NEXT: .cfi_def_cfa_offset -16 27; COMMON-NEXT: b callee_stack0 28} 29 30define swifttailcc void @caller_to8_from0() #0 { 31; COMMON-LABEL: caller_to8_from0: 32 33; Key point is that the "42" should go #16 below incoming stack 34; pointer (we didn't have arg space to reuse). 35 musttail call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 36 ret void 37 38; COMMON: str {{x[0-9]+}}, [sp, #-16]! 39; COMMON-NEXT: .cfi_def_cfa_offset 16 40; COMMON-NEXT: b callee_stack8 41} 42 43define swifttailcc void @caller_to8_from8([8 x i64], i64 %a) #0 { 44; COMMON-LABEL: caller_to8_from8: 45; COMMON-NOT: sub sp, 46 47; Key point is that the "%a" should go where at SP on entry. 48 musttail call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 49 ret void 50 51; COMMON: str {{x[0-9]+}}, [sp] 52; COMMON-NEXT: b callee_stack8 53} 54 55define swifttailcc void @caller_to16_from8([8 x i64], i64 %a) #0 { 56; COMMON-LABEL: caller_to16_from8: 57; COMMON-NOT: sub sp, 58 59; Important point is that the call reuses the "dead" argument space 60; above %a on the stack. If it tries to go below incoming-SP then the 61; callee will not deallocate the space, even in swifttailcc. 62 musttail call swifttailcc void @callee_stack16([8 x i64] undef, i64 42, i64 2) 63 64; COMMON: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp] 65; COMMON-NEXT: b callee_stack16 66 ret void 67} 68 69 70define swifttailcc void @caller_to8_from24([8 x i64], i64 %a, i64 %b, i64 %c) #0 { 71; COMMON-LABEL: caller_to8_from24: 72; COMMON-NOT: sub sp, 73 74; Key point is that the "%a" should go where at #16 above SP on entry. 75 musttail call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 76 ret void 77 78; COMMON: str {{x[0-9]+}}, [sp, #16]! 79; COMMON-NEXT: .cfi_def_cfa_offset -16 80; COMMON-NEXT: b callee_stack8 81} 82 83 84define swifttailcc void @caller_to16_from16([8 x i64], i64 %a, i64 %b) #0 { 85; COMMON-LABEL: caller_to16_from16: 86; COMMON-NOT: sub sp, 87 88; Here we want to make sure that both loads happen before the stores: 89; otherwise either %a or %b will be wrongly clobbered. 90 musttail call swifttailcc void @callee_stack16([8 x i64] undef, i64 %b, i64 %a) 91 ret void 92 93; COMMON: ldp {{x[0-9]+}}, {{x[0-9]+}}, [sp] 94; COMMON: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp] 95; COMMON-NEXT: b callee_stack16 96} 97 98define swifttailcc void @disable_tail_calls() nounwind "disable-tail-calls"="true" { 99; COMMON-LABEL: disable_tail_calls: 100; COMMON-NEXT: // %bb. 101 102 tail call swifttailcc void @callee_stack0() 103 ret void 104 105; COMMON: bl callee_stack0 106; COMMON: ret 107} 108 109; Weakly-referenced extern functions cannot be tail-called, as AAELF does 110; not define the behaviour of branch instructions to undefined weak symbols. 111define swifttailcc void @caller_weak() #0 { 112; COMMON-LABEL: caller_weak: 113; COMMON: bl callee_weak 114 tail call void @callee_weak() 115 ret void 116} 117 118declare { [2 x float] } @get_vec2() 119 120define { [3 x float] } @test_add_elem() #0 { 121; SDAG-LABEL: test_add_elem: 122; SDAG: bl get_vec2 123; SDAG: fmov s2, #1.0 124; SDAG: ret 125; GISEL-LABEL: test_add_elem: 126; GISEL: str x30, [sp, #-16]! 127; GISEL: bl get_vec2 128; GISEL: fmov s2, #1.0 129; GISEL: ldr x30, [sp], #16 130; GISEL: ret 131 132 %call = tail call { [2 x float] } @get_vec2() 133 %arr = extractvalue { [2 x float] } %call, 0 134 %arr.0 = extractvalue [2 x float] %arr, 0 135 %arr.1 = extractvalue [2 x float] %arr, 1 136 137 %res.0 = insertvalue { [3 x float] } undef, float %arr.0, 0, 0 138 %res.01 = insertvalue { [3 x float] } %res.0, float %arr.1, 0, 1 139 %res.012 = insertvalue { [3 x float] } %res.01, float 1.000000e+00, 0, 2 140 ret { [3 x float] } %res.012 141} 142 143declare double @get_double() 144define { double, [2 x double] } @test_mismatched_insert() #0 { 145; COMMON-LABEL: test_mismatched_insert: 146; COMMON: bl get_double 147; COMMON: bl get_double 148; COMMON: bl get_double 149; COMMON: ret 150 151 %val0 = call double @get_double() 152 %val1 = call double @get_double() 153 %val2 = tail call double @get_double() 154 155 %res.0 = insertvalue { double, [2 x double] } undef, double %val0, 0 156 %res.01 = insertvalue { double, [2 x double] } %res.0, double %val1, 1, 0 157 %res.012 = insertvalue { double, [2 x double] } %res.01, double %val2, 1, 1 158 159 ret { double, [2 x double] } %res.012 160} 161 162define void @fromC_totail() #0 { 163; COMMON-LABEL: fromC_totail: 164; COMMON: sub sp, sp, #48 165 166; COMMON-NOT: sub sp, 167; COMMON: mov w[[TMP:[0-9]+]], #42 168; COMMON: str x[[TMP]], [sp] 169; COMMON: bl callee_stack8 170 ; We must reset the stack to where it was before the call by undoing its extra stack pop. 171; COMMON: str x[[TMP]], [sp, #-16]! 172; COMMON: bl callee_stack8 173; COMMON: sub sp, sp, #16 174 175 call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 176 call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 177 ret void 178} 179 180define void @fromC_totail_noreservedframe(i32 %len) #0 { 181; COMMON-LABEL: fromC_totail_noreservedframe: 182; COMMON: stp x29, x30, [sp, #-48]! 183 184; COMMON: mov w[[TMP:[0-9]+]], #42 185 ; Note stack is subtracted here to allocate space for arg 186; COMMON: str x[[TMP]], [sp, #-16]! 187; COMMON: bl callee_stack8 188 ; And here. 189; COMMON: str x[[TMP]], [sp, #-16]! 190; COMMON: bl callee_stack8 191 ; But not restored here because callee_stack8 did that for us. 192; COMMON-NOT: sub sp, 193 194 ; Variable sized allocation prevents reserving frame at start of function so each call must allocate any stack space it needs. 195 %var = alloca i32, i32 %len 196 197 call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 198 call swifttailcc void @callee_stack8([8 x i64] undef, i64 42) 199 ret void 200} 201 202declare void @Ccallee_stack8([8 x i64], i64) 203 204define swifttailcc void @fromtail_toC() #0 { 205; COMMON-LABEL: fromtail_toC: 206; COMMON: sub sp, sp, #32 207 208; COMMON-NOT: sub sp, 209; COMMON: mov w[[TMP:[0-9]+]], #42 210; COMMON: str x[[TMP]], [sp] 211; COMMON: bl Ccallee_stack8 212 ; C callees will return with the stack exactly where we left it, so we mustn't try to fix anything. 213; COMMON-NOT: add sp, 214; COMMON-NOT: sub sp, 215; COMMON: str x[[TMP]], [sp]{{$}} 216; COMMON: bl Ccallee_stack8 217; COMMON-NOT: sub sp, 218 219 220 call void @Ccallee_stack8([8 x i64] undef, i64 42) 221 call void @Ccallee_stack8([8 x i64] undef, i64 42) 222 ret void 223} 224 225declare swifttailcc ptr @SwiftSelf(ptr swiftasync %context, ptr swiftself %closure) 226define swiftcc ptr @CallSwiftSelf(ptr swiftself %closure, ptr %context) #0 { 227; CHECK-LABEL: CallSwiftSelf: 228; CHECK: stp x20 229 ;call void asm "","~{r13}"() ; We get a push r13 but why not with the call 230 ; below? 231 %res = call swifttailcc ptr @SwiftSelf(ptr swiftasync %context, ptr swiftself %closure) 232 ret ptr %res 233} 234 235attributes #0 = { uwtable }