nickdesaulniers created this revision. nickdesaulniers added reviewers: ardb, peter.smith, ostannard, DavidSpickett. Herald added a subscriber: kristof.beyls. nickdesaulniers requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Building -march=armv6k Linux kernels with -mtp=cp15 fails to compile: error: hardware TLS register is not supported for the arm sub-architecture @ardb found docs for ARM1176JZF-S (ARMv6K) that reference hard thread pointer. Relax our ARMv6 check for cases where we're targeting ARM via -marm (vs Thumb1 via -mthumb). This more closely matches the KConfig requirements for where we plan to use these (ie. ARMv6K, ARMv7 (arm or thumb2)). Fixes: https://github.com/ClangBuiltLinux/linux/issues/1502 Link: https://developer.arm.com/documentation/ddi0301/h/system-control-coprocessor/system-control-processor-registers/c13--thread-and-process-id-registers Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D114116 Files: clang/lib/Driver/ToolChains/Arch/ARM.cpp clang/lib/Driver/ToolChains/Arch/ARM.h clang/test/Driver/clang-translation.c Index: clang/test/Driver/clang-translation.c =================================================================== --- clang/test/Driver/clang-translation.c +++ clang/test/Driver/clang-translation.c @@ -115,16 +115,22 @@ // ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" // RUN: %clang -target armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \ -// RUN: FileCheck -check-prefix=ARMv6T2_THREAD_POINTER-HARD %s -// ARMv6T2_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// RUN: %clang -target armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// RUN: %clang -target armv6-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" // RUN: %clang -target armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_UNSUPP %s // ARMv5_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv5 sub-architecture -// RUN: %clang -target thumbv6-linux -mtp=cp15 -### -S %s 2>&1 | \ -// RUN: FileCheck -check-prefix=ARMv6_THREAD_POINTER_UNSUPP %s -// ARMv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv6 sub-architecture +// RUN: %clang -target armv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s +// RUN: %clang -target thumbv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s +// THUMBv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the thumbv6 sub-architecture // RUN: %clang -target armv7-linux -mtp=soft -### -S %s 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s Index: clang/lib/Driver/ToolChains/Arch/ARM.h =================================================================== --- clang/lib/Driver/ToolChains/Arch/ARM.h +++ clang/lib/Driver/ToolChains/Arch/ARM.h @@ -53,6 +53,7 @@ const llvm::opt::ArgList &Args); void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple); +bool isHardTPSupported(const llvm::Triple &Triple); ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple); void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -147,6 +147,15 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// The backend does not have support for hard thread pointers when targeting +// Thumb1. +bool arm::isHardTPSupported(const llvm::Triple &Triple) { + int Ver = getARMSubArchVersionNumber(Triple); + llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName()); + return Ver >= 7 || AK == llvm::ARM::ArchKind::ARMV6T2 || + (Ver == 6 && Triple.isARM()); +} + // Select mode for reading thread pointer (-mtp=soft/cp15). arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args, const llvm::Triple &Triple) { @@ -156,10 +165,7 @@ .Case("cp15", ReadTPMode::Cp15) .Case("soft", ReadTPMode::Soft) .Default(ReadTPMode::Invalid); - if (ThreadPointer == ReadTPMode::Cp15 && - getARMSubArchVersionNumber(Triple) < 7 && - llvm::ARM::parseArch(Triple.getArchName()) != - llvm::ARM::ArchKind::ARMV6T2) { + if (ThreadPointer == ReadTPMode::Cp15 && !isHardTPSupported(Triple)) { D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName(); return ReadTPMode::Invalid; } @@ -430,7 +436,6 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args); - arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args, Triple); llvm::Optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch; @@ -482,7 +487,7 @@ } } - if (ThreadPointer == arm::ReadTPMode::Cp15) + if (getReadTPMode(D, Args, Triple) == ReadTPMode::Cp15) Features.push_back("+read-tp-hard"); const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
Index: clang/test/Driver/clang-translation.c =================================================================== --- clang/test/Driver/clang-translation.c +++ clang/test/Driver/clang-translation.c @@ -115,16 +115,22 @@ // ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" // RUN: %clang -target armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \ -// RUN: FileCheck -check-prefix=ARMv6T2_THREAD_POINTER-HARD %s -// ARMv6T2_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// RUN: %clang -target armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// RUN: %clang -target armv6-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s +// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" // RUN: %clang -target armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_UNSUPP %s // ARMv5_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv5 sub-architecture -// RUN: %clang -target thumbv6-linux -mtp=cp15 -### -S %s 2>&1 | \ -// RUN: FileCheck -check-prefix=ARMv6_THREAD_POINTER_UNSUPP %s -// ARMv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv6 sub-architecture +// RUN: %clang -target armv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s +// RUN: %clang -target thumbv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s +// THUMBv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the thumbv6 sub-architecture // RUN: %clang -target armv7-linux -mtp=soft -### -S %s 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s Index: clang/lib/Driver/ToolChains/Arch/ARM.h =================================================================== --- clang/lib/Driver/ToolChains/Arch/ARM.h +++ clang/lib/Driver/ToolChains/Arch/ARM.h @@ -53,6 +53,7 @@ const llvm::opt::ArgList &Args); void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple); +bool isHardTPSupported(const llvm::Triple &Triple); ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple); void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -147,6 +147,15 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// The backend does not have support for hard thread pointers when targeting +// Thumb1. +bool arm::isHardTPSupported(const llvm::Triple &Triple) { + int Ver = getARMSubArchVersionNumber(Triple); + llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName()); + return Ver >= 7 || AK == llvm::ARM::ArchKind::ARMV6T2 || + (Ver == 6 && Triple.isARM()); +} + // Select mode for reading thread pointer (-mtp=soft/cp15). arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args, const llvm::Triple &Triple) { @@ -156,10 +165,7 @@ .Case("cp15", ReadTPMode::Cp15) .Case("soft", ReadTPMode::Soft) .Default(ReadTPMode::Invalid); - if (ThreadPointer == ReadTPMode::Cp15 && - getARMSubArchVersionNumber(Triple) < 7 && - llvm::ARM::parseArch(Triple.getArchName()) != - llvm::ARM::ArchKind::ARMV6T2) { + if (ThreadPointer == ReadTPMode::Cp15 && !isHardTPSupported(Triple)) { D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName(); return ReadTPMode::Invalid; } @@ -430,7 +436,6 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args); - arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args, Triple); llvm::Optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch; @@ -482,7 +487,7 @@ } } - if (ThreadPointer == arm::ReadTPMode::Cp15) + if (getReadTPMode(D, Args, Triple) == ReadTPMode::Cp15) Features.push_back("+read-tp-hard"); const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits