]> granicus.if.org Git - clang/commitdiff
[ARM] Handle conflicts between -mfpu and -mfloat-abi options.
authorAsiri Rathnayake <asiri.rathnayake@arm.com>
Thu, 2 Oct 2014 09:56:07 +0000 (09:56 +0000)
committerAsiri Rathnayake <asiri.rathnayake@arm.com>
Thu, 2 Oct 2014 09:56:07 +0000 (09:56 +0000)
Summary: This patch implements warnings/downgradable errors for
invalid -mfpu, -mfloat-abi option combinations (e.g. -mfpu=none
-mfloat-abi=hard).

Change-Id: I94fa664e1bc0b5855ad835abd7a50a3e0395632d

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218863 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.td
lib/Driver/Tools.cpp
lib/Driver/Tools.h
test/Driver/arm-mfpu.c

index 720254830b4b370100ecc75e4401d0f86d897e5b..54e5162353c971b010ec43662433cb28c3f81037 100644 (file)
@@ -146,6 +146,12 @@ def warn_drv_clang_unsupported : Warning<
   "the clang compiler does not support '%0'">;
 def warn_drv_assuming_mfloat_abi_is : Warning<
   "unknown platform, assuming -mfloat-abi=%0">;
+def warn_drv_implied_soft_float_assumed : Warning<
+  "%0 implies soft-float, ignoring conflicting option '%1'">,
+  InGroup<DiagGroup<"implied-soft-float-assumed">>;
+def warn_drv_implied_soft_float_conflict : Warning<
+  "%0 implies soft-float, which conflicts with option '%1'">,
+  InGroup<DiagGroup<"implied-soft-float-conflict">>, DefaultError;
 def warn_ignoring_ftabstop_value : Warning<
   "ignoring invalid -ftabstop value '%0', using default value %1">;
 def warn_drv_overriding_flag_option : Warning<
index 99e34e4be0cf8e5eb73caba87c5fe14fbe2db1b1..28e92f9beddc5a8ec8092bc9003b0377987c00da 100644 (file)
@@ -581,14 +581,24 @@ static void getARMFPUFeatures(const Driver &D, const Arg *A,
     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
-// Select the float ABI as determined by -msoft-float, -mhard-float, and
-// -mfloat-abi=.
+// Select the float ABI as determined by -msoft-float, -mhard-float,
+// -mfpu=... and -mfloat-abi=...
 StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
-                                     const llvm::Triple &Triple) {
+                                     const llvm::Triple &Triple,
+                                     bool *ExplicitNoFloat) {
+
+  // FIXME: -msoft-float and -mhard-float identify the nature of floating point
+  // ops, whereas -mfloat-abi=... identifies the floating point argument passing
+  // convention. But here we are mushing them together into FloatABI = soft/
+  // softfp/hard, which is a bit confusing. For example, this means -msoft-float
+  // and -mfloat-abi=soft are equivalent options to clang. But when we pass
+  // arguments to the backend (AddARMTargetArgs), these two options take their
+  // original interpretations.
   StringRef FloatABI;
-  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
-                               options::OPT_mhard_float,
-                               options::OPT_mfloat_abi_EQ)) {
+  const Arg *A = Args.getLastArg(options::OPT_msoft_float,
+                                 options::OPT_mhard_float,
+                                 options::OPT_mfloat_abi_EQ);
+  if (A) {
     if (A->getOption().matches(options::OPT_msoft_float))
       FloatABI = "soft";
     else if (A->getOption().matches(options::OPT_mhard_float))
@@ -603,6 +613,31 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
     }
   }
 
+  // Some -mfpu=... options are incompatible with some mfloat-abi=... options
+  if (Arg *B = Args.getLastArg(options::OPT_mfpu_EQ)) {
+    StringRef FPU = B->getValue();
+    if (FPU == "none") {
+      // Signal incompatible -mfloat-abi=... options
+      if (FloatABI == "hard")
+        D.Diag(diag::warn_drv_implied_soft_float_conflict)
+          << B->getAsString(Args) << A->getAsString(Args);
+      else if (FloatABI == "softfp")
+        D.Diag(diag::warn_drv_implied_soft_float_assumed)
+          << B->getAsString(Args) << A->getAsString(Args);
+      // Assume soft-float
+      FloatABI = "soft";
+    } else if (FloatABI.empty() || FloatABI == "soft") {
+      // Need -mhard-float for floating point ops
+      FloatABI = "softfp";
+    } 
+  }
+
+  // This allows us to differentiate between a user specified soft-float and
+  // an inferred soft-float. The latter may be overridden under other conditions
+  // but the former has higher priority.
+  if (FloatABI == "soft" && ExplicitNoFloat)
+    *ExplicitNoFloat = true;
+
   // If unspecified, choose the default based on the platform.
   if (FloatABI.empty()) {
     switch (Triple.getOS()) {
@@ -681,7 +716,8 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
                                  const ArgList &Args,
                                  std::vector<const char *> &Features,
                                  bool ForAS) {
-  StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
+  bool ExplicitNoFloat = false;
+  StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple, &ExplicitNoFloat);
   if (!ForAS) {
     // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
     // yet (it uses the -mfloat-abi and -msoft-float options), and it is
@@ -716,6 +752,14 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
     Features.push_back("-neon");
     // Also need to explicitly disable features which imply NEON.
     Features.push_back("-crypto");
+    // Disable remaining floating-point features if soft-float is explicitly
+    // requested.
+    if (ExplicitNoFloat) {
+      Features.push_back("-vfp2");
+      Features.push_back("-vfp3");
+      Features.push_back("-vfp4");
+      Features.push_back("-fp-armv8");
+    }
   }
 
   // En/disable crc
index 8ab145652bb7993a5fd87c50deed736c260dea00..6b443baed5d5f514ec2e7f22b9c4b14ba0e55b2d 100644 (file)
@@ -614,7 +614,8 @@ namespace visualstudio {
 
 namespace arm {
   StringRef getARMFloatABI(const Driver &D, const llvm::opt::ArgList &Args,
-                         const llvm::Triple &Triple);
+                           const llvm::Triple &Triple,
+                           bool *ExplicitNoFloat = NULL);
 }
 namespace XCore {
   // For XCore, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
index e76247852d2b84a413e17e1e108996eb0ec8d865..aa7c675163333cdfea8b7a5d2f49a5ff34aa6de2 100644 (file)
 
 // RUN: %clang -target armv8-linux-gnueabi -mfpu=none %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
+// CHECK-NO-FP: "-target-feature" "-neon"
+// CHECK-NO-FP: "-target-feature" "-crypto"
 // CHECK-NO-FP: "-target-feature" "-vfp2"
 // CHECK-NO-FP: "-target-feature" "-vfp3"
 // CHECK-NO-FP: "-target-feature" "-vfp4"
 // CHECK-NO-FP: "-target-feature" "-fp-armv8"
-// CHECK-NO-FP: "-target-feature" "-crypto"
-// CHECK-NO-FP: "-target-feature" "-neon"
 
 // RUN: %clang -target arm-linux-gnueabihf %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-HF %s
 // RUN: %clang -target armv7-apple-darwin -x assembler %s -### -c 2>&1 \
 // RUN:   | FileCheck --check-prefix=ASM %s
 // ASM-NOT: -target-feature
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv7-linux-gnueabi -mfpu=none -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv6-linux-gnueabi -mfpu=none -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv5-linux-gnueabi -mfpu=none -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv4-linux-gnueabi -mfpu=none -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv7-linux-gnueabi -mfpu=none -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv6-linux-gnueabi -mfpu=none -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv5-linux-gnueabi -mfpu=none -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv4-linux-gnueabi -mfpu=none -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv8-linux-gnueabi -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv7-linux-gnueabi -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv6-linux-gnueabi -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv5-linux-gnueabi -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv4-linux-gnueabi -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv8-linux-gnueabi -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv7-linux-gnueabi -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv6-linux-gnueabi -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv5-linux-gnueabi -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv4-linux-gnueabi -msoft-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv7-linux-gnueabi -mfpu=none %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv6-linux-gnueabi -mfpu=none %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv5-linux-gnueabi -mfpu=none %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// RUN: %clang -target armv4-linux-gnueabi -mfpu=none %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI-FP %s
+// SOFT-ABI-FP-NOT: error:
+// SOFT-ABI-FP-NOT: warning:
+// SOFT-ABI-FP-NOT: "-target-feature" "+{{[^ ]*fp[^ ]*}}"
+// SOFT-ABI-FP: "-target-feature" "-neon"
+// SOFT-ABI-FP: "-target-feature" "-crypto"
+// SOFT-ABI-FP: "-target-feature" "-vfp2"
+// SOFT-ABI-FP: "-target-feature" "-vfp3"
+// SOFT-ABI-FP: "-target-feature" "-vfp4"
+// SOFT-ABI-FP: "-target-feature" "-fp-armv8"
+// SOFT-ABI-FP-NOT: "-target-feature" "+{{[^ ]*fp[^ ]*}}"
+// SOFT-ABI-FP: "-msoft-float"
+// SOFT-ABI-FP: "-mfloat-abi" "soft"
+// SOFT-ABI-FP-NOT: "-target-feature" "+{{[^ ]*fp[^ ]*}}"
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none -mfloat-abi=softfp %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=ABI-IGNORE %s
+// ABI-IGNORE: warning: -mfpu=none implies soft-float, ignoring conflicting option '-mfloat-abi=softfp'
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none -mfloat-abi=hard %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=ABI-ERROR %s
+// ABI-ERROR: error: -mfpu=none implies soft-float, which conflicts with option '-mfloat-abi=hard'
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=none -mhard-float %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=FP-ERROR %s
+// FP-ERROR: error: -mfpu=none implies soft-float, which conflicts with option '-mhard-float'
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=vfp4 -mfloat-abi=soft %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI %s
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=vfp4 -mfloat-abi=softfp %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI %s
+// RUN: %clang -target armv8-freebsd-gnueabi -mfpu=vfp4 %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=SOFT-ABI %s
+// SOFT-ABI-NOT: error:
+// SOFT-ABI-NOT: warning:
+// SOFT-ABI-NOT: "-msoft-float"
+// SOFT-ABI: "-target-feature" "+vfp4"
+// SOFT-ABI-NOT: "-msoft-float"
+// SOFT-ABI: "-mfloat-abi" "soft"
+// SOFT-ABI-NOT: "-msoft-float"
+
+// Floating point features should be disabled only when explicitly requested,
+// otherwise we must respect target inferred defaults.
+//
+// RUN: %clang -target armv8-freebsd-gnueabi %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=DEFAULT-FP %s
+// DEAFULT-FP-NOT: error:
+// DEFAULT-FP-NOT: warning:
+// DEFAULT-FP-NOT: "-target-feature" "-{{[^ ]*fp[^ ]*}}"
+// DEFAULT-FP: "-msoft-float" "-mfloat-abi" "soft"
+// DEFAULT-FP-NOT: "-target-feature" "-{{[^ ]*fp[^ ]*}}"
+
+// RUN: %clang -target armv8-linux-gnueabi -mfpu=vfp4 -mfloat-abi=hard %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=VFP-ABI %s
+// VFP-ABI-NOT: error:
+// VFP-ABI-NOT: warning:
+// VFP-ABI-NOT: "-msoft-float"
+// VFP-ABI: "-target-feature" "+vfp4"
+// VFP-ABI-NOT: "-msoft-float"
+// VFP-ABI: "-mfloat-abi" "hard"
+// VFP-ABI-NOT: "-msoft-float"