https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99342
Bug ID: 99342
Summary: Clobbered register used for input operand (aarch64)
Product: gcc
Version: 10.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: inline-asm
Assignee: unassigned at gcc dot gnu.org
Reporter: stewart.hildebrand at dornerworks dot com
Target Milestone: ---
In this snippet (adapted from OSv unikernel's arch/aarch64/arch-switch.hh), x0,
x1, and x2 are in the clobber list, yet, under certain conditions the compiler
uses one of these clobbered registers for an input operand.
asm volatile("\n"
"str x29, %0 \n"
"mov x2, sp \n"
"adr x1, 1f \n" /* address of label */
"stp x2, x1, %1 \n"
"ldp x29, x0, %2 \n"
"ldp x2, x1, %3 \n"
"mov sp, x2 \n"
"blr x1 \n"
"1: \n" /* label */
:
: "Q"(s_current->_state.fp), "Ump"(s_current->_state.sp),
"Ump"(this->_state.fp), "Ump"(this->_state.sp)
: // Registers we use here
"x0", "x1", "x2",
// Callee-saved registers (general purpose)
"x19", "x20", "x21", "x22", "x23", "x24",
"x25", "x26", "x27", "x28",
// Callee-saved registers (SIMD/FPU)
"d8", "d9", "d10", "d11", "d12", "d13",
"d14", "d15",
// Memory access
"memory");
In the assembly code emitted, lines 184 and 188 use x1 as the input operand:
174: f900009d str x29, [x4]
178: 910003e2 mov x2, sp
17c: 100000c1 adr x1, 194
<_ZN5sched3cpu25reschedule_from_interruptENSt6chrono8durationIlSt5ratioILl1ELl1000000000EEEE+0x104>
180: a9028462 stp x2, x1, [x3, #40]
184: a941803d ldp x29, x0, [x1, #24]
188: a9428422 ldp x2, x1, [x1, #40]
18c: 9100005f mov sp, x2
190: d63f0020 blr x1
The conditions under which this happens seem to include the following:
* Optimization -O2
* The function containing the inline asm gets inlined
* The function that calls the inlined function has some other code in it
As I understand it, the compiler should not have chosen a register that is
listed in the clobber list:
"When the compiler selects which registers to use to represent input and
output operands, it does not use any of the clobbered registers. As a result,
clobbered registers are available for any use in the assembler code."
(https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers)
This test case compiled correctly in g++ 9.2. We observed the bug in g++ 10.2.
We were able to reproduce this bug with the cross g++ 10.2.1 packaged with
Fedora x86_64, the native g++ 10.2.0 packaged with Ubuntu 20.10 aarch64, and
the ARM-packaged cross g++ 10.2.1 (10.2-2020.11) from
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads.
I attached the .ii file as described in the bug reporting instructions. Here is
the command line used to create the .ii file:
$ aarch64-none-linux-gnu-g++ -v -save-temps -std=gnu++11 -g -Wall -Wextra
-Werror -O2 -isystem
/home/stew/osv/build/downloaded_packages/aarch64/boost/upstream/boost_1_72_0 -c
-o sched.o sched.cc
There were no warnings/errors. Please let me know if you need any more info.
This bug was discovered by OSv developer Waldek Kozaczuk.
I verified that I can reproduce the buggy output with this command:
$ aarch64-none-linux-gnu-g++ -v -std=gnu++11 -g -Wall -Wextra -Werror -O2 -c -o
sched.o sched.ii
Using built-in specs.
COLLECT_GCC=aarch64-none-linux-gnu-g++
Target: aarch64-none-linux-gnu
Configured with:
/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/src/gcc/configure
--target=aarch64-none-linux-gnu --prefix=
--with-sysroot=/aarch64-none-linux-gnu/libc
--with-build-sysroot=/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc
--with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function
--enable-shared --disable-libssp --disable-libmudflap --enable-checking=release
--enable-languages=c,c++,fortran
--with-gmp=/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/build-aarch64-none-linux-gnu/host-tools
--with-mpfr=/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/build-aarch64-none-linux-gnu/host-tools
--with-mpc=/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/build-aarch64-none-linux-gnu/host-tools
--with-isl=/tmp/dgboter/bbs/build04--cen7x86_64/buildbot/cen7x86_64--aarch64-none-linux-gnu/build/build-aarch64-none-linux-gnu/host-tools
--enable-fix-cortex-a53-843419 --with-pkgversion='GNU Toolchain for the
A-profile Architecture 10.2-2020.11 (arm-10.16)'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.1 20201103 (GNU Toolchain for the A-profile Architecture
10.2-2020.11 (arm-10.16))
COLLECT_GCC_OPTIONS='-v' '-std=gnu++11' '-g' '-Wall' '-Wextra' '-Werror' '-O2'
'-c' '-o' 'sched.o' '-shared-libgcc' '-mlittle-endian' '-mabi=lp64'
/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../libexec/gcc/aarch64-none-linux-gnu/10.2.1/cc1plus
-fpreprocessed sched.ii -quiet -dumpbase sched.ii -mlittle-endian -mabi=lp64
-auxbase-strip sched.o -g -O2 -Wall -Wextra -Werror -std=gnu++11 -version -o
/tmp/ccgmoSYV.s
GNU C++11 (GNU Toolchain for the A-profile Architecture 10.2-2020.11
(arm-10.16)) version 10.2.1 20201103 (aarch64-none-linux-gnu)
compiled by GNU C version 4.8.5 20150623 (Red Hat 4.8.5-39), GMP
version 4.3.2, MPFR version 3.1.6, MPC version 1.0.3, isl version
isl-0.15-1-g835ea3a-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++11 (GNU Toolchain for the A-profile Architecture 10.2-2020.11
(arm-10.16)) version 10.2.1 20201103 (aarch64-none-linux-gnu)
compiled by GNU C version 4.8.5 20150623 (Red Hat 4.8.5-39), GMP
version 4.3.2, MPFR version 3.1.6, MPC version 1.0.3, isl version
isl-0.15-1-g835ea3a-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 936eda7bb9362af3c69a17a4200d3282
COLLECT_GCC_OPTIONS='-v' '-std=gnu++11' '-g' '-Wall' '-Wextra' '-Werror' '-O2'
'-c' '-o' 'sched.o' '-shared-libgcc' '-mlittle-endian' '-mabi=lp64'
/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/../../../../aarch64-none-linux-gnu/bin/as
-v -EL -mabi=lp64 -o sched.o /tmp/ccgmoSYV.s
GNU assembler version 2.35.1 (aarch64-none-linux-gnu) using BFD version (GNU
Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16))
2.35.1.20201028
COMPILER_PATH=/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../libexec/gcc/aarch64-none-linux-gnu/10.2.1/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../libexec/gcc/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/../../../../aarch64-none-linux-gnu/bin/
LIBRARY_PATH=/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/../../../../aarch64-none-linux-gnu/lib/../lib64/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../aarch64-none-linux-gnu/libc/lib/../lib64/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../aarch64-none-linux-gnu/libc/usr/lib/../lib64/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/../../../../aarch64-none-linux-gnu/lib/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../aarch64-none-linux-gnu/libc/lib/:/home/stew/dev-env-vetting/compiler-bug-test-case/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../aarch64-none-linux-gnu/libc/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-std=gnu++11' '-g' '-Wall' '-Wextra' '-Werror' '-O2'
'-c' '-o' 'sched.o' '-shared-libgcc' '-mlittle-endian' '-mabi=lp64'