[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#704111: clang fails to correctly implement hard float ABI during default compiles due to rediculously low default CPU setting.



Package: clang
Version: 1:3.0-6.1
Severity: grave
x-debbugs-cc: debian-arm@lists.debian.org; cfe-dev@cs.uiuc.edu

(note for non-debian people reading this, the version of clang in debian wheezy is a 3.0 based version which already has patches to make it invoke the linker with appropriate arguments. The llvm version also appears to be 3.0 again somewhat patched by debian)

I recently discovered that the version of clang in debian wheezy and raspbian wheezy does not work correctly on either debian armhf or raspbian. It seems the problem is that clang can't work out what CPU type it should be using and defaults to something very low (specifically arm7tdmi). With this CPU selected clang silently fails to properly use the hard float ABI and as such any armhf code it generates is broken and won't call floating point routines correctly. It also causes an assertion failure in the bfd linker (but links successfully with the gold linker). Setting the CPU type to something sensible makes it implement the hard float ABI correctly and also stops the assertion failure in the bfd linker.

I have managed to figure out how to patch clang to change the default CPU for armhf (patch attatched). However i'm not sure what it is best to set it to for debian armhf*. In particular this block of code from just below where my patch is applied seems to map all armv7 variants to a CPU type of "coretex-a8".

return llvm::StringSwitch<const char *>(MArch) .Cases("armv2", "armv2a","arm2") .Case("armv3", "arm6") .Case("armv3m", "arm7m") .Cases("armv4", "armv4t", "arm7tdmi") .Cases("armv5", "armv5t", "arm10tdmi") .Cases("armv5e", "armv5te", "arm1026ejs") .Case("armv5tej", "arm926ej-s") .Cases("armv6", "armv6k", "arm1136jf-s") .Case("armv6j", "arm1136j-s") .Cases("armv6z", "armv6zk", "arm1176jzf-s") .Case("armv6t2", "arm1156t2-s") .Cases("armv7", "armv7a", "armv7-a", "cortex-a8") .Cases("armv7r", "armv7-r", "cortex-r4") .Cases("armv7m", "armv7-m", "cortex-m3") .Case("ep9312", "ep9312") .Case("iwmmxt", "iwmmxt") .Case("xscale", "xscale") .Cases("armv6m", "armv6-m", "cortex-m0") // If all else failed, return the most base CPU LLVM supports.
   .Default("arm7tdmi");

Now it is my understanding that "traditional cortex a8" includes CPU features not required by debian armhf. Specifically neon and the extra vfp registers. The questions I have are

1: What does the "coretex-a8" CPU setting imply for clang/llvm? in particular does it imply neon and the extra vfp registers? 2: If noone can provide an answer to the above question then taking into the account how late we are in the freeze should we play it safe and specify a lower (armv6) CPU version to make sure that neon and the extra vfp registers don't get accidently used. I personally think that the answer is yes but I'm open to arguments.

If I get no response to this within about a weak I intend to attach a nmu diff containing a version of the patch that sets the default set to armv6. Then file a pre-approval request with the release team. Finally if the release team approves and noone objects I intend to upload the NMU.

Description: Fix CPU type default for armhf
  Without this patch clang defaults to a CPU type of "arm7tdmi" which
  does not work correctly with -mfloat-abi=hard leading to broken
  code.
Author: Peter Michael Green <plugwash@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

Index: clang-3.0/tools/clang/lib/Driver/Tools.cpp
===================================================================
--- clang-3.0.orig/tools/clang/lib/Driver/Tools.cpp	2013-03-27 19:50:18.000000000 +0000
+++ clang-3.0/tools/clang/lib/Driver/Tools.cpp	2013-03-27 19:53:28.000000000 +0000
@@ -442,6 +442,9 @@
   if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
     // Otherwise, if we have -march= choose the base CPU for that arch.
     MArch = A->getValue(Args);
+  } else if (Triple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+    // Use armv7-a for armhf
+    MArch = "armv7-a";
   } else {
     // Otherwise, use the Arch from the triple.
     MArch = Triple.getArchName();

Reply to: