Skip to content

Commit c35092c

Browse files
authored
[ARM] Fix HW thread pointer functionality (#130027)
- Separate check for hardware support of TLS register from check for support of Thumb2 encoding - Base decision to auto enable TLS on both hardware support and Thumb2 encoding support - Fix HW support check to correctly exclude M-Profile and include ARMV6K variants reference:https://reviews.llvm.org/D114116
1 parent f059e58 commit c35092c

File tree

2 files changed

+73
-11
lines changed

2 files changed

+73
-11
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,25 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) {
202202
T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
203203
}
204204

205-
// We follow GCC and support when the backend has support for the MRC/MCR
205+
// Check whether the architecture backend has support for the MRC/MCR
206206
// instructions that are used to set the hard thread pointer ("CP15 C13
207207
// Thread id").
208+
// This is not identical to ability to use the instruction, as the ARMV6K
209+
// variants can only use it in Arm mode since they don't support Thumb2
210+
// encoding.
208211
bool arm::isHardTPSupported(const llvm::Triple &Triple) {
209212
int Ver = getARMSubArchVersionNumber(Triple);
210213
llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
211-
return Triple.isARM() || AK == llvm::ARM::ArchKind::ARMV6T2 ||
214+
return AK == llvm::ARM::ArchKind::ARMV6K ||
215+
AK == llvm::ARM::ArchKind::ARMV6KZ ||
216+
(Ver >= 7 && !isARMMProfile(Triple));
217+
}
218+
219+
// Checks whether the architecture is capable of supporting the Thumb2 encoding
220+
static bool supportsThumb2Encoding(const llvm::Triple &Triple) {
221+
int Ver = arm::getARMSubArchVersionNumber(Triple);
222+
llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
223+
return AK == llvm::ARM::ArchKind::ARMV6T2 ||
212224
(Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline);
213225
}
214226

@@ -240,7 +252,13 @@ arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args,
240252
D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
241253
return ReadTPMode::Invalid;
242254
}
243-
return (isHardTPSupported(Triple) ? ReadTPMode::TPIDRURO : ReadTPMode::Soft);
255+
// In auto mode we enable HW mode only if both the hardware supports it and
256+
// the thumb2 encoding. For example ARMV6T2 supports thumb2, but not hardware.
257+
// ARMV6K has HW suport, but not thumb2. Otherwise we could enable it for
258+
// ARMV6K in thumb mode.
259+
bool autoUseHWTPMode =
260+
isHardTPSupported(Triple) && supportsThumb2Encoding(Triple);
261+
return autoUseHWTPMode ? ReadTPMode::TPIDRURO : ReadTPMode::Soft;
244262
}
245263

246264
void arm::setArchNameInTriple(const Driver &D, const ArgList &Args,

clang/test/Driver/arm-thread-pointer.c

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,26 @@
1414
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-TPIDRPRW %s
1515
// ARMv7_THREAD_POINTER-TPIDRPRW: "-target-feature" "+read-tp-tpidrprw"
1616

17-
// RUN: %clang --target=armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
18-
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
19-
// RUN: %clang --target=thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
20-
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
2117
// RUN: %clang --target=armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
2218
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
23-
// RUN: %clang --target=armv6-linux -mtp=cp15 -### -S %s 2>&1 | \
24-
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
25-
// RUN: %clang --target=armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \
26-
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
2719
// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-tpidruro"
2820

21+
// RUN: %clang --target=armv6k-linux -mtp=auto -### -S %s 2>&1 | \
22+
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER_AUTO %s
23+
// ARM_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"
24+
25+
// RUN: %clang --target=thumbv6k-apple-darwin -### -S %s 2>&1 | \
26+
// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_NO_AUTO %s
27+
// THUMBv6_THREAD_POINTER_NO_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"
28+
29+
// RUN: not %clang --target=thumbv6k-apple-darwin -mtp=cp15 -### -S %s 2>&1 | \
30+
// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_NO_HARD %s
31+
// THUMBv6_THREAD_POINTER_NO_HARD: unsupported option '-mtp=' for target 'thumbv6k-apple-darwin'
32+
33+
// RUN: not %clang --target=thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
34+
// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER_NO_HARD %s
35+
// ARM_THREAD_POINTER_NO_HARD: hardware TLS register is not supported for the armv6t2 sub-architecture
36+
2937
// RUN: %clang --target=armv5t-linux -mtp=cp15 -x assembler -### %s 2>&1 | \
3038
// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_ASSEMBLER %s
3139
// ARMv5_THREAD_POINTER_ASSEMBLER-NOT: hardware TLS register is not supported for the armv5 sub-architecture
@@ -47,3 +55,39 @@
4755
// RUN: %clang --target=armv7-linux -mtp=auto -### -S %s 2>&1 | \
4856
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_Auto %s
4957
// ARMv7_THREAD_POINTER_Auto: "-target-feature" "+read-tp-tpidruro"
58+
59+
// RUN: %clang --target=armv7-linux -mtp=cp15 -### -S %s 2>&1 | \
60+
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_HARD %s
61+
// ARMv7_THREAD_POINTER_HARD: "-target-feature" "+read-tp-tpidruro"
62+
63+
// RUN: %clang --target=armv7m-linux -mtp=auto -### -S %s 2>&1 | \
64+
// RUN: FileCheck -check-prefix=ARMv7m_THREAD_POINTER_Auto %s
65+
// ARMv7m_THREAD_POINTER_Auto-NOT: "-target-feature" "+read-tp-tpidruro"
66+
67+
// RUN: not %clang --target=armv7m-linux -mtp=cp15 -### -S %s 2>&1 | \
68+
// RUN: FileCheck -check-prefix=ARMv7m_THREAD_POINTER_HARD %s
69+
// ARMv7m_THREAD_POINTER_HARD: hardware TLS register is not supported for the thumbv7m sub-architecture
70+
71+
// RUN: %clang --target=armv5t-linux -mtp=auto -### -S %s 2>&1 | \
72+
// RUN: FileCheck -check-prefix=ARMv5t_THREAD_POINTER_Auto %s
73+
// ARMv5t_THREAD_POINTER_Auto-NOT: "-target-feature" "+read-tp-tpidruro"
74+
75+
// RUN: %clang --target=armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
76+
// RUN: FileCheck -check-prefix=ARMv6k_THREAD_POINTER_Auto %s
77+
// ARMv6k_THREAD_POINTER_Auto: "-target-feature" "+read-tp-tpidruro"
78+
79+
// RUN: not %clang --target=armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
80+
// RUN: FileCheck -check-prefix=ARMv6t2_THREAD_POINTER_HARD %s
81+
// ARMv6t2_THREAD_POINTER_HARD: hardware TLS register is not supported for the armv6t2 sub-architecture
82+
83+
// RUN: %clang --target=armv6t2-linux -mtp=auto -### -S %s 2>&1 | \
84+
// RUN: FileCheck -check-prefix=ARMV6t2_THREAD_POINTER_AUTO %s
85+
// ARMV6t2_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"
86+
87+
// RUN: %clang --target=armv6kz-linux -mtp=cp15 -### -S %s 2>&1 | \
88+
// RUN: FileCheck -check-prefix=ARMv6kz_THREAD_POINTER_HARD %s
89+
// ARMv6kz_THREAD_POINTER_HARD: "-target-feature" "+read-tp-tpidruro"
90+
91+
// RUN: %clang --target=armv6kz-linux -mtp=auto -### -S %s 2>&1 | \
92+
// RUN: FileCheck -check-prefix=ARMV6KZ_THREAD_POINTER_AUTO %s
93+
// ARMV6KZ_THREAD_POINTER_AUTO-NOT: "-target-feature" "+read-tp-tpidruro"

0 commit comments

Comments
 (0)