Bug 114955 - marco DATA_ALIGNMENT may conflict with pragma pack
Summary: marco DATA_ALIGNMENT may conflict with pragma pack
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-05-06 03:35 UTC by hanwei (K)
Modified: 2024-05-06 07:26 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-05-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description hanwei (K) 2024-05-06 03:35:36 UTC

    
Comment 1 Andrew Pinski 2024-05-06 03:38:27 UTC
No comment in the bug. Maybe press return too soon.
Comment 2 Andrew Pinski 2024-05-06 03:58:07 UTC
Also DATA_ALIGNMENT (and LOCAL_ALIGNMENT) does not conflict with `pragma pack`.

The documentation says https://gcc.gnu.org/onlinedocs/gcc/Structure-Layout-Pragmas.html :
```
that change the maximum alignment of members of structures (other than zero-width bit-fields), unions, and classes subsequently defined.
```

This does not mean a target is not free to increase the alignment of a global (or local) variable to begin with. It just means the alignment of a struct is that so that pointers of that struct will be with the lower alignment.

Targets/GCC could increase alignment of global and local variables even without worrying about the alignment of the struct.
Comment 3 hanwei (K) 2024-05-06 06:39:50 UTC
Yeap, press return too soon. 

Code like:

#include <stdio.h>

#pragma pack(1)

char a_global[2] = {0,0};
int g_int[3] = {1, 2, 4};
char b_global[2] = {0, 0};

struct A {
    char c;
    long long a;
    int i;
};
#pragma pack()

struct TMP g_struct = {0};
---

We set pragma pack(1) hope the address of variable (also first member of struct) with struct A type align to 1.

https://github.com/gcc-mirror/gcc/blame/ce343444c019f34172320d0873cc993d43750f41/gcc/config/aarch64/aarch64.h#L128

#define AARCH64_EXPAND_ALIGNMENT(COND, EXP, ALIGN)			\
  (((COND) && ((ALIGN) < BITS_PER_WORD)					\
    && (TREE_CODE (EXP) == ARRAY_TYPE					\
	|| TREE_CODE (EXP) == UNION_TYPE				\
	|| TREE_CODE (EXP) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))

force the mininal align of arrays, unions and structures (in aarch64 is 8) even if we set pragma pack for it.

The address of global variable and static variable is implementation-defined, but the data align behavior of GCC seem conflict with pragma pack?
Comment 4 Andrew Pinski 2024-05-06 06:44:37 UTC
>We set pragma pack(1) hope the address of variable (also first member of struct) with struct A type align to 1.

But that is not what #pragma pack is documented doing.

You need to use an explicit align attribute (or _Align or alignas [which is the portable way of doing it for C11 and C++11]).
Comment 5 hanwei (K) 2024-05-06 07:20:33 UTC
You mean the pragma pack just apply to the inner members of struct, not the first member. The align of struct (first member also) is controlled by __attribute__((aligned(...))). Right?
Comment 6 Andrew Pinski 2024-05-06 07:26:59 UTC
It is not about the alignment of the first field but rather the alignment of a struct. BUT variable alignment is controlled separately from struct alignment.

That is the point I am trying to make. If you want a variable to have a smaller alignment than what the target backend wants to give it, then you need to use the aligned attributes.

What pragma pack does is change the alignment of the struct so that if you do:

struct f *t;
....

t->field1 = 10;

It will be an unaligned access there.

But if you have a variable, the alignment will be different and the compiler can increase still to be more efficient.