diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 8f646deb266..3d026be5131 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1439,9 +1439,11 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); bool isThisReturn = false; bool isSibCall = false; + // Disable tail calls if they're not supported. - if (!Subtarget->supportsTailCall()) + if (!Subtarget->supportsTailCall() || MF.getTarget().Options.DisableTailCalls) isTailCall = false; + if (isTailCall) { // Check if it's really possible to do a tail call. isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, @@ -2273,7 +2275,7 @@ bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { if (!Subtarget->supportsTailCall()) return false; - if (!CI->isTailCall()) + if (!CI->isTailCall() || getTargetMachine().Options.DisableTailCalls) return false; return !Subtarget->isThumb1Only(); diff --git a/test/CodeGen/ARM/tail-call.ll b/test/CodeGen/ARM/tail-call.ll new file mode 100644 index 00000000000..270b41d956d --- /dev/null +++ b/test/CodeGen/ARM/tail-call.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple armv7 -O0 -o - < %s | FileCheck %s -check-prefix CHECK-TAIL +; RUN: llc -mtriple armv7 -O0 -disable-tail-calls -o - < %s \ +; RUN: | FileCheck %s -check-prefix CHECK-NO-TAIL + +declare i32 @callee(i32 %i) + +define i32 @caller(i32 %i) { +entry: + %r = tail call i32 @callee(i32 %i) + ret i32 %r +} + +; CHECK-LABEL: caller +; CHECK-TAIL: b callee + +; CHECK-LABEL: caller +; CHECK-NO-TAIL: push {lr} +; CHECK-NO-TAIL: bl callee +; CHECK-NO-TAIL: pop {lr} +; CHECK-NO-TAIL: bx lr +