Local variables in specified registers don't work correctly with inline asm operands
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
Version: 4.1.2 - 4.9.3 (4.9-2014-q4-major)
Host: all
register int r0 asm("r0") = 5;
asm volatile("mov %[r0], %[r0]" :: [r0]"r"(r0));
Expected behaviour accotding to the documentation would be that gcc generate:
...
mov r0, r0
...
Instead gcc uses under certain conditions different registers if optimization is turned on.
Related documentation is https:/
"You may not code an explicit reference to this register in the assembler instruction template part of an asm statement and assume it always refers to this variable. However, using the variable as an asm operand guarantees that the specified register is used for the operand."
I attached a testcase for reproducing this bug. There is a little more code included to increase the register pressure.
With 4.9-2014-q4-major toolchain bug has been reproduced with:
arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -O1 -fverbose-asm -S -o testcase-46164.s testcase-46164.c
Expected assembler code would have been:
...
mov r0, r0 @ r0
mov r1, r1 @ r1
mov r2, r2 @ r2
...
Actually generated assembler code:
...
mov r0, r0 @ r0
mov r4, r4 @ r1
mov r2, r2 @ r2
...
This bug was already reported upstream 5 years ago but did not see much attention.
Upstream bug: https:/
Changed in gcc-arm-embedded: | |
status: | New → In Progress |
Changed in gcc-arm-embedded: | |
status: | In Progress → Fix Committed |
Changed in gcc-arm-embedded: | |
status: | Fix Committed → Fix Released |
milestone: | none → 4.9-2015-q2-update |
You are right. This problem is related to the -O1 option. If you use -O0, -O2 or -O3 options, it is OK.
I will follow up with this issue. Thank you.