Bug 12105 - Local Variabels on "Out-of-phase" Alignment on x86
Summary: Local Variabels on "Out-of-phase" Alignment on x86
Status: RESOLVED DUPLICATE of bug 10395
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.2.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-08-29 16:06 UTC by Daniel Foesch
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Foesch 2003-08-29 16:06:05 UTC
With the following code:

int main(void)
{
  int a __attribute__((mode(v4sf))) __attribute__((aligned(16)));

  printf("%i %p\n", __alignof__(a), &a);

  return 0;
}

I get the following information.  The address of a is supposed to be 16-byte
alligned (correct), but the actual address ends in a 4 (hex) which is surely not
16-byte aligned.

If I alter the potential position of the address with the following code:

int main(void)
{
  int i;
  int a __attribute__((mode(v4sf))) __attribute__((aligned(16)));

  printf("%i %p\n", __alignof__(i), &i);
  printf("%i %p\n", __alignof__(a), &a);

  return 0;
}

I still get that it is supposed to be 16-byte aligned, and I still get an
address which ends in a 4 (hex), just the next 16-byte alligned segment up.

If I compile the first to assembly, a is then stored in -24(%ebp), and changing
it to -28(%ebp) makes the code then work.

But I need a generic solution/workaround, which will compile without assistance,
that will make this work.
Comment 1 Andrew Pinski 2003-08-29 16:11:21 UTC
This got to be one of the most frequent bugs recently.
This is a dup of bug 10395, the problem is not GCC (except that GCC should be able to work 
around it and does for non-main functions except for pthread call-backs) but really in GLIBC 
problem.

*** This bug has been marked as a duplicate of 10395 ***
Comment 2 Daniel Foesch 2003-08-29 16:33:34 UTC
How is this the same problem?  Their problem is with libpthread generating an
unaligned stack.

In my problem, gcc _DOES_ generate code to align the stack, even wrapping it in
a function like such:

int foo(void)
{
  int a __attribute__((mode(v4sf))) __attribute__((aligned(16)));

  printf("%i %p\n", __alignof__(a), &a);

  return 0;
}

int main(void)
{
  return foo();
}

Produces the same results.

GCC isn't properly aligning the stack at ALL, even though it by all accounts
should be.

This problem is not involved with libpthreads at all either, I'm not using
threads.  It's also not related to glibc.  The only place I use glibc is for the
printf(), which would have no effect on the allignment of the actual value.

My point is, that even internally to the code GCC is producing, it's producing
unaligned addresses, which are even off-phase so you can't just "work around it"
by adding int's to produce the correct alignment.
Comment 3 Daniel Foesch 2003-08-29 16:47:13 UTC
Ok, I've pretty much resolved my issue.

At -O3, it doesn't work, even in a non-main non-thread-callback function.

At -O2, it does.

I guess you could change the description to "allignment doesn't work at -O3"
Comment 4 Andrew Pinski 2003-08-29 16:54:51 UTC
You know why it does not work at -O3 is because GCC is inlining the code for foo into main so it 
still is a dup of the bug I referenced.
Comment 5 steffen@boerm.net 2003-09-10 14:07:48 UTC
Subject:  New: Local Variabels on "Out-of-phase" Alignment on x86


Hi.

I ran into the same problem when trying to use SSE in my programs. I
fixed it by using an inline assembler hack:

  asm("movl %esp,%eax");
  asm("andl $15,%eax");
  asm("subl %esp,%eax");

Putting this fragment at the beginning of main() makes sure that the
stack pointer is correctly aligned for all functions called from main(),
so all local variables are aligned properly and SSE works just fine.

Of course, this is not the optimal way of doing it, just a quick'n'dirty
workaround. Inlining, for example, will break it.
Using "-fomit-frame-pointer" should break it also.
I guess the safest way of using my hack would be to use an extremely
short main() function that calls "fixedmain()" function that does the
real work and is somehow protected against being inlined. As soon as
fixedmain() is reached, all registers have the values they are supposed
to have and inlining should work as usual.

I guess that the best way of fixing this permanently would be to make
sure that the startup code in some crt*.o file corrects the stack
pointer before calling main(). Then all problems should disappear.

Best regards,
Steffen 8-)

Comment 6 Daniel Foesch 2003-09-13 00:13:05 UTC
Subject: Re:  Local Variabels on "Out-of-phase" Alignment on x86

I fixed the problem, with -O3 optimization it was inlining my code.

gcc 3.2.1 by default already does what your assembly hack does.

That, and a shorter version of your assembly hack is:
   andl $-16, %esp

Which is what gcc automatically places in code.

On Wednesday, Sep 10, 2003, at 08:07 America/Denver, steffen at boerm 
dot net wrote:

> PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* 
> gcc-bugs@gcc.gnu.org.
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12105
>
>
>
> ------- Additional Comments From steffen at boerm dot net  2003-09-10 
> 14:07 -------
> Subject:  New: Local Variabels on "Out-of-phase" Alignment on x86
>
>
> Hi.
>
> I ran into the same problem when trying to use SSE in my programs. I
> fixed it by using an inline assembler hack:
>
>   asm("movl %esp,%eax");
>   asm("andl $15,%eax");
>   asm("subl %esp,%eax");
>
> Putting this fragment at the beginning of main() makes sure that the
> stack pointer is correctly aligned for all functions called from 
> main(),
> so all local variables are aligned properly and SSE works just fine.
>
> Of course, this is not the optimal way of doing it, just a 
> quick'n'dirty
> workaround. Inlining, for example, will break it.
> Using "-fomit-frame-pointer" should break it also.
> I guess the safest way of using my hack would be to use an extremely
> short main() function that calls "fixedmain()" function that does the
> real work and is somehow protected against being inlined. As soon as
> fixedmain() is reached, all registers have the values they are supposed
> to have and inlining should work as usual.
>
> I guess that the best way of fixing this permanently would be to make
> sure that the startup code in some crt*.o file corrects the stack
> pointer before calling main(). Then all problems should disappear.
>
> Best regards,
> Steffen 8-)
>
>
>
>
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
>