Skip to content

Commit 89c1bf1

Browse files
authored
[ARM] __ARM_ARCH macro definition fix (#81493)
This patch changes how the macro __ARM_ARCH is defined to match its defintion in the ACLE. In ACLE 5.4.1, __ARM_ARCH is defined as equal to the major architecture version for ISAs up to and including v8. From v8.1 onwards, its definition is changed to include minor versions, such that for an architecture vX.Y, __ARM_ARCH = X*100 + Y. Before this patch, LLVM defined __ARM_ARCH using only the major architecture version for all architecture versions. This patch adds functionality to define __ARM_ARCH correctly for architectures greater than or equal to v8.1.
1 parent 38c706e commit 89c1bf1

File tree

8 files changed

+112
-22
lines changed

8 files changed

+112
-22
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ X86 Support
255255
Arm and AArch64 Support
256256
^^^^^^^^^^^^^^^^^^^^^^^
257257

258+
- Fixed the incorrect definition of the __ARM_ARCH macro for architectures greater than or equal to v8.1.
259+
258260
Android Support
259261
^^^^^^^^^^^^^^^
260262

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,20 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
367367

368368
// ACLE predefines. Many can only have one possible value on v8 AArch64.
369369
Builder.defineMacro("__ARM_ACLE", "200");
370-
Builder.defineMacro("__ARM_ARCH",
371-
std::to_string(ArchInfo->Version.getMajor()));
370+
371+
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA.
372+
// For ISAs up to and including v8, __ARM_ARCH is equal to the major version
373+
// number. For ISAs from v8.1 onwards, __ARM_ARCH is scaled up to include the
374+
// minor version number, e.g. for ARM architecture ARMvX.Y:
375+
// __ARM_ARCH = X * 100 + Y.
376+
if (ArchInfo->Version.getMajor() == 8 && ArchInfo->Version.getMinor() == 0)
377+
Builder.defineMacro("__ARM_ARCH",
378+
std::to_string(ArchInfo->Version.getMajor()));
379+
else
380+
Builder.defineMacro("__ARM_ARCH",
381+
std::to_string(ArchInfo->Version.getMajor() * 100 +
382+
ArchInfo->Version.getMinor().value()));
383+
372384
Builder.defineMacro("__ARM_ARCH_PROFILE",
373385
std::string("'") + (char)ArchInfo->Profile + "'");
374386

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
130130
SubArch = llvm::ARM::getSubArch(ArchKind);
131131
ArchProfile = llvm::ARM::parseArchProfile(SubArch);
132132
ArchVersion = llvm::ARM::parseArchVersion(SubArch);
133+
ArchMinorVersion = llvm::ARM::parseArchMinorVersion(SubArch);
133134

134135
// cache CPU related strings
135136
CPUAttr = getCPUAttr();
@@ -736,9 +737,16 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
736737
if (!CPUAttr.empty())
737738
Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
738739

739-
// ACLE 6.4.1 ARM/Thumb instruction set architecture
740-
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA
741-
Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
740+
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA.
741+
// For ISAs up to and including v8, __ARM_ARCH is equal to the major version
742+
// number. For ISAs from v8.1 onwards, __ARM_ARCH is scaled up to include the
743+
// minor version number, e.g. for ARM architecture ARMvX.Y:
744+
// __ARM_ARCH = X * 100 + Y.
745+
if (ArchVersion >= 9 || ArchMinorVersion != 0)
746+
Builder.defineMacro("__ARM_ARCH",
747+
Twine(ArchVersion * 100 + ArchMinorVersion));
748+
else
749+
Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
742750

743751
if (ArchVersion >= 8) {
744752
// ACLE 6.5.7 Crypto Extension

clang/lib/Basic/Targets/ARM.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
6060
llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T;
6161
llvm::ARM::ProfileKind ArchProfile;
6262
unsigned ArchVersion;
63+
unsigned ArchMinorVersion;
6364

6465
LLVM_PREFERRED_TYPE(FPUMode)
6566
unsigned FPU : 5;

clang/test/Preprocessor/arm-target-features.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@
737737

738738
// Test whether predefines are as expected when targeting cortex-m55 (softfp FP ABI as default).
739739
// RUN: %clang -target arm-eabi -mcpu=cortex-m55 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M55 %s
740-
// M55: #define __ARM_ARCH 8
740+
// M55: #define __ARM_ARCH 801
741741
// M55: #define __ARM_ARCH_8_1M_MAIN__ 1
742742
// M55: #define __ARM_ARCH_EXT_IDIV__ 1
743743
// M55-NOT: __ARM_ARCH_ISA_ARM
@@ -764,7 +764,7 @@
764764
// KRAIT-ALLOW-FP-INSTR:#define __ARM_VFPV4__ 1
765765

766766
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M %s
767-
// CHECK-V81M: #define __ARM_ARCH 8
767+
// CHECK-V81M: #define __ARM_ARCH 801
768768
// CHECK-V81M: #define __ARM_ARCH_8_1M_MAIN__ 1
769769
// CHECK-V81M: #define __ARM_ARCH_ISA_THUMB 2
770770
// CHECK-V81M: #define __ARM_ARCH_PROFILE 'M'
@@ -821,14 +821,14 @@
821821
// CHECK-V8M-CDE-MASK2: #define __ARM_FEATURE_CDE_COPROC 0xff
822822

823823
// RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81A %s
824-
// CHECK-V81A: #define __ARM_ARCH 8
824+
// CHECK-V81A: #define __ARM_ARCH 801
825825
// CHECK-V81A: #define __ARM_ARCH_8_1A__ 1
826826
// CHECK-V81A: #define __ARM_ARCH_PROFILE 'A'
827827
// CHECK-V81A: #define __ARM_FEATURE_QRDMX 1
828828
// CHECK-V81A: #define __ARM_FP 0xe
829829

830830
// RUN: %clang -target armv8.2a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V82A %s
831-
// CHECK-V82A: #define __ARM_ARCH 8
831+
// CHECK-V82A: #define __ARM_ARCH 802
832832
// CHECK-V82A: #define __ARM_ARCH_8_2A__ 1
833833
// CHECK-V82A: #define __ARM_ARCH_PROFILE 'A'
834834
// CHECK-V82A: #define __ARM_FEATURE_QRDMX 1
@@ -838,67 +838,67 @@
838838
// CHECK-DRIVERKIT-NOT: #define __ARM_PCS_VFP 1
839839

840840
// RUN: %clang -target armv8.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V83A %s
841-
// CHECK-V83A: #define __ARM_ARCH 8
841+
// CHECK-V83A: #define __ARM_ARCH 803
842842
// CHECK-V83A: #define __ARM_ARCH_8_3A__ 1
843843
// CHECK-V83A: #define __ARM_ARCH_PROFILE 'A'
844844

845845
// RUN: %clang -target armv8.4a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V84A %s
846-
// CHECK-V84A: #define __ARM_ARCH 8
846+
// CHECK-V84A: #define __ARM_ARCH 804
847847
// CHECK-V84A: #define __ARM_ARCH_8_4A__ 1
848848
// CHECK-V84A: #define __ARM_ARCH_PROFILE 'A'
849849

850850
// RUN: %clang -target armv8.5a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V85A %s
851-
// CHECK-V85A: #define __ARM_ARCH 8
851+
// CHECK-V85A: #define __ARM_ARCH 805
852852
// CHECK-V85A: #define __ARM_ARCH_8_5A__ 1
853853
// CHECK-V85A: #define __ARM_ARCH_PROFILE 'A'
854854

855855
// RUN: %clang -target armv8.6a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V86A %s
856-
// CHECK-V86A: #define __ARM_ARCH 8
856+
// CHECK-V86A: #define __ARM_ARCH 806
857857
// CHECK-V86A: #define __ARM_ARCH_8_6A__ 1
858858
// CHECK-V86A: #define __ARM_ARCH_PROFILE 'A'
859859

860860
// RUN: %clang -target armv8.7a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V87A %s
861-
// CHECK-V87A: #define __ARM_ARCH 8
861+
// CHECK-V87A: #define __ARM_ARCH 807
862862
// CHECK-V87A: #define __ARM_ARCH_8_7A__ 1
863863
// CHECK-V87A: #define __ARM_ARCH_PROFILE 'A'
864864

865865
// RUN: %clang -target armv8.8a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V88A %s
866-
// CHECK-V88A: #define __ARM_ARCH 8
866+
// CHECK-V88A: #define __ARM_ARCH 808
867867
// CHECK-V88A: #define __ARM_ARCH_8_8A__ 1
868868
// CHECK-V88A: #define __ARM_ARCH_PROFILE 'A'
869869

870870
// RUN: %clang -target armv8.9a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V89A %s
871-
// CHECK-V89A: #define __ARM_ARCH 8
871+
// CHECK-V89A: #define __ARM_ARCH 809
872872
// CHECK-V89A: #define __ARM_ARCH_8_9A__ 1
873873
// CHECK-V89A: #define __ARM_ARCH_PROFILE 'A'
874874

875875
// RUN: %clang -target armv9a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V9A %s
876-
// CHECK-V9A: #define __ARM_ARCH 9
876+
// CHECK-V9A: #define __ARM_ARCH 900
877877
// CHECK-V9A: #define __ARM_ARCH_9A__ 1
878878
// CHECK-V9A: #define __ARM_ARCH_PROFILE 'A'
879879

880880
// RUN: %clang -target armv9.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V91A %s
881-
// CHECK-V91A: #define __ARM_ARCH 9
881+
// CHECK-V91A: #define __ARM_ARCH 901
882882
// CHECK-V91A: #define __ARM_ARCH_9_1A__ 1
883883
// CHECK-V91A: #define __ARM_ARCH_PROFILE 'A'
884884

885885
// RUN: %clang -target armv9.2a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V92A %s
886-
// CHECK-V92A: #define __ARM_ARCH 9
886+
// CHECK-V92A: #define __ARM_ARCH 902
887887
// CHECK-V92A: #define __ARM_ARCH_9_2A__ 1
888888
// CHECK-V92A: #define __ARM_ARCH_PROFILE 'A'
889889

890890
// RUN: %clang -target armv9.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V93A %s
891-
// CHECK-V93A: #define __ARM_ARCH 9
891+
// CHECK-V93A: #define __ARM_ARCH 903
892892
// CHECK-V93A: #define __ARM_ARCH_9_3A__ 1
893893
// CHECK-V93A: #define __ARM_ARCH_PROFILE 'A'
894894

895895
// RUN: %clang -target armv9.4a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V94A %s
896-
// CHECK-V94A: #define __ARM_ARCH 9
896+
// CHECK-V94A: #define __ARM_ARCH 904
897897
// CHECK-V94A: #define __ARM_ARCH_9_4A__ 1
898898
// CHECK-V94A: #define __ARM_ARCH_PROFILE 'A'
899899

900900
// RUN: %clang -target armv9.5a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V95A %s
901-
// CHECK-V95A: #define __ARM_ARCH 9
901+
// CHECK-V95A: #define __ARM_ARCH 905
902902
// CHECK-V95A: #define __ARM_ARCH_9_5A__ 1
903903
// CHECK-V95A: #define __ARM_ARCH_PROFILE 'A'
904904

llvm/include/llvm/TargetParser/ARMTargetParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ uint64_t parseArchExt(StringRef ArchExt);
258258
ArchKind parseCPUArch(StringRef CPU);
259259
ProfileKind parseArchProfile(StringRef Arch);
260260
unsigned parseArchVersion(StringRef Arch);
261+
unsigned parseArchMinorVersion(StringRef Arch);
261262

262263
void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
263264
StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU);

llvm/lib/TargetParser/ARMTargetParser.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,64 @@ unsigned ARM::parseArchVersion(StringRef Arch) {
9494
llvm_unreachable("Unhandled architecture");
9595
}
9696

97+
unsigned ARM::parseArchMinorVersion(StringRef Arch) {
98+
Arch = getCanonicalArchName(Arch);
99+
switch (parseArch(Arch)) {
100+
case ArchKind::ARMV4:
101+
case ArchKind::ARMV4T:
102+
case ArchKind::ARMV5T:
103+
case ArchKind::ARMV5TE:
104+
case ArchKind::IWMMXT:
105+
case ArchKind::IWMMXT2:
106+
case ArchKind::XSCALE:
107+
case ArchKind::ARMV5TEJ:
108+
case ArchKind::ARMV6:
109+
case ArchKind::ARMV6K:
110+
case ArchKind::ARMV6T2:
111+
case ArchKind::ARMV6KZ:
112+
case ArchKind::ARMV6M:
113+
case ArchKind::ARMV7A:
114+
case ArchKind::ARMV7VE:
115+
case ArchKind::ARMV7R:
116+
case ArchKind::ARMV7M:
117+
case ArchKind::ARMV7S:
118+
case ArchKind::ARMV7EM:
119+
case ArchKind::ARMV7K:
120+
case ArchKind::ARMV8A:
121+
case ArchKind::ARMV8R:
122+
case ArchKind::ARMV8MBaseline:
123+
case ArchKind::ARMV8MMainline:
124+
case ArchKind::ARMV9A:
125+
case ArchKind::INVALID:
126+
return 0;
127+
case ArchKind::ARMV8_1A:
128+
case ArchKind::ARMV8_1MMainline:
129+
case ArchKind::ARMV9_1A:
130+
return 1;
131+
case ArchKind::ARMV8_2A:
132+
case ArchKind::ARMV9_2A:
133+
return 2;
134+
case ArchKind::ARMV8_3A:
135+
case ArchKind::ARMV9_3A:
136+
return 3;
137+
case ArchKind::ARMV8_4A:
138+
case ArchKind::ARMV9_4A:
139+
return 4;
140+
case ArchKind::ARMV8_5A:
141+
case ArchKind::ARMV9_5A:
142+
return 5;
143+
case ArchKind::ARMV8_6A:
144+
return 6;
145+
case ArchKind::ARMV8_7A:
146+
return 7;
147+
case ArchKind::ARMV8_8A:
148+
return 8;
149+
case ArchKind::ARMV8_9A:
150+
return 9;
151+
}
152+
llvm_unreachable("Unhandled architecture");
153+
}
154+
97155
static ARM::ProfileKind getProfileKind(ARM::ArchKind AK) {
98156
switch (AK) {
99157
case ARM::ArchKind::ARMV6M:

llvm/unittests/TargetParser/TargetParserTest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,14 @@ TEST(TargetParserTest, ARMparseArchVersion) {
976976
EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i]));
977977
}
978978

979+
TEST(TargetParserTest, ARMparseArchMinorVersion) {
980+
for (unsigned i = 0; i < std::size(ARMArch); i++)
981+
if (((std::string)ARMArch[i]).find(".") == 5)
982+
EXPECT_EQ((ARMArch[i][6] - 48u), ARM::parseArchMinorVersion(ARMArch[i]));
983+
else
984+
EXPECT_EQ(0u, ARM::parseArchMinorVersion(ARMArch[i]));
985+
}
986+
979987
TEST(TargetParserTest, getARMCPUForArch) {
980988
// Platform specific defaults.
981989
{

0 commit comments

Comments
 (0)