Skip to content

Commit b4498fa

Browse files
yuyichaostaticfloat
authored andcommitted
Workaround LLVM incorrectly enables NEON on armv7-a by default
Explicitly disable NEON when a generic arch is specified (cherry picked from commit 7737162)
1 parent e284c6d commit b4498fa

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

src/codegen.cpp

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5597,27 +5597,40 @@ static inline std::string getNativeTarget()
55975597
#if defined(_CPU_ARM_) || defined(_CPU_AARCH64_)
55985598
// Check if the cpu name is a ARM/AArch64 arch name and return a
55995599
// string that can be used as LLVM feature name
5600-
static inline std::string checkARMArchFeature(const std::string &cpu)
5600+
static inline void checkARMArchFeature(std::string &cpu,
5601+
StringMap<bool> &HostFeatures)
56015602
{
5602-
const char *prefix = "armv";
5603-
size_t prefix_len = strlen(prefix);
5604-
if (cpu.size() <= prefix_len ||
5605-
memcmp(cpu.data(), prefix, prefix_len) != 0 ||
5606-
cpu[prefix_len] < '1' || cpu[prefix_len] > '9')
5607-
return std::string();
56085603
#if defined(_CPU_ARM_)
5604+
if (cpu == "generic") {
5605+
HostFeatures["neon"] = false;
5606+
return;
5607+
}
5608+
#endif
5609+
StringRef cpu_s = cpu;
5610+
if (!cpu_s.startswith("armv"))
5611+
return;
5612+
// Generic names
5613+
#if defined(_CPU_ARM_)
5614+
if (!cpu_s.startswith("armv8")) {
5615+
// Turn off `neon` for generic archs on ARM
5616+
// since LLVM seems to enable it for all armv7-a processors.
5617+
HostFeatures["neon"] = false;
5618+
}
56095619
// "v7" and "v8" are not available in the form of `armv*`
56105620
// in the feature list
56115621
if (cpu == "armv7") {
5612-
return "v7";
5622+
HostFeatures["v7"] = true;
56135623
}
56145624
else if (cpu == "armv8") {
5615-
return "v8";
5625+
HostFeatures["v8"] = true;
5626+
}
5627+
else {
5628+
HostFeatures[cpu] = true;
56165629
}
5617-
return cpu;
56185630
#else
5619-
return cpu.substr(3);
5631+
HostFeatures[cpu.substr(3)] = true;
56205632
#endif
5633+
cpu = "generic";
56215634
}
56225635
#endif
56235636

@@ -5667,9 +5680,25 @@ static inline SmallVector<std::string,10> getTargetFeatures(std::string &cpu)
56675680

56685681
// Arch version
56695682
#if __ARM_ARCH >= 8
5683+
# if defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'A'
5684+
HostFeatures["armv8-a"] = true;
5685+
# else
56705686
HostFeatures["v8"] = true;
5687+
# endif
56715688
#elif __ARM_ARCH >= 7
5689+
// v7 + aclass emits slightly different code than armv7-a
5690+
// In particular LLVM does not use the armv7-a instruction for barrier
5691+
// with v7 + aclass.
5692+
# if defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'A'
5693+
HostFeatures["armv7-a"] = true;
5694+
# elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'R'
5695+
HostFeatures["armv7-r"] = true;
5696+
# elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
5697+
// Thumb
5698+
HostFeatures["armv7-m"] = true;
5699+
# else
56725700
HostFeatures["v7"] = true;
5701+
# endif
56735702
#else
56745703
// minimum requirement
56755704
HostFeatures["v6"] = true;
@@ -5704,18 +5733,21 @@ static inline SmallVector<std::string,10> getTargetFeatures(std::string &cpu)
57045733
//
57055734
// Supported AArch64 arch names on LLVM 3.8:
57065735
// armv8.1a, armv8.2a
5707-
std::string arm_arch = checkARMArchFeature(cpu);
5708-
if (!arm_arch.empty()) {
5709-
HostFeatures[arm_arch] = true;
5710-
cpu = "generic";
5711-
}
5736+
checkARMArchFeature(cpu, HostFeatures);
57125737
#endif
57135738

57145739
SmallVector<std::string,10> attr;
5715-
for (StringMap<bool>::const_iterator it = HostFeatures.begin(); it != HostFeatures.end(); it++) {
5716-
std::string att = it->getValue() ? it->getKey().str() :
5717-
std::string("-") + it->getKey().str();
5718-
attr.append(1, att);
5740+
for (auto it = HostFeatures.begin(); it != HostFeatures.end(); it++) {
5741+
if (it->getValue()) {
5742+
attr.append(1, it->getKey().str());
5743+
}
5744+
}
5745+
// Explicitly disabled features need to be added at the end so that
5746+
// they are not reenabled by other features that implies them by default.
5747+
for (auto it = HostFeatures.begin(); it != HostFeatures.end(); it++) {
5748+
if (!it->getValue()) {
5749+
attr.append(1, std::string("-") + it->getKey().str());
5750+
}
57195751
}
57205752
return attr;
57215753
}

0 commit comments

Comments
 (0)