Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -638,6 +638,8 @@ const ArgList &Args, std::vector &Features, bool ForAS) { + bool KernelOrKext = + Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple); if (!ForAS) { // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these @@ -705,6 +707,14 @@ if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_1a) { Features.insert(Features.begin(), "+v8.1a"); } + + if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, + options::OPT_mno_long_calls)) { + if (A->getOption().matches(options::OPT_mlong_calls)) + Features.push_back("+long-calls"); + } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6))) { + Features.push_back("+long-calls"); + } } void Clang::AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs, @@ -778,11 +788,6 @@ // Kernel code has more strict alignment requirements. if (KernelOrKext) { - if (!Triple.isiOS() || Triple.isOSVersionLT(6)) { - CmdArgs.push_back("-backend-option"); - CmdArgs.push_back("-arm-long-calls"); - } - CmdArgs.push_back("-backend-option"); CmdArgs.push_back("-arm-strict-align"); @@ -4070,17 +4075,6 @@ CmdArgs.push_back("-arm-restrict-it"); } - if (TT.getArch() == llvm::Triple::arm || - TT.getArch() == llvm::Triple::thumb) { - if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, - options::OPT_mno_long_calls)) { - if (A->getOption().matches(options::OPT_mlong_calls)) { - CmdArgs.push_back("-backend-option"); - CmdArgs.push_back("-arm-long-calls"); - } - } - } - // Forward -f options with positive and negative forms; we translate // these by hand. if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) { Index: test/CodeGen/arm-long-calls.c =================================================================== --- /dev/null +++ test/CodeGen/arm-long-calls.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-ios5 -target-feature +long-calls -emit-llvm -o - %s | FileCheck -check-prefix=LONGCALL %s +// RUN: %clang_cc1 -triple thumbv7-apple-ios5 -emit-llvm -o - %s | FileCheck -check-prefix=NOLONGCALL %s + +// LONGCALL: attributes #0 = { {{.*}} "target-features"="+long-calls" +// NOLONGCALL-NOT: attributes #0 = { {{.*}} "target-features"="+long-calls" + +int foo1(int a) { return a; } Index: test/Driver/apple-kext-mkernel.c =================================================================== --- test/Driver/apple-kext-mkernel.c +++ test/Driver/apple-kext-mkernel.c @@ -11,7 +11,7 @@ // RUN: -arch armv7 -mkernel -mstrict-align -### -fsyntax-only %s 2> %t // RUN: FileCheck --check-prefix=CHECK-ARM < %t %s -// CHECK-ARM: "-backend-option" "-arm-long-calls" +// CHECK-ARM: "-target-feature" "+long-calls" // CHECK-ARM: "-backend-option" "-arm-strict-align" // CHECK-ARM-NOT: "-backend-option" "-arm-strict-align" // CHECK-ARM: "-fno-builtin" Index: test/Driver/arm-long-calls.c =================================================================== --- test/Driver/arm-long-calls.c +++ test/Driver/arm-long-calls.c @@ -7,9 +7,9 @@ // RUN: %clang -target armv7-eabi -### -mlong-calls -mno-long-calls %s 2>&1 \ // RUN: | FileCheck %s -check-prefix CHECK-NO-LONG-CALLS -// CHECK-DEFAULT-NOT: "-backend-option" "-arm-long-calls" +// CHECK-DEFAULT-NOT: "-target-feature" "+long-calls" -// CHECK-LONG-CALLS: "-backend-option" "-arm-long-calls" +// CHECK-LONG-CALLS: "-target-feature" "+long-calls" -// CHECK-NO-LONG-CALLS-NOT: "-backend-option" "-arm-long-calls" +// CHECK-NO-LONG-CALLS-NOT: "-target-feature" "+long-calls"