https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117766
--- Comment #14 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- (In reply to Tom Lane from comment #13) > After further experimentation, it seems to me that: > > * There was a behavioral change between gcc 9.3.1 and the later releases I > tested. Specifically, in 9.3.1 a -march switch does not override the > platform-selected default -mfpu, whereas in later releases the default -mfpu > is ignored if there's -march on the command line. I don't know if this was > intentional. I can work with it, but: > The changes were made in gcc-8, it was announced in the release notes. They were necessary because the Arm architecture has evolved in a way that makes the -mfpu option non-viable for some branches of the architecture. In the old system, there was -march (or -mcpu) and -mfpu. The problems with this were that: - Users had to know which FPU model went with which architecture (it was common-place to see combinations like -march=armv8-a -mfpu=neon, with users not realising that this did not enable all the available neon functionality in armv8-a). - It was possible to create Franken architectures that did not exist, such as Armv4 with floating point or armv8-m with neon. This makes testing a bigger problem. - The scheme really does not work for the M-profile MVE extension where this feature extends both the integer, FP and simd instruction sets. To address this, I implemented a new methodology for specifying the architecture and the extensions supported. The scheme uses '+<feature>' on the architecture spec, which can be validated against the supported extensions. For -march extensions are additive (we start with the base architecture, then add features that are needed to create a complete architecture specification); for -mcpu, however, the features are subtractive (we start with the most capable CPU, but then allow users to disable some extensions that they don't want. This is designed to fit the model where most vendors will want to specify a base architecture that they intend their tools to support, but most users will want to specify a specific CPU that they intend to target. To maintain backwards compatibility the new way of specifying SIMD/FPU-related features is disabled unless -mfpu=auto is specified. But... Some options are set to defaults when the compiler is configured by the vendor (or whoever builds the compiler itself). The default behaviour is to pick 'auto' as the FPU, thus enabling the new model, but if --with-fpu=<something> is used, then this disables the auto feature and it falls back to the old way. Users can still manually specify -mfpu=auto to force the new behaviour, or (at present) can use -mfpu= to force the old behaviour. The problem you are running into is, I think, that your compiler is configured for auto FPU and hard-float, but you then you then try to change the architecture without specifying the fp/simd extension you desire. This leads to an impossible architecture because you end up with the hard float ABI, but the compiler has no idea which floating-point instructions (or registers) exist. The final thing that I want to mention is the FP/SIMD options. These extensions build on each other - there's the base FP extension, introduced in Armv5, and then AdvancedSIMD (aka Neon) in Armv7. Neon extends the floating point instruction set and while the v7 Arm ARM theoretically permits Neon without FP, no product ever implemented this. V8 wend in the other direction and made Neon mandatory when floating-point was present. So GCC implements the following extensions for the v7 architecture: +fp - add floating point (as defined by the base architecture) +simd - add floating point and Neon (as defined by the base architecture) However, in Armv8, +fp isn't a permitted implementation, so this isn't available, leaving just +simd, which enables both FP and Neon. For v7 CPUs, the opposite of these exist: +nosimd - removes SIMD instructions (but leaves the floating point). +nofp - removes both SIMD and floating point. For v8 CPUs, because the two are combined, we again end up with just the extreme: +nofp - removes both SIMD and floating point.