From 1c8fccbc12e6348c8003aff9b89078324257fc4e Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Wed, 23 May 2012 18:38:57 +0000 Subject: [PATCH] [arm-fast-isel] Add support for non-global callee. Patch by Jush Lu . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157336 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 24 +++++++++++++++++------- test/CodeGen/ARM/fast-isel-call.ll | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 97131cd6987..c13f283a847 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -2216,11 +2216,6 @@ bool ARMFastISel::SelectCall(const Instruction *I, // Can't handle inline asm. if (isa(Callee)) return false; - // Only handle global variable Callees. - const GlobalValue *GV = dyn_cast(Callee); - if (!GV) - return false; - // Check the calling convention. ImmutableCallSite CS(CI); CallingConv::ID CC = CS.getCallingConv(); @@ -2313,18 +2308,33 @@ bool ARMFastISel::SelectCall(const Instruction *I, // Issue the call. MachineInstrBuilder MIB; + const GlobalValue *GV = dyn_cast(Callee); unsigned CallOpc = ARMSelectCallOp(GV); + unsigned CalleeReg = 0; + + if (!GV){ + CallOpc = isThumb2 ? ARM::tBLXr : ARM::BLX; + CalleeReg = getRegForValue(Callee); + if (CalleeReg == 0) return false; + } + // Explicitly adding the predicate here. if(isThumb2) { // Explicitly adding the predicate here. MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc))); - if (!IntrMemName) + if (!GV) + MIB.addReg(CalleeReg); + else if (!IntrMemName) MIB.addGlobalAddress(GV, 0, 0); else MIB.addExternalSymbol(IntrMemName, 0); } else { - if (!IntrMemName) + if (!GV) + MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(CallOpc)) + .addReg(CalleeReg)); + else if (!IntrMemName) // Explicitly adding the predicate here. MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc)) diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll index dd460b2a036..10d6746acfd 100644 --- a/test/CodeGen/ARM/fast-isel-call.ll +++ b/test/CodeGen/ARM/fast-isel-call.ll @@ -126,3 +126,23 @@ entry: } declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext) + +define i32 @bar0(i32 %i) nounwind { + ret i32 0 +} + +define void @foo3() uwtable { +; ARM: movw r0, #0 +; ARM: movw r1, :lower16:_bar0 +; ARM: movt r1, :upper16:_bar0 +; ARM: blx r1 +; THUMB: movs r0, #0 +; THUMB: movw r1, :lower16:_bar0 +; THUMB: movt r1, :upper16:_bar0 +; THUMB: blx r1 + %fptr = alloca i32 (i32)*, align 8 + store i32 (i32)* @bar0, i32 (i32)** %fptr, align 8 + %1 = load i32 (i32)** %fptr, align 8 + %call = call i32 %1(i32 0) + ret void +}