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'

Reply via email to