[Bug target/65956] New: [5/6 Regression] Another ARM overaligned arg passing issue
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Apr 30 21:17:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65956
Bug ID: 65956
Summary: [5/6 Regression] Another ARM overaligned arg passing
issue
Product: gcc
Version: 5.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
The following testcase is miscompiled at -O2 on armhfp, starting with r221348,
and in this case r221795 didn't fix it. Just hope it is the same thing that
breaks armhfp profiledbootstrap. The difference on the testcase is just:
mov r0, r5
- ldr r1, [sp, #24]
+ ldr r2, [sp, #24]
bl fn1
which means that we pass the second argument to fn1 in a wrong register,
supposedly because the type is void * aligned to long long alignment.
struct A { char *a; int b; long long c; };
char v[3];
__attribute__((noinline, noclone)) void
fn1 (char *x, char *y)
{
if (x != &v[1] || y != &v[2])
__builtin_abort ();
v[1]++;
}
__attribute__((noinline, noclone)) int
fn2 (char *x)
{
asm volatile ("" : "+g" (x) : : "memory");
return x == &v[0];
}
__attribute__((noinline, noclone)) void
fn3 (const char *x)
{
if (x[0] != 0)
__builtin_abort ();
}
static struct A
foo (const char *x, struct A y, struct A z)
{
struct A r = { 0, 0, 0 };
if (y.b && z.b)
{
if (fn2 (y.a) && fn2 (z.a))
switch (x[0])
{
case '|':
break;
default:
fn3 (x);
}
fn1 (y.a, z.a);
}
return r;
}
__attribute__((noinline, noclone)) int
bar (int x, struct A *y)
{
switch (x)
{
case 219:
foo ("+", y[-2], y[0]);
case 220:
foo ("-", y[-2], y[0]);
}
}
int
main ()
{
struct A a[3] = { { &v[1], 1, 1LL }, { &v[0], 0, 0LL }, { &v[2], 2, 2LL } };
bar (220, a + 2);
if (v[1] != 1)
__builtin_abort ();
return 0;
}
More information about the Gcc-bugs
mailing list