// Jump to label or value in register.
if (RetOpcode == ARM::TCRETURNdi) {
- BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPd)).
+ BuildMI(MBB, MBBI, dl,
+ TII.get(STI.isThumb() ? ARM::TAILJMPdt : ARM::TAILJMPd)).
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
JumpTarget.getTargetFlags());
} else if (RetOpcode == ARM::TCRETURNdiND) {
if (!TII->isLoadFromStackSlot(Def, FI))
return false;
} else {
-// unsigned Opcode = Def->getOpcode();
-// if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r) &&
-// Def->getOperand(1).isFI()) {
-// FI = Def->getOperand(1).getIndex();
-// Bytes = Flags.getByValSize();
-// } else
- return false;
+ return false;
}
} else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
if (Flags.isByVal())
// FIXME: Completely disable sibcall for Thumb1 since Thumb1RegisterInfo::
// emitEpilogue is not ready for them.
+ // Doing this is tricky, since the LDM/POP instruction on Thumb doesn't take
+ // LR. This means if we need to reload LR, it takes an extra instructions,
+ // which outweighs the value of the tail call; but here we don't know yet
+ // whether LR is going to be used. Probably the right approach is to
+ // generate the tail call here and turn it back into CALL/RET in
+ // emitEpilogue if LR is used.
if (Subtarget->isThumb1Only())
return false;
// (We could do this by loading the address of the callee into a register;
// that is an extra instruction over the direct call and burns a register
// as well, so is not likely to be a win.)
+
+ // It might be safe to remove this restriction on non-Darwin.
+
+ // Thumb1 PIC calls to external symbols use BX, so they can be tail calls,
+ // but we need to make sure there are enough registers; the only valid
+ // registers are the 4 used for parameters. We don't currently do this
+ // case.
if (isa<ExternalSymbolSDNode>(Callee))
return false;
"@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>;
def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
+ IIC_Br, "b\t$dst @ TAILCALL",
+ []>, Requires<[IsDarwin]>;
+
+ def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
IIC_Br, "b.w\t$dst @ TAILCALL",
[]>, Requires<[IsDarwin]>;
-; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=CHECKV4
-; RUN: llc < %s -march=arm -mattr=+v5t | FileCheck %s -check-prefix=CHECKV5
+; RUN: llc < %s -mtriple=arm-apple-darwin -march=arm | FileCheck %s -check-prefix=CHECKV4
+; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin -mattr=+v5t | FileCheck %s -check-prefix=CHECKV5
; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi\
; RUN: -relocation-model=pic | FileCheck %s -check-prefix=CHECKELF
%10 = call i32* %9(i32 %0, i32* null, i32 %1, i32* %2, i32* %3, i32* %4) ; <i32*> [#uses=1]
ret i32* %10
}
+
+define void @t4() {
+; CHECKV4: t4:
+; CHECKV4: b _t2 @ TAILCALL
+; CHECKV5: t4:
+; CHECKV5: b _t2 @ TAILCALL
+ tail call void @t2( ) ; <i32> [#uses=0]
+ ret void
+}
%tmp.upgrd.2 = tail call i32 %tmp( ) ; <i32> [#uses=0]
ret void
}
+
+define void @j() {
+; DARWIN: j:
+; DARWIN: b.w _f @ TAILCALL
+
+; LINUX: j:
+; LINUX: b.w f @ TAILCALL
+ tail call void @f()
+ ret void
+}
// Tail calls are other patterns that generate existing instructions.
if (Name == "TCRETURNdi" || Name == "TCRETURNdiND" ||
Name == "TCRETURNri" || Name == "TCRETURNriND" ||
- Name == "TAILJMPd" || Name == "TAILJMPdND" ||
- Name == "TAILJMPdNDt" ||
+ Name == "TAILJMPd" || Name == "TAILJMPdt" ||
+ Name == "TAILJMPdND" || Name == "TAILJMPdNDt" ||
Name == "TAILJMPr" || Name == "TAILJMPrND" ||
Name == "MOVr_TC")
return false;