Created attachment 58922 [details] Test code to reproduce the issue. The item's address of the array is not correct if aligned is used on the type of array item. The debug version (without gcc optimization) doesn't have the issue, but if we enable optimization like -O1/O2, all the items of the array are using the same address. Attached file is the test code to reproduce the issue. This issue could be reproduced from gcc 7.1 to latest 14.2. From following asm code we can see that the items of the array are using the same address. C code is - ------------------ u64 * l1; u64 * l2; void align_test(chn_t * p) { l1 = (u64*)(&(p->lock[0])); l2 = (u64*)(&(p->lock[99])); printf("addr is [0]=%llu, [99]=%llu\n", l1, l2); } ------------------ asm code is - ------------------ align_test: sub rsp, 8 mov rsi, rdi mov QWORD PTR l1[rip], rdi mov QWORD PTR l2[rip], rdi mov rdx, rdi mov edi, OFFSET FLAT:.LC0 mov eax, 0 call printf add rsp, 8 ret ------------------ Please download the test code and compile with gcc optimization like -O2 to check the issue. Bug 65204 appears to be the same as this issue, but it's resolved. Thanks!
This was rejected in GCC 5.4-4.7.0 . But produced wrong code at -O1 and above starting in GCC 7.1.0.
The linked PRs kinda of point out this is invalid code and should be rejected ...
Hi Andrew, Do you mean that gcc should give an error like old version? For example, error: alignment of array elements is greater than element size
Hello experts, What do you think about the fact that it only happens when using -O1/2/3? It seems like the other issues linked have nothing to do with that fact.
The optimization issue is because we have an element type that looks like <integer_type 0x7ffff69b27e0 spinlock_t volatile unsigned SI size <integer_cst 0x7ffff6824198 type <integer_type 0x7ffff68220a8 bitsizetype> constant 32> unit-size <integer_cst 0x7ffff68241b0 type <integer_type 0x7ffff6822000 sizetype> constant 4> user align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff69b2738 precision:32 min <integer_cst 0x7ffff68241c8 0> max <integer_cst 0x7ffff6824180 4294967295> pointer_to_this <pointer_type 0x7ffff69dd540>> in particular with TYPE_ALIGN > TYPE_SIZE which is a "cannot happen". Because ARRAY_REF records the element size in units of element alignment this ends up as zero ... In this case value-numbering makes ARRAY_REF OP2 explicit while keeping it implicit ends up being "fine" (fine as in still densely packing spinlock_t and thus giving elements wrong alignment). I wonder whether the bug is that sizeof (spinlock_t) is 4, but of course that might be difficult to change. But I suppose this is also how C works; possibly the C frontend should build a variant type of the element type if over-alignment should be ignored - putting in the over-aligned type most definitely breaks the middle-end with regard to how ARRAY_REF is defined. This is a C frontend issue, it produces wrong GENERIC.
Thank you Richard for your detailed elaboration.