[clang] d1a3396 - [Driver][ARM] Disable unsupported features when nofp arch extension is used
Victor Campos via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 06:19:55 PDT 2020
Author: Victor Campos
Date: 2020-07-29T14:13:22+01:00
New Revision: d1a3396bfbc6fd6df927f2864c18d86e742cabff
URL: https://github.com/llvm/llvm-project/commit/d1a3396bfbc6fd6df927f2864c18d86e742cabff
DIFF: https://github.com/llvm/llvm-project/commit/d1a3396bfbc6fd6df927f2864c18d86e742cabff.diff
LOG: [Driver][ARM] Disable unsupported features when nofp arch extension is used
A list of target features is disabled when there is no hardware
floating-point support. This is the case when one of the following
options is passed to clang:
- -mfloat-abi=soft
- -mfpu=none
This option list is missing, however, the extension "+nofp" that can be
specified in -march flags, such as "-march=armv8-a+nofp".
This patch also disables unsupported target features when nofp is passed
to -march.
Differential Revision: https://reviews.llvm.org/D82948
Added:
clang/test/Driver/arm-nofp-disabled-features.c
Modified:
clang/lib/Driver/ToolChains/Arch/ARM.cpp
clang/test/CodeGen/arm-bf16-softfloat.c
llvm/include/llvm/Support/ARMTargetParser.h
llvm/lib/Support/ARMTargetParser.cpp
llvm/unittests/Support/TargetParserTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index afe896b4a65b..d74d5db0c083 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -73,14 +73,15 @@ static unsigned getARMFPUFeatures(const Driver &D, const Arg *A,
}
// Decode ARM features from string like +[no]featureA+[no]featureB+...
-static bool DecodeARMFeatures(const Driver &D, StringRef text,
- StringRef CPU, llvm::ARM::ArchKind ArchKind,
- std::vector<StringRef> &Features) {
+static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU,
+ llvm::ARM::ArchKind ArchKind,
+ std::vector<StringRef> &Features,
+ unsigned &ArgFPUID) {
SmallVector<StringRef, 8> Split;
text.split(Split, StringRef("+"), -1, false);
for (StringRef Feature : Split) {
- if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features))
+ if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUID))
return false;
}
return true;
@@ -102,14 +103,14 @@ static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
llvm::StringRef ArchName, llvm::StringRef CPUName,
std::vector<StringRef> &Features,
- const llvm::Triple &Triple) {
+ const llvm::Triple &Triple, unsigned &ArgFPUID) {
std::pair<StringRef, StringRef> Split = ArchName.split("+");
std::string MArch = arm::getARMArch(ArchName, Triple);
llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
if (ArchKind == llvm::ARM::ArchKind::INVALID ||
- (Split.second.size() && !DecodeARMFeatures(
- D, Split.second, CPUName, ArchKind, Features)))
+ (Split.second.size() && !DecodeARMFeatures(D, Split.second, CPUName,
+ ArchKind, Features, ArgFPUID)))
D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
@@ -117,15 +118,15 @@ static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
llvm::StringRef CPUName, llvm::StringRef ArchName,
std::vector<StringRef> &Features,
- const llvm::Triple &Triple) {
+ const llvm::Triple &Triple, unsigned &ArgFPUID) {
std::pair<StringRef, StringRef> Split = CPUName.split("+");
std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
llvm::ARM::ArchKind ArchKind =
arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
if (ArchKind == llvm::ARM::ArchKind::INVALID ||
- (Split.second.size() && !DecodeARMFeatures(
- D, Split.second, CPU, ArchKind, Features)))
+ (Split.second.size() &&
+ !DecodeARMFeatures(D, Split.second, CPU, ArchKind, Features, ArgFPUID)))
D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
@@ -347,6 +348,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
StringRef ArchName;
StringRef CPUName;
+ unsigned ArchArgFPUID = llvm::ARM::FK_INVALID;
+ unsigned CPUArgFPUID = llvm::ARM::FK_INVALID;
// Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
if (WaCPU) {
@@ -364,14 +367,14 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
D.Diag(clang::diag::warn_drv_unused_argument)
<< ArchArg->getAsString(Args);
ArchName = StringRef(WaArch->getValue()).substr(7);
- checkARMArchName(D, WaArch, Args, ArchName, CPUName,
- ExtensionFeatures, Triple);
+ checkARMArchName(D, WaArch, Args, ArchName, CPUName, ExtensionFeatures,
+ Triple, ArchArgFPUID);
// FIXME: Set Arch.
D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
} else if (ArchArg) {
ArchName = ArchArg->getValue();
- checkARMArchName(D, ArchArg, Args, ArchName, CPUName,
- ExtensionFeatures, Triple);
+ checkARMArchName(D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures,
+ Triple, ArchArgFPUID);
}
// Add CPU features for generic CPUs
@@ -390,8 +393,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
}
if (CPUArg)
- checkARMCPUName(D, CPUArg, Args, CPUName, ArchName,
- ExtensionFeatures, Triple);
+ checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures,
+ Triple, CPUArgFPUID);
// Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
unsigned FPUID = llvm::ARM::FK_INVALID;
const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
@@ -455,20 +458,26 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("+fullfp16");
}
- // Setting -msoft-float/-mfloat-abi=soft effectively disables the FPU (GCC
- // ignores the -mfpu options in this case).
- // Note that the ABI can also be set implicitly by the target selected.
+ // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to
+ // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in
+ // this case). Note that the ABI can also be set implicitly by the target
+ // selected.
if (ABI == arm::FloatABI::Soft) {
llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
// Disable all features relating to hardware FP, not already disabled by the
// above call.
+ Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-bf16", "-mve",
+ "-mve.fp", "-fpregs"});
+ } else if (FPUID == llvm::ARM::FK_NONE ||
+ ArchArgFPUID == llvm::ARM::FK_NONE ||
+ CPUArgFPUID == llvm::ARM::FK_NONE) {
+ // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to
+ // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the
+ // FPU, but not the FPU registers, thus MVE-I, which depends only on the
+ // latter, is still supported.
Features.insert(Features.end(),
- {"-dotprod", "-fp16fml", "-mve", "-mve.fp", "-fpregs"});
- } else if (FPUID == llvm::ARM::FK_NONE) {
- // -mfpu=none is *very* similar to -mfloat-abi=soft, only that it should not
- // disable MVE-I.
- Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-mve.fp"});
+ {"-dotprod", "-fp16fml", "-bf16", "-mve.fp"});
if (!hasIntegerMVE(Features))
Features.emplace_back("-fpregs");
}
diff --git a/clang/test/CodeGen/arm-bf16-softfloat.c b/clang/test/CodeGen/arm-bf16-softfloat.c
index 5ea7319ec50b..3ff4f465223c 100644
--- a/clang/test/CodeGen/arm-bf16-softfloat.c
+++ b/clang/test/CodeGen/arm-bf16-softfloat.c
@@ -1,4 +1,9 @@
-// RUN: not %clang -o %t.out -target arm-arm-eabi -march=armv8-a+bf16 -mfloat-abi=soft -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target arm-arm-none-eabi -march=armv8-a+bf16 -mfloat-abi=soft -c %s -o %t 2>&1 | FileCheck %s
+// RUN: not %clang -target arm-arm-none-eabi -march=armv8-a+bf16 -mfpu=none -c %s -o %t 2>&1 | FileCheck %s
+// RUN: not %clang -target arm-arm-none-eabi -march=armv8-a+bf16+nofp -c %s -o %t 2>&1 | FileCheck %s
+// RUN: not %clang -target arm-arm-none-eabi -march=armv8-a+bf16+fp+nofp -c %s -o %t 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+bf16+fp -c %s -o %t
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+bf16+nofp+fp -c %s -o %t
// CHECK: error: __bf16 is not supported on this target
extern __bf16 var;
diff --git a/clang/test/Driver/arm-nofp-disabled-features.c b/clang/test/Driver/arm-nofp-disabled-features.c
new file mode 100644
index 000000000000..432e4a98cffc
--- /dev/null
+++ b/clang/test/Driver/arm-nofp-disabled-features.c
@@ -0,0 +1,18 @@
+// RUN: %clang -target arm-arm-none-eabi -mfloat-abi=soft %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MFLOAT-ABI-SOFT
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-dotprod"
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-fp16fml"
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-bf16"
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-mve"
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-mve.fp"
+// CHECK-MFLOAT-ABI-SOFT: "-target-feature" "-fpregs"
+
+// RUN: %clang -target arm-arm-none-eabi -mfpu=none %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+nofp %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a35+nofp %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+nofp+nomve %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NOMVE
+// RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a35+nofp+nomve %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-NOMVE
+// CHECK: "-target-feature" "-dotprod"
+// CHECK: "-target-feature" "-fp16fml"
+// CHECK: "-target-feature" "-bf16"
+// CHECK: "-target-feature" "-mve.fp"
+// CHECK-NOMVE: "-target-feature" "-fpregs"
diff --git a/llvm/include/llvm/Support/ARMTargetParser.h b/llvm/include/llvm/Support/ARMTargetParser.h
index 4e76b3c4b83e..7dd2abd29212 100644
--- a/llvm/include/llvm/Support/ARMTargetParser.h
+++ b/llvm/include/llvm/Support/ARMTargetParser.h
@@ -250,7 +250,8 @@ StringRef getSubArch(ArchKind AK);
StringRef getArchExtName(uint64_t ArchExtKind);
StringRef getArchExtFeature(StringRef ArchExt);
bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
- std::vector<StringRef> &Features);
+ std::vector<StringRef> &Features,
+ unsigned &ArgFPUKind);
StringRef getHWDivName(uint64_t HWDivKind);
// Information by Name
diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp
index 56a91f7dc787..751f84475f42 100644
--- a/llvm/lib/Support/ARMTargetParser.cpp
+++ b/llvm/lib/Support/ARMTargetParser.cpp
@@ -490,9 +490,10 @@ static unsigned findDoublePrecisionFPU(unsigned InputFPUKind) {
return ARM::FK_INVALID;
}
-bool ARM::appendArchExtFeatures(
- StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
- std::vector<StringRef> &Features) {
+bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
+ StringRef ArchExt,
+ std::vector<StringRef> &Features,
+ unsigned &ArgFPUID) {
size_t StartingNumFeatures = Features.size();
const bool Negated = stripNegationPrefix(ArchExt);
@@ -527,6 +528,7 @@ bool ARM::appendArchExtFeatures(
} else {
FPUKind = getDefaultFPU(CPU, AK);
}
+ ArgFPUID = FPUKind;
return ARM::getFPUFeatures(FPUKind, Features);
}
return StartingNumFeatures != Features.size();
diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp
index 0127cb6ae009..9f923e1358dd 100644
--- a/llvm/unittests/Support/TargetParserTest.cpp
+++ b/llvm/unittests/Support/TargetParserTest.cpp
@@ -668,9 +668,10 @@ static bool
testArchExtDependency(const char *ArchExt,
const std::initializer_list<const char *> &Expected) {
std::vector<StringRef> Features;
+ unsigned FPUID;
if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt,
- Features))
+ Features, FPUID))
return false;
return llvm::all_of(Expected, [&](StringRef Ext) {
More information about the cfe-commits
mailing list