From 0110ac66ebd1e59e6ac163e13670f36d091084f6 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 19 Jun 2010 01:01:32 +0000 Subject: [PATCH] Disable sibcall optimization for Thumb1 for now since Thumb1RegisterInfo::emitEpilogue is not expecting them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106368 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 25 +++++++++++++------ test/CodeGen/ARM/call-tc.ll | 11 +++++--- test/CodeGen/Thumb/2010-06-18-SibCallCrash.ll | 8 ++++++ test/CodeGen/Thumb2/thumb2-call-tc.ll | 2 +- 4 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 test/CodeGen/Thumb/2010-06-18-SibCallCrash.ll diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 3dfd080c0af..d0c40229d40 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1389,7 +1389,6 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, const SmallVectorImpl &Outs, const SmallVectorImpl &Ins, SelectionDAG& DAG) const { - const Function *CallerF = DAG.getMachineFunction().getFunction(); CallingConv::ID CallerCC = CallerF->getCallingConv(); bool CCMatch = CallerCC == CalleeCC; @@ -1407,19 +1406,29 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, if (isCalleeStructRet || isCallerStructRet) return false; - // On Thumb, for the moment, we can only do this to functions defined in this - // compilation, or to indirect calls. A Thumb B to an ARM function is not - // easily fixed up in the linker, unlike BL. - if (Subtarget->isThumb()) { - if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + // FIXME: Completely disable sibcal for Thumb1 since Thumb1RegisterInfo:: + // emitEpilogue is not ready for them. + if (Subtarget->isThumb1Only()) + return false; + + if (isa(Callee)) + return false; + + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + if (Subtarget->isThumb1Only()) + return false; + + // On Thumb, for the moment, we can only do this to functions defined in this + // compilation, or to indirect calls. A Thumb B to an ARM function is not + // easily fixed up in the linker, unlike BL. + if (Subtarget->isThumb()) { const GlobalValue *GV = G->getGlobal(); if (GV->isDeclaration() || GV->isWeakForLinker()) return false; - } else if (isa(Callee)) { - return false; } } + // If the calling conventions do not match, then we'd better make sure the // results are returned in the same way as what the caller expects. if (!CCMatch) { diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll index 8103fab2092..2bbdb91c90b 100644 --- a/test/CodeGen/ARM/call-tc.ll +++ b/test/CodeGen/ARM/call-tc.ll @@ -7,22 +7,25 @@ declare void @g(i32, i32, i32, i32) -define void @f() { +define void @t1() { +; CHECKELF: t1: ; CHECKELF: PLT call void @g( i32 1, i32 2, i32 3, i32 4 ) ret void } -define void @g.upgrd.1() { +define void @t2() { +; CHECKV4: t2: ; CHECKV4: bx r0 @ TAILCALL +; CHECKV5: t2: ; CHECKV5: bx r0 @ TAILCALL %tmp = load i32 ()** @t ; [#uses=1] %tmp.upgrd.2 = tail call i32 %tmp( ) ; [#uses=0] ret void } -define i32* @m_231b(i32, i32, i32*, i32*, i32*) nounwind { -; CHECKV4: m_231b +define i32* @t3(i32, i32, i32*, i32*, i32*) nounwind { +; CHECKV4: t3: ; CHECKV4: bx r{{.*}} BB0: %5 = inttoptr i32 %0 to i32* ; [#uses=1] diff --git a/test/CodeGen/Thumb/2010-06-18-SibCallCrash.ll b/test/CodeGen/Thumb/2010-06-18-SibCallCrash.ll new file mode 100644 index 00000000000..ad8b064bf4b --- /dev/null +++ b/test/CodeGen/Thumb/2010-06-18-SibCallCrash.ll @@ -0,0 +1,8 @@ +; RUN: llc -march=thumb < %s +; rdar://8104457 + +define arm_apcscc void @t(i32* %m) nounwind { +entry: + tail call arm_apcscc void undef(i32* %m, i16 zeroext undef) nounwind + ret void +} diff --git a/test/CodeGen/Thumb2/thumb2-call-tc.ll b/test/CodeGen/Thumb2/thumb2-call-tc.ll index d31ae0cc455..fe47e348ab2 100644 --- a/test/CodeGen/Thumb2/thumb2-call-tc.ll +++ b/test/CodeGen/Thumb2/thumb2-call-tc.ll @@ -11,7 +11,7 @@ define void @f() { ; LINUX: f: ; LINUX: bl g - call void @g( i32 1, i32 2, i32 3, i32 4 ) + tail call void @g( i32 1, i32 2, i32 3, i32 4 ) ret void }