Bug 70133 - AArch64 -mtune=native generates improperly formatted -march parameters
Summary: AArch64 -mtune=native generates improperly formatted -march parameters
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: 6.0
Assignee: James Greenhalgh
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-08 02:00 UTC by davidwillmore
Modified: 2016-04-15 08:24 UTC (History)
5 users (show)

See Also:
Host: aarch64*-none-linux-gnu
Target: aarch64*-none-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-03-08 00:00:00


Attachments
compiler build info and execution host info (3.40 KB, text/plain)
2016-03-08 02:00 UTC, davidwillmore
Details

Note You need to log in before you can comment on or make changes to this bug.
Description davidwillmore 2016-03-08 02:00:53 UTC
Created attachment 37893 [details]
compiler build info and execution host info

On an ODROID C2 board (Amlogic S905 processor) which has Cortex-A53 cores with the following CPU Features (found in /proc/cpuinfo) "fp asimd crc32", -mtune=native expands to -march=armv8-a+fp+simd+nocrypto+crc+nolse which causes gcc to emit the error:
Assembler messages:
Error: must specify extensions to add before specifying those to remove
Error: unrecognized option -march=armv8-a+fp+simd+nocrypto+crc+nolse

If the same build is attempted with "-mtune=native" replaced by "-march=armv8-a+fp+simd+crc+nocrypto+nolse" the compile succeeds as expected.
Comment 1 ktkachov 2016-03-08 08:32:55 UTC
I'll have a look
Comment 2 ktkachov 2016-03-08 09:56:16 UTC
You're using a Linaro GCC, please report the problem to them.
-mtune=native should not be getting rewritten to an -march option and I don't see that happening with the /proc/cpuinfo contents you provided. I see it rewritten to -mtune=cortex-a53.

The malformed -march option should not be getting passed down to the assembler as of commit r227028 on trunk.

I can't reproduce this with a recent trunk.
Can you please try with a recent clean snapshot from trunk?
Comment 3 Christophe Lyon 2016-03-09 11:46:24 UTC
I do not have access to the hardware you are using, but here is what I observed on an APM board.

I built several flavors of GCC, and compiled your attached testcase, and here are the directives generated in the assembler file:
gcc-trunk: .arch armv8-a+fp+sim
gcc-linaro-5.2-2015.11-2/hello.s: .cpu generic+fp+simd
gcc-linaro-snapshot-5.3-2016.02/hello.s:  .arch armv8-a+fp+simd

All 3 are accepted by the version of gas installed on the machine (2.25/ubuntu)


As Kyrylo suggested, can you try either with gcc-trunk or with a newer version of Linaro GCC?
In particular, we backported the commit he mentions (r227028) after release 2015.11 was made, and it is available in our latest snapshot.
Comment 4 Andrew Roberts 2016-03-17 16:16:25 UTC
I've built latest snapshot on Arch Linux Arm aarch64 Odroid-C2 system and see the same thing:

/usr/local/gcc-6.0.0/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-6.0.0/bin/gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-6.0.0/libexec/gcc/aarch64-unknown-linux-gnu/6
.0.0/lto-wrapper
Target: aarch64-unknown-linux-gnu
Configured with: ../gcc-6.0.0/configure --prefix=/usr/local/gcc-6.0.0 --program-
suffix= --disable-werror --enable-shared --enable-threads=posix --enable-checkin
g=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exception
s --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=g
nu --enable-plugin --enable-initfini-array --enable-gnu-indirect-function --enab
le-lto --with-isl --enable-languages=c,c++,fortran --disable-libgcj --enable-clo
cale=gnu --disable-libstdcxx-pch --enable-install-libiberty --disable-multilib -
-enable-shared --enable-clocale=gnu --with-arch-directory=aarch64 --enable-multi
arch --host=aarch64-unknown-linux-gnu --build=aarch64-unknown-linux-gnu --target
=aarch64-unknown-linux-gnu --with-arch=armv8-a --disable-bootstrap
Thread model: posix
gcc version 6.0.0 20160313 (experimental) (GCC) 

echo "int main(void) { return 0; }" | /usr/local/gcc-6.0.0/bin/gcc -march=native
 -c -x c -
Assembler messages:
Error: must specify extensions to add before specifying those to remove
Error: unrecognized option -march=armv8-a+fp+simd+nocrypto+crc+nolse

Where as:
echo "int main(void) { return 0; }" | /usr/local/gcc-6.0.0/bin/gcc -march=armv8-
a+simd+crc+nolse -c -x c -

works

This is with binutils:
ld -v
GNU ld (GNU Binutils) 2.26.0.20160302

cat /proc/cpuinfo
Processor       : AArch64 Processor rev 4 (aarch64)
processor       : 0
processor       : 1
processor       : 2
processor       : 3
Features        : fp asimd crc32
CPU implementer : 0x41
CPU architecture: AArch64
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 4

Hardware        : ODROID-C2
Revision        : 020b

uname -a
Linux alarm 3.14.29-10-ARCH #1 SMP PREEMPT Wed Mar 16 20:13:56 MDT 2016 aarch64 
GNU/Linux

I also saw the same thing with the Linero compiler on Ubuntu, and Arch Linux's gcc 5.3.0. I did try to build gcc 6 snapshot on Ubuntu to report it but it was too flakey, Arch Works better.
Comment 5 James Greenhalgh 2016-03-17 16:55:38 UTC
The crux of this issue is going to be that your Cortex-A53 has no support for the cryptography extension, but does have support for the CRC extensions.

By inspection of host_detect_local_cpu, I see that we run through all the extensions that we know about, checking to see whether that extension is a substring of the Features we read from /proc/cpuinfo . If it is we add +extension, if not we add +noextension.

So, it seems reasonable to me that if we run this algorithm on a core without crypto, but with CRC, we'll get the string described (-march=armv8-a+fp+simd+nocrypto+crc+nolse) forwarded to the assembler on command line.

And sure enough, the assembler wants to read everything you've got before you start telling it what you've not got.

I see a few issues.

1) There's not really a good reason for an assembler to have this syntax restriction. The code does the right thing whatever order you put your features in.
2) We'll have to support these older assemblers anyway, so at the least we'll have to hold off writing the "+no" extension strings until we're done with the
"+" extension strings.
3) We should think about whether we need to put out these +no extension strings at all. I don't like that for my older systems I'll need to keep updating my binutils to cover any new extension strings (e.g. +nolse) that are added by GCC if I want to use -march=native . We shouldn't force that if we don't have to.

So, Confirmed.
Comment 6 Christophe Lyon 2016-03-18 16:46:15 UTC
> 3) We should think about whether we need to put out these +no extension
> strings at all. I don't like that for my older systems I'll need to keep
> updating my binutils to cover any new extension strings (e.g. +nolse) that
> are added by GCC if I want to use -march=native . We shouldn't force that if
> we don't have to.
> 

Do you know why these +no where introduced in the first place?

Why would there be a difference between "+nolse" and "" for instance?
Comment 7 Andrew Pinski 2016-03-18 16:50:09 UTC
(In reply to Christophe Lyon from comment #6)
> > 3) We should think about whether we need to put out these +no extension
> > strings at all. I don't like that for my older systems I'll need to keep
> > updating my binutils to cover any new extension strings (e.g. +nolse) that
> > are added by GCC if I want to use -march=native . We shouldn't force that if
> > we don't have to.
> > 
> 
> Do you know why these +no where introduced in the first place?
> 
> Why would there be a difference between "+nolse" and "" for instance?

X86, adds the -mno-* option too with respect of -march=native.
Comment 8 James Greenhalgh 2016-03-18 16:56:11 UTC
(In reply to Christophe Lyon from comment #6)
> > 3) We should think about whether we need to put out these +no extension
> > strings at all. I don't like that for my older systems I'll need to keep
> > updating my binutils to cover any new extension strings (e.g. +nolse) that
> > are added by GCC if I want to use -march=native . We shouldn't force that if
> > we don't have to.
> > 
> 
> Do you know why these +no where introduced in the first place?
> 
> Why would there be a difference between "+nolse" and "" for instance?

We don't keep track (in aarch64-driver.c) of which flags are implicitly included (e.g. +fp+simd) and would need an explicit +nofp to disable, and which flags need explicitly enabled (e.g. +crc) and so don't need to be explicitly disabled.

I'm working on a clean-up.
Comment 9 ktkachov 2016-03-18 17:48:31 UTC
Thanks for picking this up.
I agree we should keep track of the extensions implied by the architecture
Comment 10 James Greenhalgh 2016-04-11 10:15:32 UTC
Author: jgreenhalgh
Date: Mon Apr 11 10:14:59 2016
New Revision: 234876

URL: https://gcc.gnu.org/viewcvs?rev=234876&root=gcc&view=rev
Log:
[Patch AArch64 2/3] Rework the code to print extension strings (pr70133)

gcc/

	PR target/70133
	* config/aarch64/aarch64-common.c (aarch64_option_extension): Keep
	track of a canonical flag name.
	(all_extensions): Likewise.
	(arch_to_arch_name): Also track extension flags enabled by the arch.
	(all_architectures): Likewise.
	(aarch64_parse_extension): Move to here.
	(aarch64_get_extension_string_for_isa_flags): Take a new argument,
	rework.
	(aarch64_rewrite_selected_cpu): Update for above change.
	* config/aarch64/aarch64-option-extensions.def: Rework the way flags
	are handled, such that the single explicit value enabled by an
	extension is kept seperate from the implicit values it also enables.
	* config/aarch64/aarch64-protos.h (aarch64_parse_opt_result): Move
	to here.
	(aarch64_parse_extension): New.
	* config/aarch64/aarch64.c (aarch64_parse_opt_result): Move from
	here to config/aarch64/aarch64-protos.h.
	(aarch64_parse_extension): Move from here to
	common/config/aarch64/aarch64-common.c.
	(aarch64_option_print): Update.
	(aarch64_declare_function_name): Likewise.
	(aarch64_start_file): Likewise.
	* config/aarch64/driver-aarch64.c (arch_extension): Keep track of
	the canonical flag for extensions.
	* config.gcc (aarch64*-*-*): Extend regex for capturing extension
	flags.

gcc/testsuite/

	PR target/70133
	* gcc.target/aarch64/mgeneral-regs_4.c: Fix expected output.
	* gcc.target/aarch64/target_attr_15.c: Likewise.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/common/config/aarch64/aarch64-common.c
    trunk/gcc/config.gcc
    trunk/gcc/config/aarch64/aarch64-option-extensions.def
    trunk/gcc/config/aarch64/aarch64-protos.h
    trunk/gcc/config/aarch64/aarch64.c
    trunk/gcc/config/aarch64/driver-aarch64.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_4.c
    trunk/gcc/testsuite/gcc.target/aarch64/target_attr_15.c
Comment 11 James Greenhalgh 2016-04-11 10:16:58 UTC
Author: jgreenhalgh
Date: Mon Apr 11 10:16:26 2016
New Revision: 234877

URL: https://gcc.gnu.org/viewcvs?rev=234877&root=gcc&view=rev
Log:
[Patch AArch64 3/3] Fix up for pr70133

gcc/

	PR target/70133
	* config/aarch64/driver-aarch64.c
	(aarch64_get_extension_string_for_isa_flags): New.
	(arch_extension): Rename to...
	(aarch64_arch_extension): ...This.
	(ext_to_feat_string): Rename to...
	(aarch64_extensions): ...This.
	(aarch64_core_data): Keep track of architecture extension flags.
	(cpu_data): Rename to...
	(aarch64_cpu_data): ...This.
	(aarch64_arch_driver_info): Keep track of architecture extension
	flags.
	(get_arch_name_from_id): Rename to...
	(get_arch_from_id): ...This, change return type.
	(host_detect_local_cpu): Update and reformat for renames, handle
	extensions through common infrastructure.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/aarch64/driver-aarch64.c
Comment 12 James Greenhalgh 2016-04-11 10:21:14 UTC
Fixed on trunk with r234875 r234876 and r234877 . You'll need to contact Linaro through their support/bug channels if you think these fixes should be ported to the Linaro releases.
Comment 13 davidwillmore 2016-04-11 11:49:46 UTC
Thank you very much!
Comment 14 Christophe Lyon 2016-04-15 08:24:20 UTC
We (Linaro) have backported the relevant patches to our 5.x branch, and this fix is available in our 5.3-2016.04 snapshot.