diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -285,6 +285,35 @@ (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0); } +static void appendNoFPUnsupportedFeatures(const arm::FloatABI ABI, + const unsigned FPUID, + const StringRef &ArchName, + std::vector &Features) { + auto checkFPDisabledInArchName = [](const StringRef &ArchName) { + SmallVector Split; + ArchName.split(Split, '+', -1, false); + return llvm::any_of( + Split, [](const StringRef &Extension) { return Extension == "nofp"; }); + }; + + 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", "-mve", "-mve.fp", "-fpregs"}); + } else if (FPUID == llvm::ARM::FK_NONE || + checkFPDisabledInArchName(ArchName)) { + // -mfpu=none or -march=armvX+nofp is *very* similar to -mfloat-abi=soft, + // only that it should not disable MVE-I. + Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-mve.fp"}); + if (!hasIntegerMVE(Features)) { + Features.emplace_back("-fpregs"); + } + } +} + void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, std::vector &Features, bool ForAS) { @@ -455,23 +484,10 @@ 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. - 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", "-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"}); - if (!hasIntegerMVE(Features)) - Features.emplace_back("-fpregs"); - } + // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to + // -march 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. + appendNoFPUnsupportedFeatures(ABI, FPUID, ArchName, Features); // En/disable crc code generation. if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {