1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare fastcc void @callee_stack0() 4*9880d681SAndroid Build Coastguard Workerdeclare fastcc void @callee_stack8([8 x i32], i64) 5*9880d681SAndroid Build Coastguard Workerdeclare fastcc void @callee_stack16([8 x i32], i64, i64) 6*9880d681SAndroid Build Coastguard Workerdeclare extern_weak fastcc void @callee_weak() 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to0_from0() nounwind { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to0_from0: 10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: // BB 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack0() 13*9880d681SAndroid Build Coastguard Worker ret void 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack0 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to0_from8([8 x i32], i64) { 19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to0_from8: 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack0() 22*9880d681SAndroid Build Coastguard Worker ret void 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, sp, #16 25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack0 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to8_from0() { 29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to8_from0: 30*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #32 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; Key point is that the "42" should go #16 below incoming stack 33*9880d681SAndroid Build Coastguard Worker; pointer (we didn't have arg space to reuse). 34*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp, #16]! 38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack8 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to8_from8([8 x i32], i64 %a) { 42*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to8_from8: 43*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; Key point is that the "%a" should go where at SP on entry. 46*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 47*9880d681SAndroid Build Coastguard Worker ret void 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp, #16]! 50*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack8 51*9880d681SAndroid Build Coastguard Worker} 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to16_from8([8 x i32], i64 %a) { 54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to16_from8: 55*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; Important point is that the call reuses the "dead" argument space 58*9880d681SAndroid Build Coastguard Worker; above %a on the stack. If it tries to go below incoming-SP then the 59*9880d681SAndroid Build Coastguard Worker; callee will not deallocate the space, even in fastcc. 60*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2) 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]! 63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack16 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) { 69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to8_from24: 70*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; Key point is that the "%a" should go where at #16 above SP on entry. 73*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 74*9880d681SAndroid Build Coastguard Worker ret void 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp, #32]! 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack8 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_to16_from16: 83*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker; Here we want to make sure that both loads happen before the stores: 86*9880d681SAndroid Build Coastguard Worker; otherwise either %a or %b will be wrongly clobbered. 87*9880d681SAndroid Build Coastguard Worker tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a) 88*9880d681SAndroid Build Coastguard Worker ret void 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; CHECK: ldp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16] 91*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]! 92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b callee_stack16 93*9880d681SAndroid Build Coastguard Worker} 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; Weakly-referenced extern functions cannot be tail-called, as AAELF does 97*9880d681SAndroid Build Coastguard Worker; not define the behaviour of branch instructions to undefined weak symbols. 98*9880d681SAndroid Build Coastguard Workerdefine fastcc void @caller_weak() { 99*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_weak: 100*9880d681SAndroid Build Coastguard Worker; CHECK: bl callee_weak 101*9880d681SAndroid Build Coastguard Worker tail call void @callee_weak() 102*9880d681SAndroid Build Coastguard Worker ret void 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerdeclare { [2 x float] } @get_vec2() 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerdefine { [3 x float] } @test_add_elem() { 108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_add_elem: 109*9880d681SAndroid Build Coastguard Worker; CHECK: bl get_vec2 110*9880d681SAndroid Build Coastguard Worker; CHECK: fmov s2, #1.0 111*9880d681SAndroid Build Coastguard Worker; CHECK: ret 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker %call = tail call { [2 x float] } @get_vec2() 114*9880d681SAndroid Build Coastguard Worker %arr = extractvalue { [2 x float] } %call, 0 115*9880d681SAndroid Build Coastguard Worker %arr.0 = extractvalue [2 x float] %arr, 0 116*9880d681SAndroid Build Coastguard Worker %arr.1 = extractvalue [2 x float] %arr, 1 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker %res.0 = insertvalue { [3 x float] } undef, float %arr.0, 0, 0 119*9880d681SAndroid Build Coastguard Worker %res.01 = insertvalue { [3 x float] } %res.0, float %arr.1, 0, 1 120*9880d681SAndroid Build Coastguard Worker %res.012 = insertvalue { [3 x float] } %res.01, float 1.000000e+00, 0, 2 121*9880d681SAndroid Build Coastguard Worker ret { [3 x float] } %res.012 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workerdeclare double @get_double() 125*9880d681SAndroid Build Coastguard Workerdefine { double, [2 x double] } @test_mismatched_insert() { 126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_mismatched_insert: 127*9880d681SAndroid Build Coastguard Worker; CHECK: bl get_double 128*9880d681SAndroid Build Coastguard Worker; CHECK: bl get_double 129*9880d681SAndroid Build Coastguard Worker; CHECK: bl get_double 130*9880d681SAndroid Build Coastguard Worker; CHECK: ret 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker %val0 = call double @get_double() 133*9880d681SAndroid Build Coastguard Worker %val1 = call double @get_double() 134*9880d681SAndroid Build Coastguard Worker %val2 = tail call double @get_double() 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker %res.0 = insertvalue { double, [2 x double] } undef, double %val0, 0 137*9880d681SAndroid Build Coastguard Worker %res.01 = insertvalue { double, [2 x double] } %res.0, double %val1, 1, 0 138*9880d681SAndroid Build Coastguard Worker %res.012 = insertvalue { double, [2 x double] } %res.01, double %val2, 1, 1 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker ret { double, [2 x double] } %res.012 141*9880d681SAndroid Build Coastguard Worker} 142