Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -1595,8 +1595,9 @@ bool isLocalARMFunc = false; ARMFunctionInfo *AFI = MF.getInfo(); - if (EnableARMLongCalls) { - assert (getTargetMachine().getRelocationModel() == Reloc::Static + if (EnableARMLongCalls || Subtarget->usesLongCalls()) { + assert ((getTargetMachine().getRelocationModel() == Reloc::Static || + Subtarget->isTargetWindows()) && "long-calls with non-static relocation model!"); // Handle a global address or an external symbol. If it's not one of // those, the target's already in a register, so we don't need to do Index: lib/Target/ARM/ARMSubtarget.h =================================================================== --- lib/Target/ARM/ARMSubtarget.h +++ lib/Target/ARM/ARMSubtarget.h @@ -112,6 +112,9 @@ /// Thumb. bool SupportsTailCall; + /// UsesLongCalls - True if the OS uses long calls. + bool UsesLongCalls; + /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF /// only so far) bool HasFP16; @@ -384,6 +387,8 @@ bool useMovt() const { return UseMovt && !isMinSize(); } bool supportsTailCall() const { return SupportsTailCall; } + bool usesLongCalls() const { return UsesLongCalls; } + bool allowsUnalignedMem() const { return AllowsUnalignedMem; } bool restrictIT() const { return RestrictIT; } Index: lib/Target/ARM/ARMSubtarget.cpp =================================================================== --- lib/Target/ARM/ARMSubtarget.cpp +++ lib/Target/ARM/ARMSubtarget.cpp @@ -117,6 +117,7 @@ IsR9Reserved = ReserveR9; UseMovt = false; SupportsTailCall = false; + UsesLongCalls = false; HasFP16 = false; HasD16 = false; HasHardwareDivide = false; @@ -216,6 +217,8 @@ if (isTargetWindows()) { TargetABI = ARM_ABI_AAPCS; NoARM = true; + + UsesLongCalls = true; } if (isAAPCS_ABI()) Index: test/CodeGen/ARM/Windows/calls.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/Windows/calls.ll @@ -0,0 +1,36 @@ +; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s + +declare void @external() + +define void @internal() nounwind { +entry: + ret void +} + +define void @call_external() nounwind { +entry: + tail call void @external() + ret void +} + +define void @call_internal() nounwind { +entry: + tail call void @internal() + ret void +} + +; CHECK: call_external: +; CHECK: ldr r0, .L[[CPI:[^ ]*]] +; CHECK: bx r0 +; CHECK: .align 2 +; CHECK: .L[[CPI]] +; CHECK: .long external + +; CHECK: call_internal +; CHECK: ldr r0, .L[[CPI:[^ ]*]] +; FIXME: relax this to a bl function +; CHECK: bx r0 +; CHECK: .align 2 +; CHECK: .L[[CPI]] +; CHECK: .long internal +