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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits