Skip to content

Commit 2477272

Browse files
committed
[ARM] reject -mtp=cp15 if target subarch does not support it
Currently, we permit -mtp=cp15 even for targets that don't implement the TLS register. When building for ARMv6 or earlier, this means we emit instructions that will UNDEF at runtime. For Thumb1, passing -mtp=cp15 will trigger an assert in the backend. So let's add some diagnostics to ensure that -mtp=cp15 is only accepted for ARMv6T2 or newer. Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D113026
1 parent 22a1aa5 commit 2477272

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

clang/lib/Driver/ToolChains/Arch/ARM.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,21 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) {
148148
}
149149

150150
// Select mode for reading thread pointer (-mtp=soft/cp15).
151-
arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args) {
151+
arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args,
152+
const llvm::Triple &Triple) {
152153
if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
153154
arm::ReadTPMode ThreadPointer =
154155
llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
155156
.Case("cp15", ReadTPMode::Cp15)
156157
.Case("soft", ReadTPMode::Soft)
157158
.Default(ReadTPMode::Invalid);
159+
if (ThreadPointer == ReadTPMode::Cp15 &&
160+
getARMSubArchVersionNumber(Triple) < 7 &&
161+
llvm::ARM::parseArch(Triple.getArchName()) !=
162+
llvm::ARM::ArchKind::ARMV6T2) {
163+
D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
164+
return ReadTPMode::Invalid;
165+
}
158166
if (ThreadPointer != ReadTPMode::Invalid)
159167
return ThreadPointer;
160168
if (StringRef(A->getValue()).empty())
@@ -422,7 +430,7 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
422430
bool KernelOrKext =
423431
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
424432
arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args);
425-
arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args);
433+
arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args, Triple);
426434
llvm::Optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv,
427435
WaArch;
428436

clang/lib/Driver/ToolChains/Arch/ARM.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ FloatABI getARMFloatABI(const Driver &D, const llvm::Triple &Triple,
5353
const llvm::opt::ArgList &Args);
5454
void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args,
5555
llvm::Triple &triple);
56-
ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args);
56+
ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args,
57+
const llvm::Triple &Triple);
5758
void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args,
5859
types::ID InputType, llvm::Triple &Triple);
5960

clang/test/Driver/clang-translation.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,27 @@
110110
// ARMV5E: "-cc1"
111111
// ARMV5E: "-target-cpu" "arm1022e"
112112

113-
// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \
113+
// RUN: %clang -target armv7-linux -mtp=cp15 -### -S %s 2>&1 | \
114114
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s
115115
// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard"
116116

117-
// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \
117+
// RUN: %clang -target armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
118+
// RUN: FileCheck -check-prefix=ARMv6T2_THREAD_POINTER-HARD %s
119+
// ARMv6T2_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard"
120+
121+
// RUN: %clang -target armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \
122+
// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_UNSUPP %s
123+
// ARMv5_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv5 sub-architecture
124+
125+
// RUN: %clang -target thumbv6-linux -mtp=cp15 -### -S %s 2>&1 | \
126+
// RUN: FileCheck -check-prefix=ARMv6_THREAD_POINTER_UNSUPP %s
127+
// ARMv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv6 sub-architecture
128+
129+
// RUN: %clang -target armv7-linux -mtp=soft -### -S %s 2>&1 | \
118130
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s
119131
// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard"
120132

121-
// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \
133+
// RUN: %clang -target armv7-linux -### -S %s 2>&1 | \
122134
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s
123135
// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard"
124136

0 commit comments

Comments
 (0)