Skip to content

Commit

Permalink
[clang][Driver][ARM] Favor -mfpu over default CPU features
Browse files Browse the repository at this point in the history
When processing the command line options march, mcpu and mfpu, we store
the implied target features on a vector. The change D62998 introduced a
temporary vector, where the processed features get accumulated. When
calling DecodeARMFeaturesFromCPU, which sets the default features for
the specified CPU, we certainly don't want to override the features
that have been explicitly specified on the command line. Therefore, the
default features should appear first in the final vector. This problem
became evident once I added the missing (unhandled) target features in
ARM::getExtensionFeatures.

Differential Revision: https://reviews.llvm.org/D63936

llvm-svn: 366027
  • Loading branch information
labrinea committed Jul 14, 2019
1 parent aae0cb6 commit 24cacf9
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 33 deletions.
6 changes: 5 additions & 1 deletion clang/lib/Driver/ToolChains/Arch/ARM.cpp
Expand Up @@ -376,7 +376,11 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
Features.push_back(
Args.MakeArgString((F.second ? "+" : "-") + F.first()));
} else if (!CPUName.empty()) {
DecodeARMFeaturesFromCPU(D, CPUName, ExtensionFeatures);
// This sets the default features for the specified CPU. We certainly don't
// want to override the features that have been explicitly specified on the
// command line. Therefore, process them directly instead of appending them
// at the end later.
DecodeARMFeaturesFromCPU(D, CPUName, Features);
}

if (CPUArg)
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/arm-target-features.c
Expand Up @@ -32,7 +32,7 @@

// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
// CHECK-BASIC-V82: "target-features"="+armv8.2-a,+crc,+crypto,+d32,+dotprod,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+neon,+ras,+thumb-mode,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"
// CHECK-BASIC-V82: "target-features"="+armv8.2-a,+crc,+crypto,+d32,+dotprod,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fpregs,+fullfp16,+hwdiv,+hwdiv-arm,+neon,+ras,+thumb-mode,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"

// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM
// CHECK-BASIC-V8-ARM: "target-features"="+armv8-a,+crc,+crypto,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+neon,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode"
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/ARMTargetParser.def
Expand Up @@ -148,6 +148,7 @@ ARM_ARCH_EXT_NAME("aes", ARM::AEK_AES, "+aes", "-aes")
ARM_ARCH_EXT_NAME("dotprod", ARM::AEK_DOTPROD, "+dotprod","-dotprod")
ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp")
ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, nullptr, nullptr)
ARM_ARCH_EXT_NAME("fp.dp", ARM::AEK_FP_DP, nullptr, nullptr)
ARM_ARCH_EXT_NAME("mve", ARM::AEK_SIMD, "+mve", "-mve")
ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_SIMD | ARM::AEK_FP), "+mve.fp", "-mve.fp")
ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), nullptr, nullptr)
Expand Down
30 changes: 6 additions & 24 deletions llvm/lib/Support/ARMTargetParser.cpp
Expand Up @@ -409,30 +409,12 @@ bool ARM::getExtensionFeatures(unsigned Extensions,
if (Extensions == AEK_INVALID)
return false;

if (Extensions & AEK_CRC)
Features.push_back("+crc");
else
Features.push_back("-crc");

if (Extensions & AEK_DSP)
Features.push_back("+dsp");
else
Features.push_back("-dsp");

if (Extensions & AEK_FP16FML)
Features.push_back("+fp16fml");
else
Features.push_back("-fp16fml");

if (Extensions & AEK_RAS)
Features.push_back("+ras");
else
Features.push_back("-ras");

if (Extensions & AEK_DOTPROD)
Features.push_back("+dotprod");
else
Features.push_back("-dotprod");
for (const auto AE : ARCHExtNames) {
if ((Extensions & AE.ID) == AE.ID && AE.Feature)
Features.push_back(AE.Feature);
else if (AE.NegFeature)
Features.push_back(AE.NegFeature);
}

return getHWDivFeatures(Extensions, Features);
}
Expand Down
15 changes: 8 additions & 7 deletions llvm/unittests/Support/TargetParserTest.cpp
Expand Up @@ -571,17 +571,18 @@ TEST(TargetParserTest, ARMFPURestriction) {
TEST(TargetParserTest, ARMExtensionFeatures) {
std::map<unsigned, std::vector<StringRef>> Extensions;

Extensions[ARM::AEK_CRC] = { "+crc", "-crc" };
Extensions[ARM::AEK_DSP] = { "+dsp", "-dsp" };
for (auto &Ext : ARM::ARCHExtNames) {
if (Ext.Feature && Ext.NegFeature)
Extensions[Ext.ID] = { StringRef(Ext.Feature),
StringRef(Ext.NegFeature) };
}

Extensions[ARM::AEK_HWDIVARM] = { "+hwdiv-arm", "-hwdiv-arm" };
Extensions[ARM::AEK_HWDIVTHUMB] = { "+hwdiv", "-hwdiv" };
Extensions[ARM::AEK_RAS] = { "+ras", "-ras" };
Extensions[ARM::AEK_FP16FML] = { "+fp16fml", "-fp16fml" };
Extensions[ARM::AEK_DOTPROD] = { "+dotprod", "-dotprod" };

std::vector<StringRef> Features;

EXPECT_FALSE(AArch64::getExtensionFeatures(ARM::AEK_INVALID, Features));
EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));

for (auto &E : Extensions) {
// test +extension
Expand All @@ -598,7 +599,7 @@ TEST(TargetParserTest, ARMExtensionFeatures) {
Found = std::find(std::begin(Features), std::end(Features), E.second.at(1));
EXPECT_TRUE(Found != std::end(Features));
EXPECT_TRUE(Extensions.size() == Features.size());
}
}
}

TEST(TargetParserTest, ARMFPUFeatures) {
Expand Down

0 comments on commit 24cacf9

Please sign in to comment.