r362601 - [ARM] Allow "-march=foo+fp" to vary with foo

Sjoerd Meijer via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 5 06:12:01 PDT 2019


Author: sjoerdmeijer
Date: Wed Jun  5 06:12:01 2019
New Revision: 362601

URL: http://llvm.org/viewvc/llvm-project?rev=362601&view=rev
Log:
[ARM] Allow "-march=foo+fp" to vary with foo

Now, when clang processes an argument of the form "-march=foo+x+y+z",
then instead of calling getArchExtFeature() for each of the extension
names "x", "y", "z" and appending the returned string to its list of
low-level subtarget features, it will call appendArchExtFeatures()
which does the appending itself.

The difference is that appendArchExtFeatures can add _more_ than one
low-level feature name to the output feature list if it has to, and
also, it gets told some information about what base architecture and
CPU the extension is going to go with, which means that "+fp" can now
mean something different for different CPUs. Namely, "+fp" now selects
whatever the _default_ FPU is for the selected CPU and/or
architecture, as defined in the ARM_ARCH or ARM_CPU_NAME macros in
ARMTargetParser.def.

On the clang side, I adjust DecodeARMFeatures to call the new
appendArchExtFeatures function in place of getArchExtFeature. This
means DecodeARMFeatures needs to be passed a CPU name and an ArchKind,
which meant changing its call sites to make those available, and also
sawing getLLVMArchSuffixForARM in half so that you can get an ArchKind
enum value out of it instead of a string.

Also, I add support here for the extension name "+fp.dp", which will
automatically look through the FPU list for something that looks just
like the default FPU except for also supporting double precision.

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

Modified:
    cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp
    cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h
    cfe/trunk/test/Driver/armv8.1m.main.c
    cfe/trunk/test/Driver/armv8.1m.main.s

Modified: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp?rev=362601&r1=362600&r2=362601&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp Wed Jun  5 06:12:01 2019
@@ -72,15 +72,13 @@ static void getARMFPUFeatures(const Driv
 
 // 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) {
   SmallVector<StringRef, 8> Split;
   text.split(Split, StringRef("+"), -1, false);
 
   for (StringRef Feature : Split) {
-    StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
-    if (!FeatureName.empty())
-      Features.push_back(FeatureName);
-    else
+    if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features))
       return false;
   }
   return true;
@@ -100,14 +98,16 @@ static void DecodeARMFeaturesFromCPU(con
 // getARMArch is used here instead of just checking the -march value in order
 // to handle -march=native correctly.
 static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
-                             llvm::StringRef ArchName,
+                             llvm::StringRef ArchName, llvm::StringRef CPUName,
                              std::vector<StringRef> &Features,
                              const llvm::Triple &Triple) {
   std::pair<StringRef, StringRef> Split = ArchName.split("+");
 
   std::string MArch = arm::getARMArch(ArchName, Triple);
-  if (llvm::ARM::parseArch(MArch) == llvm::ARM::ArchKind::INVALID ||
-      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
+  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
+  if (ArchKind == llvm::ARM::ArchKind::INVALID ||
+      (Split.second.size() && !DecodeARMFeatures(
+        D, Split.second, CPUName, ArchKind, Features)))
     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
@@ -119,8 +119,11 @@ static void checkARMCPUName(const Driver
   std::pair<StringRef, StringRef> Split = CPUName.split("+");
 
   std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
-  if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() ||
-      (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
+  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)))
     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
@@ -327,25 +330,12 @@ void arm::getARMTargetFeatures(const Too
   if (ThreadPointer == arm::ReadTPMode::Cp15)
     Features.push_back("+read-tp-hard");
 
-  // Check -march. ClangAs gives preference to -Wa,-march=.
   const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
+  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
   StringRef ArchName;
-  if (WaArch) {
-    if (ArchArg)
-      D.Diag(clang::diag::warn_drv_unused_argument)
-          << ArchArg->getAsString(Args);
-    ArchName = StringRef(WaArch->getValue()).substr(7);
-    checkARMArchName(D, WaArch, Args, ArchName, Features, Triple);
-    // 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, Features, Triple);
-  }
+  StringRef CPUName;
 
   // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
-  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
-  StringRef CPUName;
   if (WaCPU) {
     if (CPUArg)
       D.Diag(clang::diag::warn_drv_unused_argument)
@@ -355,6 +345,20 @@ void arm::getARMTargetFeatures(const Too
   } else if (CPUArg)
     CPUName = CPUArg->getValue();
 
+  // Check -march. ClangAs gives preference to -Wa,-march=.
+  if (WaArch) {
+    if (ArchArg)
+      D.Diag(clang::diag::warn_drv_unused_argument)
+          << ArchArg->getAsString(Args);
+    ArchName = StringRef(WaArch->getValue()).substr(7);
+    checkARMArchName(D, WaArch, Args, ArchName, CPUName, Features, Triple);
+    // 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, Features, Triple);
+  }
+
   // Add CPU features for generic CPUs
   if (CPUName == "native") {
     llvm::StringMap<bool> HostFeatures;
@@ -625,11 +629,12 @@ std::string arm::getARMTargetCPU(StringR
   return getARMCPUForMArch(Arch, Triple);
 }
 
-/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
-/// CPU  (or Arch, if CPU is generic).
-// FIXME: This is redundant with -mcpu, why does LLVM use this.
-StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
-                                       const llvm::Triple &Triple) {
+/// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a
+/// particular CPU (or Arch, if CPU is generic). This is needed to
+/// pass to functions like llvm::ARM::getDefaultFPU which need an
+/// ArchKind as well as a CPU name.
+llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch,
+                                               const llvm::Triple &Triple) {
   llvm::ARM::ArchKind ArchKind;
   if (CPU == "generic") {
     std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
@@ -645,6 +650,15 @@ StringRef arm::getLLVMArchSuffixForARM(S
                           ? llvm::ARM::ArchKind::ARMV7K
                           : llvm::ARM::parseCPUArch(CPU);
   }
+  return ArchKind;
+}
+
+/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
+/// CPU  (or Arch, if CPU is generic).
+// FIXME: This is redundant with -mcpu, why does LLVM use this.
+StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
+                                       const llvm::Triple &Triple) {
+  llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
   if (ArchKind == llvm::ARM::ArchKind::INVALID)
     return "";
   return llvm::ARM::getSubArch(ArchKind);

Modified: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h?rev=362601&r1=362600&r2=362601&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h (original)
+++ cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h Wed Jun  5 06:12:01 2019
@@ -13,6 +13,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/TargetParser.h"
 #include <string>
 #include <vector>
 
@@ -25,6 +26,8 @@ std::string getARMTargetCPU(StringRef CP
                             const llvm::Triple &Triple);
 const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
 StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
+llvm::ARM::ArchKind getLLVMArchKindForARM(StringRef CPU, StringRef Arch,
+                                          const llvm::Triple &Triple);
 StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch,
                                   const llvm::Triple &Triple);
 

Modified: cfe/trunk/test/Driver/armv8.1m.main.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/armv8.1m.main.c?rev=362601&r1=362600&r2=362601&view=diff
==============================================================================
--- cfe/trunk/test/Driver/armv8.1m.main.c (original)
+++ cfe/trunk/test/Driver/armv8.1m.main.c Wed Jun  5 06:12:01 2019
@@ -2,13 +2,48 @@
 // RUN: FileCheck --check-prefix=CHECK-DSP < %t %s
 // CHECK-DSP: "-target-feature" "+dsp"
 
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FP < %t %s
+// CHECK-FP: "-target-feature" "+fp-armv8"
+// CHECK-FP-NOT: "-target-feature" "+fp64"
+// CHECK-FP-NOT: "-target-feature" "+d32"
+// CHECK-FP: "-target-feature" "+fullfp16"
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nofp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NOFP < %t %s
+// CHECK-NOFP: "-target-feature" "-vfp2" "-target-feature" "-vfp3" "-target-feature" "-fp16" "-target-feature" "-vfp4" "-target-feature" "-fp-armv8" "-target-feature" "-fp64" "-target-feature" "-d32" "-target-feature" "-neon" "-target-feature" "-crypto"
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp.dp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FPDP < %t %s
+// CHECK-FPDP: "-target-feature" "+fp-armv8"
+// CHECK-FPDP: "-target-feature" "+fullfp16"
+// CHECK-FPDP: "-target-feature" "+fp64"
+// CHECK-FPDP-NOT: "-target-feature" "+d32"
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nofp.dp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NOFPDP < %t %s
+// CHECK-NOFPDP: "-target-feature" "-fp64"
+
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve  -### %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-MVE < %t %s
 // CHECK-MVE: "-target-feature" "+mve"
 
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nomve  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s
+// CHECK-NOMVE: "-target-feature" "-mve"
+
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp  -### %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-MVEFP < %t %s
 // CHECK-MVEFP: "-target-feature" "+mve.fp"
 // CHECK-MVEFP-NOT: "-target-feature" "+fp64"
 
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+nomve.fp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NOMVEFP < %t %s
+// CHECK-NOMVEFP: "-target-feature" "-mve.fp"
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+fp.dp  -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-MVEFP_DP < %t %s
+// CHECK-MVEFP_DP: "-target-feature" "+mve.fp"
+// CHECK-MVEFP_DP: "-target-feature" "+fp64"
+
 double foo (double a) { return a; }

Modified: cfe/trunk/test/Driver/armv8.1m.main.s
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/armv8.1m.main.s?rev=362601&r1=362600&r2=362601&view=diff
==============================================================================
--- cfe/trunk/test/Driver/armv8.1m.main.s (original)
+++ cfe/trunk/test/Driver/armv8.1m.main.s Wed Jun  5 06:12:01 2019
@@ -5,10 +5,24 @@
 # RUN:      FileCheck --check-prefix=ERROR-V81M < %t %s
 # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+dsp -o /dev/null %s 2>%t
 # RUN:      FileCheck --check-prefix=ERROR-V81M_DSP < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_FP < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_FP < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp.dp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp.dp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s
 # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve -o /dev/null %s 2>%t
 # RUN:      FileCheck --check-prefix=ERROR-V81M_MVE < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_MVE < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve+fp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_MVE_FP < %t %s
 # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve.fp -o /dev/null %s 2>%t
 # RUN:      FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s
+# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve.fp -o /dev/null %s 2>%t
+# RUN:      FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s
 
 .syntax unified
 .thumb
@@ -39,15 +53,21 @@ vcmp.f64 d0,d1
 # ERROR-V8M: :[[@LINE-1]]:1: error
 # ERROR-V81M: :[[@LINE-2]]:1: error
 # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
-# ERROR-V81M_MVE: :[[@LINE-4]]:1: error
-# ERROR-V81M_MVEFP: :[[@LINE-5]]:1: error
+# ERROR-V81M_FP: :[[@LINE-4]]:1: error
+# ERROR-V81M_MVE: :[[@LINE-5]]:1: error
+# ERROR-V81M_MVE_FP: :[[@LINE-6]]:1: error
+# ERROR-V81M_MVEFP: :[[@LINE-7]]:1: error
 
 asrl r0, r1, r2
 # ERROR-V8M: :[[@LINE-1]]:1: error
 # ERROR-V81M: :[[@LINE-2]]:1: error
 # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
+# ERROR-V81M_FP: :[[@LINE-4]]:1: error
+# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error
 
 vcadd.i8 q0, q1, q2, #90
 # ERROR-V8M: :[[@LINE-1]]:1: error
 # ERROR-V81M: :[[@LINE-2]]:1: error
 # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
+# ERROR-V81M_FP: :[[@LINE-4]]:1: error
+# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error




More information about the cfe-commits mailing list