Function:
float y;
float foo(float x)
{
y = x * x + x;
asm volatile (vmov.i8 q0, #0 ::: q0);
asm volatile (vmov.i8 q1, #0 ::: q1);
asm volatile (vmov.i8 q2, #0 ::: q2);
asm volatile (vmov.i8 q3, #0 ::: q3);
asm volatile (vmov.i8 q4, #0 ::: q4);
asm volatile (vmov.i8 q5, #0 ::: q5);
asm volatile (vmov.i8 q6, #0 ::: q6);
asm volatile (vmov.i8 q7, #0 ::: q7);
return y;
}
being compiled with -O -Wall -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp
always returns 0.
The cause of incorrect behaviour is that in function foo y is allocated on s15
which is not considered clobbered by asm volatile (vmov.i8 q3, #0 :::
q3);. Mentioning in clobber lists s1 s2 and s3 alongside q0, s5 s6 and s7
alongside q1 and so on solves the problem: clobbered register got spilled.
Omitting any of them makes GCC allocate y on this register and do not spill it.
I also noticed that only d8, d10, d12 and d14 got saved at the beginning of the
function though all d8-d15 should be saved. This was mentioned in bug #42321
comment #1 also.
I tried this example on 4.4.3 and today's trunk.
--
Summary: Overwriting neon quad register does not clobber all
included single registers
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: batuzovk at ispras dot ru
GCC target triplet: arm-unknown-linux-gnueabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43440