public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/38001]  New: regression in 4.3: alignment checks wrongly optimized away (runtime failure)
@ 2008-11-03 13:26 thomas dot orgis at awi dot de
  2008-11-03 13:27 ` [Bug c/38001] " thomas dot orgis at awi dot de
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: thomas dot orgis at awi dot de @ 2008-11-03 13:26 UTC (permalink / raw)
  To: gcc-bugs

For mpg123 I use __attribute__((aligned(16))) for variables that are possibly
used by SSE code. Now, I also create a library containing that SSE code, which
can be used from third party applications.
The use case of linking gcc-compiled mpg123 code with another compiler that did
_not_ align the stack at 16 bytes lead to the implementation of a runtime
alignment check in the toplevel API calls of the library.

I stripped this down to the example I am about to attach.
Please note that I observed the issue in my library code first, so it should
not be bound to problems with the stack in main() -- though the example has the
code in main().

Basic code fragment:

        double __attribute__((aligned(16))) altest[1];
        double __attribute__((aligned(16))) altest2[1];
        if((size_t)altest % 16 != 0 || (size_t)altest2 % 16 != 0)
        printf("not aligned with %!\n");

If the stack from the caller is not proper, I expected this check to fire.
Now a specific user who had -mpreferred-stack-boundary=2 in his CFLAGS pointed
me to reinvestigate the matter:

Since that option apparently overrides the __attribute__((aligned(16))) (a bug
or misfeature on its own, IMHO), the user encountered a segfault on using the
misaligned memory in SSE code.
That made me realize that I not just have to check for misaligned stack from
the caller but also for the alignment working at all in one stack frame (hence,
the two variables altest and altest2). Now, I updated the check and noticed
that gcc-4.3.1 -mpreferred-stack-boundary=2 still produced a crashing program
instead of triggering the check at runtime.

I compared with gcc-3.3.6 and gcc-3.4.6; both versions correctly detected the
bad alignment at runtime and stopped in a controlled way. This led to
investigations with the stripped down code.

Results:
1. gcc-4.3.1 optimizes away the altest % 16 or altest & 15 to plain zero, under
the wrong assumption that the alignment to 16 bytes works.
2. consequently, the if(altest % 16 != 0 ...) check is totally optimized away
-- even with -O0!
2. additonally, the & 15 check is miscompiled by gcc-3.4.6: it boils down to
  and $0x1,%eax
instead of
  and $0xf,%eax
...please see the attached files, with disassembly. This is inconsistent,
even...

Actually, I am not sure how many bugs I am raising here. The main point is:
GCC should not omptimize away a computation which has an unknown result at
compile time -- or at least take into account that it actually does so against
it's own actions that render the predicted result invalid (align the stack at a
different boundary).

Footnote: I know that it is a bad idea to have -mpreferred-stack-boundary=2 in
this case, but this shows that the check is miscompiled and that insight also
applies to the correctly compiled library being linked with other code that
aligns stack differently.


-- 
           Summary: regression in 4.3: alignment checks wrongly optimized
                    away (runtime failure)
           Product: gcc
           Version: 4.3.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: thomas dot orgis at awi dot de
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
@ 2008-11-03 13:27 ` thomas dot orgis at awi dot de
  2008-11-03 13:33 ` jakub at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: thomas dot orgis at awi dot de @ 2008-11-03 13:27 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from thomas dot orgis at awi dot de  2008-11-03 13:26 -------
Created an attachment (id=16617)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=16617&action=view)
tar with the test source file, script to test the bug, example disassembly


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
  2008-11-03 13:27 ` [Bug c/38001] " thomas dot orgis at awi dot de
@ 2008-11-03 13:33 ` jakub at gcc dot gnu dot org
  2008-11-03 13:36 ` thomas dot orgis at awi dot de
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu dot org @ 2008-11-03 13:33 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from jakub at gcc dot gnu dot org  2008-11-03 13:31 -------
The check is not miscompiled, gcc assumes __attribute__((aligned (16)))
variables
are 16 bytes aligned and uses this everywhere, including optimizing out
unnecessary check.  This is a user bug, you simply should never call
-mpreferred-stack-boundary=4 routines from -mpreferred-stack-boundary=2
compiled code.  GCC documentation even warns against this.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
  2008-11-03 13:27 ` [Bug c/38001] " thomas dot orgis at awi dot de
  2008-11-03 13:33 ` jakub at gcc dot gnu dot org
@ 2008-11-03 13:36 ` thomas dot orgis at awi dot de
  2008-11-03 15:57 ` tg at mirbsd dot org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: thomas dot orgis at awi dot de @ 2008-11-03 13:36 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from thomas dot orgis at awi dot de  2008-11-03 13:35 -------
Are you saying that there is no way to protect my library from user programs
that have  misaligned stacks?
The whole checking business is in vain, then?

To sad that it working fine with older gccs made be believe that I do something
usefule there in preventing segfaults.

And: In any case, if -mpreferred-stack-boundary obviously contradicts the
aligned attribute, couldn't gcc at least give a compile error on this?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (2 preceding siblings ...)
  2008-11-03 13:36 ` thomas dot orgis at awi dot de
@ 2008-11-03 15:57 ` tg at mirbsd dot org
  2008-11-03 16:09 ` thomas dot orgis at awi dot de
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: tg at mirbsd dot org @ 2008-11-03 15:57 UTC (permalink / raw)
  To: gcc-bugs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 402 bytes --]



------- Comment #4 from tg at mirbsd dot org  2008-11-03 15:55 -------
The aligned attribute is for data, not for the stack.
The gcc texinfo page says that gcc does not re-align
the stack once misaligned (it could do that though,
or you could do that yourself). But optimising away
the checks is something we’re used to from gcc4…


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (3 preceding siblings ...)
  2008-11-03 15:57 ` tg at mirbsd dot org
@ 2008-11-03 16:09 ` thomas dot orgis at awi dot de
  2008-11-03 16:19 ` jakub at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: thomas dot orgis at awi dot de @ 2008-11-03 16:09 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from thomas dot orgis at awi dot de  2008-11-03 16:08 -------
Aren't we talking about data on the stack?

And, actually gcc-4.2 can realign the stack, if you ask it to.
But, well ... in any case it would be very helpful if a programmer had a way to
deal devensively with stack issues for a library that is compiled separately
from programs using it.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (4 preceding siblings ...)
  2008-11-03 16:09 ` thomas dot orgis at awi dot de
@ 2008-11-03 16:19 ` jakub at gcc dot gnu dot org
  2008-11-03 23:39 ` hjl dot tools at gmail dot com
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu dot org @ 2008-11-03 16:19 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from jakub at gcc dot gnu dot org  2008-11-03 16:17 -------
4.2 doesn't realign stack except for main, only gcc 4.4 does and only for
alignments larger than 16 bytes (and only on i386/x86_64).
You can use an optimization barrier to force a check, but I think it is a bad
idea to slow down a library just because users might call it with bad stack
alignment, using -mpreferred-stack-boundary is an ABI switch, people who mix
code with different ABIs get what they deserve.
Say
uintptr_t aladdr = (uintptr_t) altest;
asm ("" : "+r" (aladdr));
if ((aladdr & 15) != 0)
  puts ("stack not properly aligned");


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (5 preceding siblings ...)
  2008-11-03 16:19 ` jakub at gcc dot gnu dot org
@ 2008-11-03 23:39 ` hjl dot tools at gmail dot com
  2008-11-04  8:54 ` thomas dot orgis at awi dot de
  2008-11-04 15:21 ` hjl dot tools at gmail dot com
  8 siblings, 0 replies; 10+ messages in thread
From: hjl dot tools at gmail dot com @ 2008-11-03 23:39 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from hjl dot tools at gmail dot com  2008-11-03 23:38 -------
With gcc 4.4 on Linux/ia32, you can use -mincoming-stack-boundary=2
to compile your library to support library users compiled with
-mpreferred-stack-boundary=2. Compile will align stack properly
and efficiently when needed.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (6 preceding siblings ...)
  2008-11-03 23:39 ` hjl dot tools at gmail dot com
@ 2008-11-04  8:54 ` thomas dot orgis at awi dot de
  2008-11-04 15:21 ` hjl dot tools at gmail dot com
  8 siblings, 0 replies; 10+ messages in thread
From: thomas dot orgis at awi dot de @ 2008-11-04  8:54 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from thomas dot orgis at awi dot de  2008-11-04 08:52 -------
Ok, first, let me apologize for the "& 15 check is miscompiled" statement...
operator precedence got me there.

The feature for stack-realignment I meant is
__attribute__((force_align_arg_pointer))
I use this already for the API entry functions of the library when gcc >= 4.2
is available. It _does_ solve the issue for misaligned stack from the caller,
doesn't it?

So, strictly, current gcc does not need the checks, except for the case where
the user asked for trouble with -mpreferred-stack-boundary (which still should
throw an error: __attribute__((aligned(16))) clearly is in conflict with that).

I still need a way to handle the issue with older gccs, as I provide a source
package and want to avoid bug reports about mysterious segfaults: The SSE stuff
that needs alignment is an internal detail of the library, users should not
need to specifically compile their programs for that detail.

Now, since older gccs don't optimize away the check, it is still of use there.
But I am wondering about the power of __attribute__((aligned(16))); gcc-3.4
seems to be unable to align

double __attribute__((aligned(16))) altest[1];

as opposed to 

double __attribute__((aligned(16))) altest[2];

It sort of makes sense, the data structure should not be smaller than the
alignment... but gcc-4.3 does align that correctly. Is that a bug in the older
gcc or just coincidence?
Well, I think I will go with the simple check with altest[2] for old compilers
that don't know force_align_arg_pointer and luckily don't optimize away the
check at the same time -- without need for the optimization barrier.
Is that a good strategy? I can imagine that gcc folks are not that keen on
caring for old gcc versions, but with mpg123 we want to support any C89
compiler, basically, however old.

As for -mincoming-stack-boundary=2: __attribute__((force_align_arg_pointer))
does solve the problem equivalently, doesn't it?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c/38001] regression in 4.3: alignment checks wrongly optimized away (runtime failure)
  2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
                   ` (7 preceding siblings ...)
  2008-11-04  8:54 ` thomas dot orgis at awi dot de
@ 2008-11-04 15:21 ` hjl dot tools at gmail dot com
  8 siblings, 0 replies; 10+ messages in thread
From: hjl dot tools at gmail dot com @ 2008-11-04 15:21 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from hjl dot tools at gmail dot com  2008-11-04 15:20 -------
(In reply to comment #8)
> As for -mincoming-stack-boundary=2: __attribute__((force_align_arg_pointer))
> does solve the problem equivalently, doesn't it?
> 

They are the same in gcc 4.4.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38001


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-11-04 15:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-03 13:26 [Bug c/38001] New: regression in 4.3: alignment checks wrongly optimized away (runtime failure) thomas dot orgis at awi dot de
2008-11-03 13:27 ` [Bug c/38001] " thomas dot orgis at awi dot de
2008-11-03 13:33 ` jakub at gcc dot gnu dot org
2008-11-03 13:36 ` thomas dot orgis at awi dot de
2008-11-03 15:57 ` tg at mirbsd dot org
2008-11-03 16:09 ` thomas dot orgis at awi dot de
2008-11-03 16:19 ` jakub at gcc dot gnu dot org
2008-11-03 23:39 ` hjl dot tools at gmail dot com
2008-11-04  8:54 ` thomas dot orgis at awi dot de
2008-11-04 15:21 ` hjl dot tools at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).