From 7651dd8359c70035ee12a3bafdb25062bb3e90a2 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 28 Jul 2015 22:26:45 +0000 Subject: [PATCH] [ARM] Pass subtarget feature "+strict-align". This commit changes the driver to save subtarget feature "+strict-align" to the IR instead of using backend option "arm-strict-align". This is needed for LTO. Also, move the logic in ARM backend that was deciding whether strict alignment should be forced to the front-end. rdar://problem/21529937 http://reviews.llvm.org/D11472 llvm-svn: 243489 --- clang/lib/Driver/Tools.cpp | 57 +++++++++++++++++++++------------- clang/test/Driver/apple-kext-mkernel.c | 4 +-- clang/test/Driver/arm-alignment.c | 31 ++++++++++++++++-- 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index f5cb90e..f554cae 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -799,6 +799,42 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("+long-calls"); } + // Kernel code has more strict alignment requirements. + if (KernelOrKext) + Features.push_back("+strict-align"); + else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, + options::OPT_munaligned_access)) { + if (A->getOption().matches(options::OPT_munaligned_access)) { + // No v6M core supports unaligned memory access (v6M ARM ARM A3.2). + if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) + D.Diag(diag::err_target_unsupported_unaligned) << "v6m"; + } else + Features.push_back("+strict-align"); + } else { + // Assume pre-ARMv6 doesn't support unaligned accesses. + // + // ARMv6 may or may not support unaligned accesses depending on the + // SCTLR.U bit, which is architecture-specific. We assume ARMv6 + // Darwin and NetBSD targets support unaligned accesses, and others don't. + // + // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit + // which raises an alignment fault on unaligned accesses. Linux + // defaults this bit to 0 and handles it as a system-wide (not + // per-process) setting. It is therefore safe to assume that ARMv7+ + // Linux targets support unaligned accesses. The same goes for NaCl. + // + // The above behavior is consistent with GCC. + int VersionNum = getARMSubArchVersionNumber(Triple); + if (Triple.isOSDarwin() || Triple.isOSNetBSD()) { + if (VersionNum < 6) + Features.push_back("+strict-align"); + } else if (Triple.isOSLinux() || Triple.isOSNaCl()) { + if (VersionNum < 7) + Features.push_back("+strict-align"); + } else + Features.push_back("+strict-align"); + } + // llvm does not support reserving registers in general. There is support // for reserving r9 on ARM though (defined as a platform-specific register // in ARM EABI). @@ -879,27 +915,6 @@ void Clang::AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs, CmdArgs.push_back("hard"); } - // Kernel code has more strict alignment requirements. - if (KernelOrKext) { - CmdArgs.push_back("-backend-option"); - CmdArgs.push_back("-arm-strict-align"); - } - - // -mkernel implies -mstrict-align; don't add the redundant option. - if (!KernelOrKext) { - if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, - options::OPT_munaligned_access)) { - CmdArgs.push_back("-backend-option"); - if (A->getOption().matches(options::OPT_mno_unaligned_access)) - CmdArgs.push_back("-arm-strict-align"); - else { - if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) - D.Diag(diag::err_target_unsupported_unaligned) << "v6m"; - CmdArgs.push_back("-arm-no-strict-align"); - } - } - } - // Forward the -mglobal-merge option for explicit control over the pass. if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, options::OPT_mno_global_merge)) { diff --git a/clang/test/Driver/apple-kext-mkernel.c b/clang/test/Driver/apple-kext-mkernel.c index 5f4f522..9c20cfc 100644 --- a/clang/test/Driver/apple-kext-mkernel.c +++ b/clang/test/Driver/apple-kext-mkernel.c @@ -12,8 +12,8 @@ // RUN: FileCheck --check-prefix=CHECK-ARM < %t %s // CHECK-ARM: "-target-feature" "+long-calls" -// CHECK-ARM: "-backend-option" "-arm-strict-align" -// CHECK-ARM-NOT: "-backend-option" "-arm-strict-align" +// CHECK-ARM: "-target-feature" "+strict-align" +// CHECK-ARM-NOT: "-target-feature" "+strict-align" // CHECK-ARM: "-fno-builtin" // CHECK-ARM: "-fno-rtti" // CHECK-ARM: "-fno-common" diff --git a/clang/test/Driver/arm-alignment.c b/clang/test/Driver/arm-alignment.c index 3fe5951..21caf83 100644 --- a/clang/test/Driver/arm-alignment.c +++ b/clang/test/Driver/arm-alignment.c @@ -7,6 +7,18 @@ // RUN: %clang -target arm-none-gnueabi -mno-unaligned-access -munaligned-access -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s +// RUN: %clang -target armv6-apple-darwin -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s + +// RUN: %clang -target armv6-netbsd-eabi -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s + +// RUN: %clang -target armv7-unknown-linux -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s + +// RUN: %clang -target armv7-unknown-nacl-gnueabihf -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s + // RUN: %clang -target aarch64-none-gnueabi -munaligned-access -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s @@ -16,7 +28,7 @@ // RUN: %clang -target aarch64-none-gnueabi -mno-unaligned-access -munaligned-access -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s -// CHECK-UNALIGNED-ARM: "-backend-option" "-arm-no-strict-align" +// CHECK-UNALIGNED-ARM-NOT: "-target-feature" "+strict-align" // CHECK-UNALIGNED-AARCH64: "-backend-option" "-aarch64-no-strict-align" @@ -32,6 +44,21 @@ // RUN: %clang -target arm-none-gnueabi -munaligned-access -mstrict-align -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s +// RUN: %clang -target arm-none-gnueabi -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s + +// RUN: %clang -target armv5-apple-darwin -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s + +// RUN: %clang -target armv5t-netbsd-eabi -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s + +// RUN: %clang -target armv6-unknown-linux -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s + +// RUN: %clang -target armv6-unknown-nacl-gnueabihf -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s + // RUN: %clang -target aarch64-none-gnueabi -mno-unaligned-access -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s @@ -47,7 +74,7 @@ // RUN: %clang -target aarch64-none-gnueabi -mkernel -mno-unaligned-access -### %s 2> %t // RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s -// CHECK-ALIGNED-ARM: "-backend-option" "-arm-strict-align" +// CHECK-ALIGNED-ARM: "-target-feature" "+strict-align" // CHECK-ALIGNED-AARCH64: "-backend-option" "-aarch64-strict-align" // Make sure that v6M cores always trigger the unsupported aligned accesses error -- 2.7.4