Skip to content

Q Extension No Longer Supported in GCC 14 #1586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jordancarlin opened this issue Oct 18, 2024 · 18 comments
Closed

Q Extension No Longer Supported in GCC 14 #1586

jordancarlin opened this issue Oct 18, 2024 · 18 comments

Comments

@jordancarlin
Copy link
Contributor

The update from GCC 13 to GCC 14 seems to have broken the Q extension. Prior to #1531 including q in the march string worked correctly and compiled quad-precision floating-point instructions. Now it fails before it even begins compiling while checking march. If q is left out of the march string it (unsurprisingly) fails on unrecognized instructions when it hits a q instruction in an assembly file. The exact error message is below.

riscv64-unknown-elf-gcc: error: '-march=rv64gqc': extension 'q' is unsupported standard single letter extension
@jordancarlin jordancarlin changed the title Q Extension No Longer Supported Q Extension No Longer Supported in GCC 14 Oct 18, 2024
@TommyMurphyTM1234
Copy link
Collaborator

TommyMurphyTM1234 commented Oct 18, 2024

What does riscv64-unknown-elf-gcc -march=help show?

This is what I get:

/riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (g04696df0963) 14.2.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

/riscv64-unknown-elf-gcc -march=help
All available -march extensions for RISC-V:
        Name                Version
        i                       2.0, 2.1
        e                       2.0
        m                       2.0
        a                       2.0, 2.1
        f                       2.0, 2.2
        d                       2.0, 2.2
        c                       2.0
        v                       1.0
        h                       1.0
        zic64b                  1.0
        zicbom                  1.0
        zicbop                  1.0
        zicboz                  1.0
        ziccamoa                1.0
        ziccif                  1.0
        zicclsm                 1.0
        ziccrse                 1.0
        zicntr                  2.0
        zicond                  1.0
        zicsr                   2.0
        zifencei                2.0
        zihintntl               1.0
        zihintpause             2.0
        zihpm                   2.0
        zmmul                   1.0
        za128rs                 1.0
        za64rs                  1.0
        zawrs                   1.0
        zfa                     1.0
        zfh                     1.0
        zfhmin                  1.0
        zfinx                   1.0
        zdinx                   1.0
        zca                     1.0
        zcb                     1.0
        zcd                     1.0
        zce                     1.0
        zcf                     1.0
        zcmp                    1.0
        zcmt                    1.0
        zba                     1.0
        zbb                     1.0
        zbc                     1.0
        zbkb                    1.0
        zbkc                    1.0
        zbkx                    1.0
        zbs                     1.0
        zk                      1.0
        zkn                     1.0
        zknd                    1.0
        zkne                    1.0
        zknh                    1.0
        zkr                     1.0
        zks                     1.0
        zksed                   1.0
        zksh                    1.0
        zkt                     1.0
        ztso                    1.0
        zvbb                    1.0
        zvbc                    1.0
        zve32f                  1.0
        zve32x                  1.0
        zve64d                  1.0
        zve64f                  1.0
        zve64x                  1.0
        zvfbfmin                1.0
        zvfh                    1.0
        zvfhmin                 1.0
        zvkb                    1.0
        zvkg                    1.0
        zvkn                    1.0
        zvknc                   1.0
        zvkned                  1.0
        zvkng                   1.0
        zvknha                  1.0
        zvknhb                  1.0
        zvks                    1.0
        zvksc                   1.0
        zvksed                  1.0
        zvksg                   1.0
        zvksh                   1.0
        zvkt                    1.0
        zvl1024b                1.0
        zvl128b                 1.0
        zvl16384b               1.0
        zvl2048b                1.0
        zvl256b                 1.0
        zvl32768b               1.0
        zvl32b                  1.0
        zvl4096b                1.0
        zvl512b                 1.0
        zvl64b                  1.0
        zvl65536b               1.0
        zvl8192b                1.0
        zhinx                   1.0
        zhinxmin                1.0
        smaia                   1.0
        smepmp                  1.0
        smstateen               1.0
        ssaia                   1.0
        sscofpmf                1.0
        ssstateen               1.0
        sstc                    1.0
        svinval                 1.0
        svnapot                 1.0
        svpbmt                  1.0
        xcvalu                  1.0
        xcvbi                   1.0
        xcvelw                  1.0
        xcvmac                  1.0
        xcvsimd                 1.0
        xtheadba                1.0
        xtheadbb                1.0
        xtheadbs                1.0
        xtheadcmo               1.0
        xtheadcondmov           1.0
        xtheadfmemidx           1.0
        xtheadfmv               1.0
        xtheadint               1.0
        xtheadmac               1.0
        xtheadmemidx            1.0
        xtheadmempair           1.0
        xtheadsync              1.0
        xtheadvector            1.0
        xventanacondops         1.0

The Q/q extension is not listed there by default so I guess that (since GCC 14?) you may need to explicitly enable such support in the toolchain at configuration and build time?

So far I have been unable to identify a GCC patch on the mailing list that might have caused this change in behaviour between GCC 13 and 14.

@TommyMurphyTM1234
Copy link
Collaborator

@TommyMurphyTM1234
Copy link
Collaborator

@cmuellner or @kito-cheng - would you happen to know what patches/changes caused this situation? And why?
So far my searches of the patches mailing list for possible candidates/suspects have yielded nothing.

@TommyMurphyTM1234
Copy link
Collaborator

FWIW neither is the Q/q extension listed as an option for -march=... in the GCC documentation:

Nor is any Q/q based ABI listed there either.

I wonder if this gives a clue?

Maybe when Q/q was accepted it was just at the front and but nothing useful happened at the back end and consequently support was removed? Perhaps until hardware implementing Q is available and work is done on GCC to properly support it?

@jordancarlin - with GCC 13 did the compiler ever generate any Q/q instructions for you when that extension was included in the architecture specified?

@cmuellner
Copy link
Collaborator

The update from GCC 13 to GCC 14 seems to have broken the Q extension. Prior to #1531 including q in the march string worked correctly and compiled quad-precision floating-point instructions. Now it fails before it even begins compiling while checking march. If q is left out of the march string it (unsurprisingly) fails on unrecognized instructions when it hits a q instruction in an assembly file. The exact error message is below.

Looking into the history of gcc/config/riscv/riscv.cc in GCC, I can't see that there was ever Q support in the GCC's RISC-V backend (e.g. look into the FP moves in riscv_output_move()).

That said, GCC releases before GCC 14 indeed accepted q as part of the march string. This was likely addressed (I would even say fixed) by cleanup in the corresponding parser code (gcc/common/config/riscv/riscv-common.cc) in January 2024. Now only those extensions are accepted, that are indeed supported (i.e., if they are listed in riscv_ext_version_table).

Note, that Binutils has "Q" support (there is an entry for "q" in bfd/elfxx-riscv.c). This explains why it looked like the GNU toolchain had "Q" support.

@jordancarlin
Copy link
Contributor Author

@TommyMurphyTM1234 @cmuellner Thanks for helping look into this. I know that Q was never listed in the march help documentation. When using Q with gcc 13 it was with assembly files, so GCC wasn’t generating any Q instructions from C, but it was able to compile them into an elf file. If this small amount of support was removed since there was no corresponding backend, what is the best path forward for assembly files that contain Q instructions? https://github.com/openhwgroup/cvw implements Q support, so our tool flow for compiling tests breaks with GCC 14 at the moment.

@cmuellner
Copy link
Collaborator

Would it work for you to use the assembler instead of the compiler (e.g. riscv64-unknown-linux-gnu-as -o test.o test.s)?

@jordancarlin
Copy link
Contributor Author

I'm not as familiar with using the assembler directly so will need to look into it and get back to you. Thanks for the idea.

@TommyMurphyTM1234
Copy link
Collaborator

I'm not as familiar with using the assembler directly so will need to look into it and get back to you. Thanks for the idea.

You just invoke the assembler directly, as @cmuellner suggested by calling riscv64-unknown-elf-as directly rather than via the GCC front end riscv64-unknown-elf-gcc. The latter is normally the recommended way but there can be situations (such as this) where you might need to manually invoke specific tools directly.

The documentation for the assembler is here:

(Thanks for the clarifying info @cmuellner! 👍).

@jordancarlin
Copy link
Contributor Author

Yes. Just switching to riscv64-unknown-elf-as instead of riscv64-unknown-elf-gcc seems to have dramatically changed what is being output, so investigating why that is.

@jordancarlin
Copy link
Contributor Author

I suspect it has to do with a file that is #included and the assembler not supporting linking. It looks like I will need to directly call the linker first before using the assembler.

@TommyMurphyTM1234
Copy link
Collaborator

I suspect it has to do with a file that is #included and the assembler not supporting linking. It looks like I will need to directly call the linker first before using the assembler.

That doesn't make sense.
Linking is the last step in compiling a program and comes before compilation and assembling.
Why would you be calling the linker before the assembler and why would that help at all?

@TommyMurphyTM1234
Copy link
Collaborator

Maybe provide a small self-contained test case and people will be able to advise.

@TommyMurphyTM1234
Copy link
Collaborator

Just for completeness on the original issue, this fails:

git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=`pwd`/installed-tools --with-arch=rv64gcq
make 2>&1 | tee build.log

...

cp doc/gcc.1 doc/g++.1
/home/user/issue-1586/build-gcc-newlib-stage1/./gcc/xgcc -B/home/user/issue-1586/build-gcc-newlib-stage1/./gcc/  -xc -nostdinc /dev/null -S -o /dev/null -fself-test=../.././gcc/gcc/testsuite/selftests
xgcc: error: '-march=rv64imafdqc_zicsr_zifencei': extension 'q' is unsupported standard single letter extension
xgcc: error: '-march=rv64imafdqc_zicsr_zifencei': extension 'q' is unsupported standard single letter extension
make[2]: *** [../.././gcc/gcc/c/Make-lang.in:153: s-selftest-c] Error 1
rm gfdl.pod gcc.pod gcov-dump.pod gcov-tool.pod fsf-funding.pod gpl.pod cpp.pod gcov.pod lto-dump.pod
make[2]: Leaving directory '/home/user/issue-1586/build-gcc-newlib-stage1/gcc'
make[1]: *** [Makefile:4689: all-gcc] Error 2
make[1]: Leaving directory '/home/user/issue-1586/build-gcc-newlib-stage1'
make: *** [Makefile:651: stamps/build-gcc-newlib-stage1] Error 2

@jordancarlin
Copy link
Contributor Author

jordancarlin commented Oct 18, 2024

@TommyMurphyTM1234 With GCC 13 we were using the following command in a Makefile to compile tests. I've included one of the simple tests along with the linker script below. The included test doesn't actually have a Q instruction in it because that is a much more complicated test, but should be able to compile with the same options.

%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
	riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 -mcmodel=medany -nostartfiles -Tlink.ld $<

example.zip

I changed the Makefile to use the command below, but get a very different result now. I assume this is because it is not using the linker script. Sorry if that was unclear before.

%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
	riscv64-unknown-elf-as -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 $<

@jordancarlin
Copy link
Contributor Author

I suspect it has to do with a file that is #included and the assembler not supporting linking. It looks like I will need to directly call the linker first before using the assembler.

That doesn't make sense. Linking is the last step in compiling a program and comes before compilation and assembling. Why would you be calling the linker before the assembler and why would that help at all?

Oops. Meant after the assembler

@TommyMurphyTM1234
Copy link
Collaborator

@TommyMurphyTM1234 With GCC 13 we were using the following command in a Makefile to compile tests. I've included one of the simple tests along with the linker script below. The included test doesn't actually have a Q instruction in it because that is a much more complicated test, but should be able to compile with the same options.

%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
	riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 -mcmodel=medany -nostartfiles -Tlink.ld $<

example.zip

I changed the Makefile to use the command below, but get a very different result now. I assume this is because it is not using the linker script. Sorry if that was unclear before.

%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
	riscv64-unknown-elf-as -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom_zbkb_zbkx_zknd_zkne_zknh -mabi=lp64 $<

You should probably try changing it with GCC 13 first to ensure that you get the same results with your original Makefile which just calls gcc and the modified one that calls as and ld separately. Once you have the same results doing that then you know what to do for GCC 14.

Your modified version ONLY seems to call as? You need to manually call as for each assembly language source file that has Q instructions in order to create the corresponding object file. You then need to call ld (or the gcc front end) to link these any any other object files, libraries and startup code etc. into a complete ELF file.

(I'm using as, ld and gcc as shorthands for the RISC-V versions here).

@jordancarlin
Copy link
Contributor Author

Thanks for all the help. Our Q tests are working now. I ended up having to run just the preprocessor of gcc first to handle the #includes, then the assembler for the files that depend on Q, and finally the linker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants