Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -276,6 +276,12 @@ return ABI; } +static bool hasIntegerMVE(const std::vector &F) { + const auto &mve = llvm::find(F, "+mve"); + const auto &nomve = llvm::find(F, "-mve"); + return mve != F.end() && (nomve == F.end() || std::distance(nomve, mve) > 0); +} + void arm::getARMTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple, const ArgList &Args, @@ -459,18 +465,13 @@ // Disable all features relating to hardware FP, not already disabled by the // above call. - Features.insert(Features.end(), {"-neon", "-crypto", "-dotprod", "-fp16fml", - "-mve", "-mve.fp", "-fpregs"}); + 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(), - {"-neon", "-crypto", "-dotprod", "-fp16fml", "-mve.fp"}); - // Even though we remove MVE-FP, we still need to check if it was originally - // present among the requested extensions, because it implies MVE-I, which - // should not be disabled by -mfpu-none. - if (!llvm::is_contained(Features, "+mve") && - !llvm::is_contained(Features, "+mve.fp")) + Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-mve.fp"}); + if (!hasIntegerMVE(Features)) Features.emplace_back("-fpregs"); } Index: clang/test/Driver/arm-mfpu.c =================================================================== --- clang/test/Driver/arm-mfpu.c +++ clang/test/Driver/arm-mfpu.c @@ -419,6 +419,21 @@ // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-mve.fp" // CHECK-MVEFP-FPUNONE-NOT: "-target-feature" "-fpregs" +// RUN: %clang -target arm-none-none-eabi %s -march=armv8.1-m.main+mve.fp+nomve -mfpu=none -### -c 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MVEFP-NOMVE-FPUNONE %s +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-vfp2sp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-vfp3d16sp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-vfp4d16sp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-fp-armv8d16sp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-fp64" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-d32" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-neon" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-crypto" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "+dsp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-mve" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-mve.fp" +// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-fpregs" + // RUN: %clang -target arm-none-none-eabi %s -march=armv8.1-m.main+mve -mfpu=none -### -c 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-MVEI-FPUNONE %s // CHECK-MVEI-FPUNONE-DAG: "-target-feature" "-mve.fp" Index: clang/test/Preprocessor/arm-target-features.c =================================================================== --- clang/test/Preprocessor/arm-target-features.c +++ clang/test/Preprocessor/arm-target-features.c @@ -761,8 +761,9 @@ // CHECK-V81M-MVEFP: #define __ARM_FEATURE_SIMD32 1 // CHECK-V81M-MVEFP: #define __ARM_FPV5__ 1 -// nofp discards mve.fp, but not mve/dsp -// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+nofp -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M-MVEFP-NOFP %s +// fpu=none/nofp discards mve.fp, but not mve/dsp +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+nofp -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M-MVEFP-NOFP %s +// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp -mfpu=none -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M-MVEFP-NOFP %s // CHECK-V81M-MVEFP-NOFP: #define __ARM_FEATURE_DSP 1 // CHECK-V81M-MVEFP-NOFP: #define __ARM_FEATURE_MVE 1