[PATCH] D150902: [ARM][Driver] Warn if -mhard-float is incompatible

Michael Platings via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu May 18 12:48:03 PDT 2023


michaelplatings created this revision.
michaelplatings added reviewers: stuij, pratlucas.
Herald added subscribers: dmgreen, kristof.beyls.
Herald added a project: All.
michaelplatings requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

Mixing -mfloat-abi=hard with a CPU that doesn't have floating point
registers is an error in GCC:

  cc1: error: '-mfloat-abi=hard': selected processor lacks an FPU

Since there is code in the wild (including in clang tests) that relies
on Clang's current behaviour, emit a warning instead of an error.

Unlike the GCC error, the new warning refers to floating point
registers instead of an FPU. This is because -mfloat-abi=hard and
-march=armv8.1-m.main+mve+nofp are compatible - in that case floating
point registers are required, but an FPU is not required.

My initial thought was to use the floating point ABI calculated by
arm::getARMFloatABI() but in invalid cases which error for other
reasons the ABI is miscalculated and the warning would cause confusion.
Therefore only warn if the user specifies the float ABI explicitly.

Fixes part of https://github.com/llvm/llvm-project/issues/55755


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150902

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/lib/Driver/ToolChains/Arch/ARM.cpp
  clang/test/Driver/arm-no-float-regs.c


Index: clang/test/Driver/arm-no-float-regs.c
===================================================================
--- /dev/null
+++ clang/test/Driver/arm-no-float-regs.c
@@ -0,0 +1,24 @@
+// REQUIRES: arm-registered-target
+
+// Check that -mfloat-abi=hard gives a warning if FP registers aren't available.
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m0 -mfloat-abi=hard -c %s 2>&1
+
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m0 -mhard-float -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=HARDFLOAT %s
+
+
+// -mfloat-abi=hard and -march=...+nofp are incompatible in this instance:
+// RUN: %clang --target=arm-none-eabi -march=armv8.1-m.main+nofp -mfloat-abi=hard -c %s 2>&1
+// -mfloat-abi=hard and -march=...+nofp are compatible in this instance:
+// RUN: %clang --target=arm-none-eabi -march=armv8.1-m.main+mve+nofp -mfloat-abi=hard -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=NOWARN %s
+
+// Here the float ABI is calculated as "hard" and FP registers are
+// calculated to not be available. Since the float ABI wasn't specified
+// explicitly, the warning should not be emitted.
+// RUN: not %clang -target thumbv5-windows -mcpu=arm10tdmi -c %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck -check-prefix=NOWARN %s
+
+// CHECK: warning: '-mfloat-abi=hard': selected processor lacks floating point registers
+// HARDFLOAT: warning: '-mhard-float': selected processor lacks floating point registers
+// NOWARN-NOT: selected processor lacks floating point registers
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -144,6 +144,22 @@
         << A->getSpelling() << A->getValue();
 }
 
+// If -mfloat-abi=hard or -mhard-float are specified explicitly then check that
+// floating point registers are available on the target CPU.
+static void checkARMFloatABI(const Driver &D, const ArgList &Args,
+                             const std::vector<StringRef> &Features) {
+  if (llvm::find(Features, "-fpregs") == Features.end())
+    return;
+  const Arg *A =
+      Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                      options::OPT_mfloat_abi_EQ);
+  if (A && (A->getOption().matches(options::OPT_mhard_float) ||
+            (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
+             A->getValue() == StringRef("hard"))))
+    D.Diag(clang::diag::warn_drv_no_floating_point_registers)
+        << A->getAsString(Args);
+}
+
 bool arm::useAAPCSForMachO(const llvm::Triple &T) {
   // The backend is hardwired to assume AAPCS for M-class processors, ensure
   // the frontend matches that.
@@ -910,6 +926,8 @@
 
   if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
     Features.push_back("+no-bti-at-return-twice");
+
+  checkARMFloatABI(D, Args, Features);
 }
 
 std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -417,6 +417,8 @@
 def warn_drv_unsupported_float_abi_by_lib : Warning<
   "float ABI '%0' is not supported by current library">,
   InGroup<DiagGroup<"unsupported-abi">>;
+def warn_drv_no_floating_point_registers: Warning<
+  "'%0': selected processor lacks floating point registers">;
 def warn_ignoring_ftabstop_value : Warning<
   "ignoring invalid -ftabstop value '%0', using default value %1">;
 def warn_drv_overriding_flag_option : Warning<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150902.523514.patch
Type: text/x-patch
Size: 3671 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230518/d0ba96c2/attachment-0001.bin>


More information about the cfe-commits mailing list