GCC Bugzilla – Bug 33594
[4.0/4.1/4.2 regression] stack arrays not aligned on word boundaries
Last modified: 2007-10-16 20:46:06 UTC
gcc version: 4.2.1 (also occurs with versions as early as 4.0.2)
configured with: ../gcc-4.2.1/configure --enable-languages=c,c++
With gcc 4.x, local variable arrays declared on the stack are no longer aligned at word boundaries. For example:
In gcc 3.x, buf would be aligned on a word boundary. With gcc 4.x, the alignment assigned is that of the underlying type - in this case 1-byte for char array.
The cause of the change in alignment seems to be the following:
- gcc 4.x allocates stack in cfgexpand.c, function expand_one_stack_var()
- this calls get_decl_align_unit(), also in cfgexpand.c
- the alignment is then read using macro DECL_ALIGN, which returns the alignment of the type
- a further revision is made using macro LOCAL_ALIGNMENT
- however, LOCAL_ALIGNMENT is not defined for the sparc architecture (in gcc/config/sparc.h), causing the alignment to remain as default
In contrast, gcc 3.4.6 seems to allocate stack in function.c, assign_stack_local_1(), which does not use the alignment macros
Why this is a problem:
- on the sparc platform, a cast from a stack allocated buffer to a structure pointer fails due to the new alignment. Although such code is inherently non-portable, there is a lot of it out there which used to work with the 3.x family.
- there is also a small performance loss from accessing unaligned structures. This is seen in software that receives data from external sources (a socket for example) into a stack buffer.
- add a LOCAL_ALIGNMENT macro for sparc and align arrays on word-boundaries, as was done before
- bug id 22605 reported against gcc 4.0.1
As you say, you cannot rely on alignment > 1 for an array of char.
- why change the behavior of gcc from 3.x to 4.x?
- is there any harm in adding alignment for arrays? If not, can we make this an enhancement request?
You should able to use the attribute aligned to get what you want.
You're right - I can use aligned, but I will have to search through 100,000+ lines of code to find all the places that character arrays are used and then add the aligned directive. A lot of this code is open-source or vendor-supplied that we build and use. Not a fun task...
Any chance of the enhancement request?
This issue has affected *many* developers on a variety of platforms including ARM and PPC. There is no elegant way to resolve this without searching through every line of code. There is a warning -Wcast-align that helps to find where some of these alignment issues may exist, but there is no nice way to fix them (i.e. the warning will persist even after the variable in question is aligned).
Please consider re-submitting this as an enhancement request.
Based on the feedback below, I'd like to reopen this as an enhancement request. Rationale for requesting this as an enhancment is as follows:
-> restoring gcc 3.x behavior will ease migration to gcc 4.x on alignment enforcing platforms (ARM, SPARC, PPC etc.). Without this, the migration will be painful & slow. I don't think it is in anyone's interest to stay on older releases.
-> comments in sparc.h clearly indicate a desire to align character arrays:
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
I have attached a patch for the SPARC platform below. This was tested on Solaris 10, with gcc 4.1.2 and 4.2.1.
diff -cr gcc-4.2.1/gcc/config/sparc/sparc.h gcc-4.2.1-new/gcc/config/sparc/sparc.h
*** gcc-4.2.1/gcc/config/sparc/sparc.h Tue Oct 3 16:25:00 2006
--- gcc-4.2.1-new/gcc/config/sparc/sparc.h Mon Oct 1 20:05:16 2007
*** 690,695 ****
--- 690,702 ----
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+ /* Make stack local arrays of chars word-aligned for the same reasons. */
+ #define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 1
Taking care of it.
most of the PowerPC don't enforce alignment requirements for integer instructions (except for cache inhibited memory) so please don't use that as an example.
Subject: Bug 33594
Date: Tue Oct 16 20:43:02 2007
New Revision: 129385
* config/sparc/sparc.h (LOCAL_ALIGNMENT): Define.
Will be fixed in the future 4.3.x releases. Thanks for reporting this.