1*9880d681SAndroid Build Coastguard Worker; Test the 'call' instruction and the tailcall variant. 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; FIXME: We should remove the need for -enable-mips-tail-calls 4*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C 5*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C 6*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C 7*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C 8*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C 9*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C 10*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C 11*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C 12*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C 13*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C 14*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C 15*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,R6C 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerdeclare void @extern_void_void() 18*9880d681SAndroid Build Coastguard Workerdeclare i32 @extern_i32_void() 19*9880d681SAndroid Build Coastguard Workerdeclare float @extern_float_void() 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Workerdefine i32 @call_void_void() { 22*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_void_void: 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $[[TGT]] 29*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $[[TGT]] 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker call void @extern_void_void() 32*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 33*9880d681SAndroid Build Coastguard Worker ret i32 0 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine i32 @call_i32_void() { 37*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_i32_void: 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $[[TGT]] 44*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $[[TGT]] 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker %1 = call i32 @extern_i32_void() 47*9880d681SAndroid Build Coastguard Worker %2 = add i32 %1, 1 48*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 49*9880d681SAndroid Build Coastguard Worker ret i32 %2 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerdefine float @call_float_void() { 53*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_float_void: 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker; FIXME: Not sure why we don't use $gp directly on such a simple test. We should 56*9880d681SAndroid Build Coastguard Worker; look into it at some point. 57*9880d681SAndroid Build Coastguard Worker; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25 58*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]]) 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $[[TGT]] 63*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $[[TGT]] 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker %1 = call float @extern_float_void() 67*9880d681SAndroid Build Coastguard Worker %2 = fadd float %1, 1.0 68*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 69*9880d681SAndroid Build Coastguard Worker ret float %2 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workerdefine void @musttail_call_void_void() { 73*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_void_void: 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker; ALL: jr $[[TGT]] 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker musttail call void @extern_void_void() 82*9880d681SAndroid Build Coastguard Worker ret void 83*9880d681SAndroid Build Coastguard Worker} 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Workerdefine i32 @musttail_call_i32_void() { 86*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_i32_void: 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; ALL: jr $[[TGT]] 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker %1 = musttail call i32 @extern_i32_void() 95*9880d681SAndroid Build Coastguard Worker ret i32 %1 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerdefine float @musttail_call_float_void() { 99*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_float_void: 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; ALL: jr $[[TGT]] 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker %1 = musttail call float @extern_float_void() 108*9880d681SAndroid Build Coastguard Worker ret float %1 109*9880d681SAndroid Build Coastguard Worker} 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerdefine i32 @indirect_call_void_void(void ()* %addr) { 112*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_void_void: 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 115*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $25 116*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $25 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker call void %addr() 119*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 120*9880d681SAndroid Build Coastguard Worker ret i32 0 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Workerdefine i32 @indirect_call_i32_void(i32 ()* %addr) { 124*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_i32_void: 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 127*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $25 128*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $25 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker %1 = call i32 %addr() 132*9880d681SAndroid Build Coastguard Worker %2 = add i32 %1, 1 133*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 134*9880d681SAndroid Build Coastguard Worker ret i32 %2 135*9880d681SAndroid Build Coastguard Worker} 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workerdefine float @indirect_call_float_void(float ()* %addr) { 138*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_float_void: 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 141*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $25 142*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $25 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker %1 = call float %addr() 146*9880d681SAndroid Build Coastguard Worker %2 = fadd float %1, 1.0 147*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 148*9880d681SAndroid Build Coastguard Worker ret float %2 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker; We can't use 'musttail' here because the verifier is too conservative and 152*9880d681SAndroid Build Coastguard Worker; prohibits any prototype difference. 153*9880d681SAndroid Build Coastguard Workerdefine void @tail_indirect_call_void_void(void ()* %addr) { 154*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_void_void: 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 157*9880d681SAndroid Build Coastguard Worker; ALL: jr $25 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker tail call void %addr() 160*9880d681SAndroid Build Coastguard Worker ret void 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Workerdefine i32 @tail_indirect_call_i32_void(i32 ()* %addr) { 164*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_i32_void: 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 167*9880d681SAndroid Build Coastguard Worker; ALL: jr $25 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Worker %1 = tail call i32 %addr() 170*9880d681SAndroid Build Coastguard Worker ret i32 %1 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Workerdefine float @tail_indirect_call_float_void(float ()* %addr) { 174*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_float_void: 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Worker; ALL: move $25, $4 177*9880d681SAndroid Build Coastguard Worker; ALL: jr $25 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker %1 = tail call float %addr() 180*9880d681SAndroid Build Coastguard Worker ret float %1 181*9880d681SAndroid Build Coastguard Worker} 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker; Check that passing undef as a double value doesn't cause machine code errors 184*9880d681SAndroid Build Coastguard Worker; for FP64. 185*9880d681SAndroid Build Coastguard Workerdeclare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Workerdefine hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 { 188*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: thunk_undef_double: 189*9880d681SAndroid Build Coastguard Worker; O32: # implicit-def: %A2 190*9880d681SAndroid Build Coastguard Worker; O32: # implicit-def: %A3 191*9880d681SAndroid Build Coastguard Worker; ALL: jr $25 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker tail call void @undef_double(i32 undef, double undef) #8 194*9880d681SAndroid Build Coastguard Worker ret void 195*9880d681SAndroid Build Coastguard Worker} 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker; Check that immediate addresses do not use jal. 198*9880d681SAndroid Build Coastguard Workerdefine i32 @jal_only_allows_symbols() { 199*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: jal_only_allows_symbols: 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Worker; ALL-NOT: {{jal }} 202*9880d681SAndroid Build Coastguard Worker; ALL: addiu $[[TGT:[0-9]+]], $zero, 1234 203*9880d681SAndroid Build Coastguard Worker; ALL-NOT: {{jal }} 204*9880d681SAndroid Build Coastguard Worker; NOT-R6C: jalr $[[TGT]] 205*9880d681SAndroid Build Coastguard Worker; R6C: jalrc $[[TGT]] 206*9880d681SAndroid Build Coastguard Worker; ALL-NOT: {{jal }} 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker call void () inttoptr (i32 1234 to void ()*)() 209*9880d681SAndroid Build Coastguard Worker; R6C: jrc $ra 210*9880d681SAndroid Build Coastguard Worker ret i32 0 211*9880d681SAndroid Build Coastguard Worker} 212*9880d681SAndroid Build Coastguard Worker 213